diff --git a/Documentation/devicetree/bindings/arm/msm/clock-cpu-8996.txt b/Documentation/devicetree/bindings/arm/msm/clock-cpu-8996.txt index f3c6cc747710d732e7463a65fd0ec36b01850692..bb74c167a3242843346ed3303ed6d76f35e9ccce 100644 --- a/Documentation/devicetree/bindings/arm/msm/clock-cpu-8996.txt +++ b/Documentation/devicetree/bindings/arm/msm/clock-cpu-8996.txt @@ -8,6 +8,7 @@ PLL FMAXes etc. Required properties: - compatible: Must be either "qcom,cpu-clock-8996" or "qcom,cpu-clock-8996-v3" or "qcom,cpu-clock-8996-pro" + or "qcom,cpu-clock-8996-auto" - reg: Pairs of physical base addresses and region sizes of memory mapped registers. - reg-names: Names of the bases for the above registers. Expected @@ -39,6 +40,11 @@ Required properties: clock for the CBF. - cbf-dev: The CBF cache device to which the OPP table for the CBF clock domain will be added. + +Optional properties: +- qcom,pwrcl-early-boot-freq: Power cluster early boot up frequency in HZ. +- qcom,perfcl-early-boot-freq: Perf cluster early boot up frequency in HZ. + Example: clock_cpu: qcom,cpu-clock-8996@ { compatible = "qcom,cpu-clock-8996"; diff --git a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt index a6537ebd2512cb743f1f4bc11fdb452256c4b2e5..7d5e8a1c910a2f9a90b35c10a9a22e70aa1cf469 100644 --- a/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt +++ b/Documentation/devicetree/bindings/arm/msm/mdm-modem.txt @@ -6,8 +6,8 @@ to be reset. Required Properties: - compatible: The bus devices need to be compatible with - "qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom, ext-mdm9x45", - "qcom,ext-mdm9x55". + "qcom,mdm2-modem", "qcom,ext-mdm9x25", "qcom,ext-mdm9x35", "qcom,ext-mdm9x45", + "qcom,ext-mdm9x55", "qcom,ext-apq8096". Required named gpio properties: - qcom,mdm2ap-errfatal-gpio: gpio for the external modem to indicate to the apps processor @@ -110,6 +110,10 @@ Optional driver parameters: on behalf of the subsystem driver. - qcom,mdm-link-info: a string indicating additional info about the physical link. For example: "devID_domain.bus.slot" in case of PCIe. +- qcom,mdm-auto-boot: Boolean. To indicate this instance of esoc boots independently. +- qcom,mdm-statusline-not-a-powersource: Boolean. If set, status line to esoc device is not a + power source. +- qcom,mdm-userspace-handle-shutdown: Boolean. If set, userspace handles shutdown requests. Example: mdm0: qcom,mdm0 { diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 5647b22eede00f1a6488a96ee2b5e0fe384d10e9..d442cf02a816fcaf2360b579aa09ab101365df0d 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -186,6 +186,7 @@ compatible = "qcom,apq8094-fluid" compatible = "qcom,apq8094-liquid" compatible = "qcom,apq8094-mtp" compatible = "qcom,apq8094-dragonboard" +compatible = "qcom,apq8096-adp" compatible = "qcom,apq8096-cdp" compatible = "qcom,apq8096-mtp" compatible = "qcom,apq8096-dragonboard" @@ -280,6 +281,7 @@ compatible = "qcom,sdm660-rumi" compatible = "qcom,sdm660-cdp" compatible = "qcom,sdm660-mtp" compatible = "qcom,sdm660-qrd" +compatible = "qcom,sda660-qrd" compatible = "qcom,sda658-mtp" compatible = "qcom,sda658-cdp" compatible = "qcom,sda660-mtp" @@ -290,6 +292,7 @@ compatible = "qcom,sdm630-cdp" compatible = "qcom,sda630-mtp" compatible = "qcom,sda630-cdp" compatible = "qcom,sdm630-qrd" +compatible = "qcom,sda630-qrd" compatible = "qcom,msm8952-rumi" compatible = "qcom,msm8952-sim" compatible = "qcom,msm8952-qrd" diff --git a/Documentation/devicetree/bindings/cache/msm_cache_erp64.txt b/Documentation/devicetree/bindings/cache/msm_cache_erp64.txt new file mode 100644 index 0000000000000000000000000000000000000000..5dfb6d60529ddaa0b9699ba671fbe6c9d88d5d08 --- /dev/null +++ b/Documentation/devicetree/bindings/cache/msm_cache_erp64.txt @@ -0,0 +1,26 @@ +* MSM 64bit L0, L1, L2 and L3 cache error reporting driver + +Required properties: +- compatible: Should be "qcom,kryo_cache_erp64" +- reg: I/O address L3 hardware block. +- interrupts: Should contain the L0/L1, L2 and L3 cache error interrupt number. +- interrupt-names: Should contain the interrupt names "l1_irq", "l2_irq_info_0", + "l2_irq_info_1", "l2_irq_err_0", "l2_irq_err_1", "l3_irq". + +Example: + qcom,cache_erp64@6500000 { + compatible = "qcom,kryo_cache_erp64"; + reg = <0x6500000 0x4000>; + /* + * PPI 0 for L0/L1 + * SPI 1 for Cluster 1 L2 Info + * SPI 9 for Cluster 2 L2 Info + * SPI 2 for Cluster 1 L2 Error + * SPI 10 for Cluster 2 L2 Error + * SPI 17 for L3 error + */ + interrupts = <1 0 0>, <0 1 0>, <0 9 0>, <0 2 0>, <0 10 0>, + <0 17 0>; + interrupt-names = "l1_irq", "l2_irq_info_0", "l2_irq_info_1", + "l2_irq_err_0", "l2_irq_err_1", "l3_irq"; + }; diff --git a/Documentation/devicetree/bindings/cache/msm_m4m_erp.txt b/Documentation/devicetree/bindings/cache/msm_m4m_erp.txt new file mode 100644 index 0000000000000000000000000000000000000000..5526f118852802cb3a22af757def7eb1933bcf3c --- /dev/null +++ b/Documentation/devicetree/bindings/cache/msm_m4m_erp.txt @@ -0,0 +1,15 @@ +* MSM M4M error reporting driver + +Required properties: +- compatible: Should be "qcom,m4m_erp". +- reg: I/O address M4M hardware block. +- interrupts: Should contain the M4M error interrupt number. +- interrupt-names: Should contain the interrupt names "m4m_irq". + +Example: + qcom,m4m_erp64@9A40000 { + compatible = "qcom,m4m_erp"; + reg = <0x9A40000 0x40000>; + interrupts = <0 22 0>; + interrupt-names = "m4m_irq"; + }; diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 8a47b77abfca677e234fdd618ee029935e0861dc..e8c74a6e738baac1ef1175664283bc5ee95f1233 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -18,6 +18,7 @@ Required properties: "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock "allwinner,sun4i-a10-axi-clk" - for the AXI clock "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 + "allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates "allwinner,sun4i-a10-ahb-clk" - for the AHB clock "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13 @@ -43,6 +44,7 @@ Required properties: "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 + "allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3 "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 diff --git a/Documentation/devicetree/bindings/fb/mdss-dp.txt b/Documentation/devicetree/bindings/fb/mdss-dp.txt index aa227c2628da04dbcb8746a68f10dc7a8c344ae2..707e6edb26eaa9e4466232d74e231dc56905de03 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dp.txt @@ -27,7 +27,46 @@ Required properties - qcom,aux-en-gpio: Specifies the aux-channel enable gpio. - qcom,aux-sel-gpio: Specifies the aux-channel select gpio. - qcom,usbplug-cc-gpio: Specifies the usbplug orientation gpio. -- qcom,aux-cfg-settings: An array that specifies the DP AUX configuration settings. +- qcom,aux-cfg0-settings: Specifies the DP AUX configuration 0 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg1-settings: Specifies the DP AUX configuration 1 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg2-settings: Specifies the DP AUX configuration 2 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg3-settings: Specifies the DP AUX configuration 3 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg4-settings: Specifies the DP AUX configuration 4 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg5-settings: Specifies the DP AUX configuration 5 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg6-settings: Specifies the DP AUX configuration 6 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg7-settings: Specifies the DP AUX configuration 7 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg8-settings: Specifies the DP AUX configuration 8 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. +- qcom,aux-cfg9-settings: Specifies the DP AUX configuration 9 settings. The first + entry in this array corresponds to the register offset + within DP AUX, while the remaining entries indicate the + programmable values. Optional properties: - qcom,-supply-entries: A node that lists the elements of the supply used by the @@ -87,7 +126,16 @@ Example: "core_aux_clk", "core_cfg_ahb_clk", "ctrl_link_clk", "ctrl_link_iface_clk", "ctrl_crypto_clk", "ctrl_pixel_clk"; - qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03]; + qcom,aux-cfg0-settings = [1c 00]; + qcom,aux-cfg1-settings = [20 13 23 1d]; + qcom,aux-cfg2-settings = [24 00]; + qcom,aux-cfg3-settings = [28 00]; + qcom,aux-cfg4-settings = [2c 0a]; + qcom,aux-cfg5-settings = [30 26]; + qcom,aux-cfg6-settings = [34 0a]; + qcom,aux-cfg7-settings = [38 03]; + qcom,aux-cfg8-settings = [3c bb]; + qcom,aux-cfg9-settings = [40 03]; qcom,logical2physical-lane-map = [02 03 01 00]; qcom,phy-register-offset = <0x4>; qcom,max-pclk-frequency-khz = <593470>; diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index 90ccfa7c62e20d7e2ecd7ebf7933d4ed81109ab1..1f8458cd06596c6edce3cd134b1a7a951ec93776 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -563,6 +563,7 @@ Optional properites: to a non-DSI interface. - qcom,bridge-name: A string to indicate the name of the bridge chip connected to DSI. qcom,bridge-name is required if qcom,dba-panel is defined for the panel. +- qcom,hdmi-mode: Indicates where current panel is HDMI mode, otherwise, it will be DVI mode. - qcom,adjust-timer-wakeup-ms: An integer value to indicate the timer delay(in ms) to accommodate s/w delay while configuring the event timer wakeup logic. @@ -581,6 +582,15 @@ Additional properties added to the second level nodes that represent timings pro commands. "dsi_lp_mode" = DSI low power mode (default) "dsi_hs_mode" = DSI high speed mode +- qcom,sublinks-count: An integer value indicates the number of sublinks in the panel. + Default value is 1. This property is used only if qcom,split-link-enabled + is defined. +- qcom,lanes-per-sublink: An integer value indicates the number of data lanes per sublink in the panel. + Default value is 1. This property is used only if qcom,split-link-enabled + is defined. +- qcom,split-link-enabled: A boolean value to enable/disable the split link feature. If qcom,sublinks-count + or qcom,lanes-per-sublink are not defined, default values are used. + Note, if a given optional qcom,* binding is not present, then the driver will configure the default values specified. @@ -808,6 +818,10 @@ Example: qcom,mdss-dsc-version = <0x11>; qcom,mdss-dsc-scr-version = <0x1>; + qcom,split-link-enabled; + qcom,sublinks-count = <2>; + qcom,lanes-per-sublink = <2>; + dsi_sim_vid_config0: config0 { qcom,lm-split = <360 360>; qcom,mdss-dsc-encoders = <2>; diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt index 6c20d22f98b42ebcdd1ad164a899075714774297..0d55389f3790bcd6525bf1f6a131ccfb4fff22df 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt @@ -50,6 +50,8 @@ Optional properties: -- qcom,supply-post-on-sleep: time to sleep (ms) after turning on -- qcom,supply-pre-off-sleep: time to sleep (ms) before turning off -- qcom,supply-post-off-sleep: time to sleep (ms) after turning off + -- qcom,supply-lp-mode-disable-allowed: supply can be turned off in + low power state. - pll-src-config Specified the source PLL for the DSI link clocks: "PLL0" - Clocks sourced out of DSI PLL0 diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt index a596aa1c595d058ae4b62c6bca53217c71e289d3..c2550e6fe26c1a932a08050b6e4e35a7c752e623 100644 --- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt +++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt @@ -82,6 +82,8 @@ Optional properties: - qcom,shutdown-poweroff-type Same description as qcom,warm-reset-poweroff- type but this applies for the system shutdown case. +- qcom,kpdpwr-sw-debounce Boolean property to enable the debounce logic + on the KPDPWR_N rising edge. All the below properties are in the sub-node section (properties of the child diff --git a/Documentation/devicetree/bindings/net/neutrino_avb.txt b/Documentation/devicetree/bindings/net/neutrino_avb.txt new file mode 100644 index 0000000000000000000000000000000000000000..46c6a5208eba0df2be9baa79226c310f022982a4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/neutrino_avb.txt @@ -0,0 +1,28 @@ +* Neutrino Ethernet * +This driver implements Ethernet driver for Neutrino ethernet controller +Required properties: + - compatible: Should be "qcom,ntn_avb" + - ntn-rst-gpio: Neutrino reset GPIO + - vdd-ntn-hsic-supply: neutrino HSIC power supply + - vdd-ntn-pci-supply: PCIe core power supply + - vdd-ntn-io-supply: Neutrino IO power supply + - vdd-ntn-phy-supply: Ethernet Phy power supply + - vdd-ntn-core-supply: Neutrino core power supply + - pinctrl-names: should contain GPIO details + - pinctrl-0: Neutrino reset GPIO [this is from MSM] + - ntn-rst-delay-msec: dealy (msec) required after PCIe reset for stabilization + - ntn-rc-num: PCIe root complex number on which Neutrino is connected +Example: + qcom,ntn_avb { + compatible = "qcom,ntn_avb"; + ntn-rst-gpio = <&pm8994_gpios 13 0>; + vdd-ntn-hsic-supply = <&pm8994_l25>; + vdd-ntn-pci-supply = <&pm8994_s4>; + vdd-ntn-io-supply = <&pm8994_s4>; + vdd-ntn-phy-supply = <&pm8994_l9>; + vdd-ntn-core-supply = <&pm8994_l19>; + pinctrl-names = "default"; + pinctrl-0 = <&ntn_default>; + qcom,ntn-rst-delay-msec = <100>; + qcom,ntn-rc-num = <1>; + }; diff --git a/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt b/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt index d7edafc9a46bbc482a38c5a1d42a42fc05b1123d..4a69e03951b7219fe6ed76518bece118ee84ef35 100644 --- a/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt +++ b/Documentation/devicetree/bindings/pil/subsys-pil-tz.txt @@ -67,6 +67,7 @@ Optional properties: - qcom,complete-ramdump: Boolean. If set, complete ramdump i.e. region between start address of first segment to end address of last segment will be collected without leaving any hole in between. +- qcom,ignore-ssr-failure: Boolean. If set, SSR failures are not considered fatal. Example: qcom,venus@fdce0000 { diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt index 5a2c3ecd3d1e38f125ad1a4ae87ef5fdcd410978..b41219d51973a0eb68711d53268418db99389f79 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt @@ -169,6 +169,24 @@ Charger specific properties: Definition: Boolean flag which when present enables intput suspend for debug battery. +- qcom,min-freq-khz + Usage: optional + Value type: + Definition: Specifies the minimum charger buck/boost switching frequency + in KHz. It overrides the min frequency defined for the charger. + +- qcom,max-freq-khz + Usage: optional + Value type: + Definition: Specifies the maximum charger buck/boost switching frequency in + KHz. It overrides the max frequency defined for the charger. + +- qcom,otg-deglitch-time-ms + Usage: optional + Value type: + Definition: Specifies the deglitch interval for OTG detection. + If the value is not present, 50 msec is used as default. + ============================================= Second Level Nodes - SMB2 Charger Peripherals ============================================= diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt index 5529e30811fb783361007c896120a74feb5f6cc3..92ef23c3a2905a95cf11ca32ebe93e5133222e0d 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt @@ -22,8 +22,7 @@ Charger specific properties: Definition: String which indicates the charging mode. Can be one of the following: Standalone/Parallel Master - "qcom,smb138x-charger" - smb138x Parallel Slave - "qcom,smb138x-parallel-slave" - smb1355 Parallel Slave - "qcom,smb1355-parallel-slave", + Parallel Slave - "qcom,smb138x-parallel-slave" - qcom,pmic-revid Usage: required @@ -36,8 +35,7 @@ Charger specific properties: Usage: optional Value type: Definition: Specifies parallel charging mode. If not specified, MID-MID - option is selected by default. Note that smb1355 can only - run in MID-MID configuration. + option is selected by default. - qcom,suspend-input Usage: optional @@ -127,7 +125,7 @@ Example ======= smb138x_charger: qcom,smb138x-charger { - compatible = "qcom,smb138x-charger"; + compatible = "qcom,qpnp-smb138x-charger"; #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt b/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt new file mode 100644 index 0000000000000000000000000000000000000000..7d492f5d7e256ccb40938c6b4796b8735f2eb50b --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt @@ -0,0 +1,72 @@ +ON Semiconductor NCP6335d regulator + +NCP6335d is able to deliver up to 5.0 A, with programmable output voltage from +0.6 V to 1.87 V in 10mV steps, with synchronous rectification and automatic PWM/ +PFM transitions, enable pins and power good/fail signaling. + +The NCP6335d interface is via I2C bus. + +Required Properties: +- compatible: Must be "onnn,ncp6335d-regulator". +- reg: The device 8-bit I2C address. +- regulator-min-microvolt: Minimum voltage in microvolts supported by this + regulator. +- regulator-max-microvolt: Maximum voltage in microvolts supported by this + regulator. +- onnn,min-setpoint: Minimum setpoint voltage in microvolts supported + by this regulator. +- onnn,step-size: The step size of the regulator, in uV. +- onnn,min-slew-ns: Minimum time in ns needed to change voltage by + one step size. This value corresponds to DVS + mode bit of 00b in command register. +- onnn,max-slew-ns: Maximum time in ns needed to change voltage by + one step size. This value corresponds to DVS + mode bit of 11b in command register. +- onnn,vsel: Working vsel register. Supported value are 0 + or 1. +- onnn,slew-ns: Time in ns needed to change voltage by one step + size. Supported value are 333, 666, 1333, 2666. + +Optional Properties: +- onnn,discharge-enable: Present: discharge enabled. + Not Present: discharge disabled. +- onnn,restore-reg: Present: Restore vsel register from backup register. + Not Present: No restore. +- onnn,vsel-gpio: Present: GPIO connects to the VSEL pin and set the + VSEL pin according to device tree flag. + Not Present: No GPIO is connected to vsel pin. +- pinctrl-names: The state name of the VSEL pin configuration. + Only support: "default" +- pinctrl-0: The phandles of the pin configuration node in + pinctrl for VSEL pin. + For details of pinctrl properties, please refer to: + "Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt" +- onnn,sleep-enable: Present: Forced in sleep mode when EN and VSEL + pins are low. + Not Present: Low quiescent current mode when EN and VSEL + pins are low. +- onnn,mode: A string which specifies the initial mode to use for the regulator. + Supported values are "pwm" and "auto". PWM mode is more + robust, but draws more current than auto mode. If this propery + is not specified, then the regulator will be in the hardware default mode. + +Example: + i2c_0 { + ncp6335d-regulator@1c { + compatible = "onnn,ncp6335d-regulator"; + reg = <0x1c>; + onnn,vsel = <0>; + onnn,slew-rate-ns = <2666>; + onnn,discharge-enable; + onnn,step-size = <10000>; + onnn,min-slew-ns = <333>; + onnn,max-slew-ns = <2666>; + pintrl-names = "default"; + pinctrl-0 = <&ext_buck_vsel_default>; + + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1350000>; + onnn,min-setpoint = <600000>; + onnn,vsel-gpio = <&msmgpio 2 1>; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt index c9cfc889fababafc3ceaa70fef6b6dedda52e4d3..0d53b9fa4378897e562f0d23732f5b6e82bc9c04 100644 --- a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt @@ -151,6 +151,10 @@ LAB subnode optional properties: any value in the allowed limit. - qcom,notify-lab-vreg-ok-sts: A boolean property which upon set will poll and notify the lab_vreg_ok status. +- qcom,qpnp-lab-sc-wait-time-ms: This property is used to specify the time + (in ms) to poll for the short circuit + detection. If not specified the default time + is 5 sec. Following properties are available only for PM660A: diff --git a/Documentation/devicetree/bindings/regulator/qpnp-oledb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-oledb-regulator.txt index 38f599ba5321f2acc757417a5931975ce8e6d56c..55fde0d4feb6321295314745e07b3316af5c9f60 100644 --- a/Documentation/devicetree/bindings/regulator/qpnp-oledb-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qpnp-oledb-regulator.txt @@ -14,6 +14,11 @@ Required Node Structure Value type: Definition: should be "qcom,qpnp-oledb-regulator". +- qcom,pmic-revid + Usage: required + Value type: + Definition: Used to identify the PMIC subtype. + - reg Usage: required Value type: @@ -57,13 +62,6 @@ Required Node Structure rail. This property is applicable only if qcom,ext-pin-ctl property is specified and it is specific to PM660A. -- qcom,force-pd-control - Usage: optional - Value type: - Definition: Used to enable the pull down control forcibly via SPMI by - disabling the pull down configuration done by hardware - automatically through SWIRE pulses. - - qcom,pbs-client Usage: optional Value type: @@ -224,6 +222,7 @@ pm660a_oledb: qpnp-oledb@e000 { compatible = "qcom,qpnp-oledb-regulator"; #address-cells = <1>; #size-cells = <1>; + qcom,pmic-revid = <&pm660l_revid>; reg = <0xe000 0x100>; label = "oledb"; diff --git a/Documentation/devicetree/bindings/soc/qcom/qpnp-haptic.txt b/Documentation/devicetree/bindings/soc/qcom/qpnp-haptic.txt index 33764982425797ffefa9a0683564812810183fe4..aa3363b52a03a9443c93bacd3e38a663ddbfb056 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qpnp-haptic.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qpnp-haptic.txt @@ -76,6 +76,10 @@ Optional properties when qcom,actuator-type is "lra" at End of Pattern - qcom,lra-res-cal-period : Auto resonance calibration period. The values range from 4 to 32(default) +- qcom,lra-auto-mode : If this property is specified, haptics mode for LRA + actuators will be automatically configured along with + other required settings runtime based on the duration + of the pattern. - qcom,perform-lra-auto-resonance-search : boolean, define this property if: a) the underlying PMI chip does not have a register in the MISC block to read the error percentage in RC clock diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index acf12239c813a38f7d4eda4cfcfc456f8fe4a887..dec5442b33d61fe44525087065b3f2efa0529d5d 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -1245,12 +1245,9 @@ Required properties: When clock rate is set to zero, then external clock is assumed. - [Second Level Nodes] - -Required properties: - - - compatible : "qcom,msm-dai-q6-tdm" - - qcom,msm-dai-q6-mi2s-dev-id: TDM port ID. + - qcom,msm-cpudai-tdm-clk-internal: Clock Source. + 0 - EBIT clock from clk tree + 1 - IBIT clock from clk tree - qcom,msm-cpudai-tdm-sync-mode: Synchronization setting. 0 - Short sync bit mode @@ -1275,6 +1272,13 @@ Required properties: 1 - 1 bit clock cycle 2 - 2 bit clock cycle + [Second Level Nodes] + +Required properties: + + - compatible : "qcom,msm-dai-q6-tdm" + - qcom,msm-dai-q6-mi2s-dev-id: TDM port ID. + - qcom,msm-cpudai-tdm-data-align: Indicate how data is packed within the slot. For example, 32 slot width in case of sample bit width is 24. @@ -1309,17 +1313,18 @@ Example: qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36912>; qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <0>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&quat_tdm_active &quat_tdm_dout_active>; pinctrl-1 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; - qcom,msm-cpudai-tdm-sync-mode = <0>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; qcom,msm-cpudai-tdm-header-start-offset = <0>; qcom,msm-cpudai-tdm-header-width = <2>; diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt index bef9193345746a046c70d85b9559272290f23be9..633abd2b8d087472392bbd4517f3d70258c48d2e 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.txt @@ -42,6 +42,9 @@ Required properties: cell 4: interrupt flags indicating level-sense information, as defined in dt-bindings/interrupt-controller/irq.h +Optional properties: +- qcom,reserved-chan : Reserved channel for debug purpose + Example V1 PMIC-Arbiter: spmi { @@ -56,6 +59,7 @@ Example V1 PMIC-Arbiter: qcom,ee = <0>; qcom,channel = <0>; + qcom,reserved-chan = <511>; #address-cells = <2>; #size-cells = <0>; diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0220f18658e8568c87862fef62c4436cc751e92d..e953469cbe5e5df7cbc41a3eb48b13929ee09f4f 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2692,6 +2692,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. we can turn it on. on: enable the feature + page_poison= [KNL] Boot-time parameter changing the state of + poisoning on the buddy allocator. + off: turn off poisoning + on: turn on poisoning + panic= [KNL] Kernel behaviour on panic: delay timeout > 0: seconds before rebooting timeout = 0: wait forever diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2d8fe6499090f2bd1778cc5a1808e70b27f09494..f6851d94c1af59807c0978b52ec4d97036386a08 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1418,11 +1418,20 @@ accept_ra_pinfo - BOOLEAN Functional default: enabled if accept_ra is enabled. disabled if accept_ra is disabled. +accept_ra_rt_info_min_plen - INTEGER + Minimum prefix length of Route Information in RA. + + Route Information w/ prefix smaller than this variable shall + be ignored. + + Functional default: 0 if accept_ra_rtr_pref is enabled. + -1 if accept_ra_rtr_pref is disabled. + accept_ra_rt_info_max_plen - INTEGER Maximum prefix length of Route Information in RA. - Route Information w/ prefix larger than or equal to this - variable shall be ignored. + Route Information w/ prefix larger than this variable shall + be ignored. Functional default: 0 if accept_ra_rtr_pref is enabled. -1 if accept_ra_rtr_pref is disabled. diff --git a/Documentation/networking/netlink_mmap.txt b/Documentation/networking/netlink_mmap.txt deleted file mode 100644 index 54f10478e8e30ccda77da9d345c01b9ace781e07..0000000000000000000000000000000000000000 --- a/Documentation/networking/netlink_mmap.txt +++ /dev/null @@ -1,332 +0,0 @@ -This file documents how to use memory mapped I/O with netlink. - -Author: Patrick McHardy - -Overview --------- - -Memory mapped netlink I/O can be used to increase throughput and decrease -overhead of unicast receive and transmit operations. Some netlink subsystems -require high throughput, these are mainly the netfilter subsystems -nfnetlink_queue and nfnetlink_log, but it can also help speed up large -dump operations of f.i. the routing database. - -Memory mapped netlink I/O used two circular ring buffers for RX and TX which -are mapped into the processes address space. - -The RX ring is used by the kernel to directly construct netlink messages into -user-space memory without copying them as done with regular socket I/O, -additionally as long as the ring contains messages no recvmsg() or poll() -syscalls have to be issued by user-space to get more message. - -The TX ring is used to process messages directly from user-space memory, the -kernel processes all messages contained in the ring using a single sendmsg() -call. - -Usage overview --------------- - -In order to use memory mapped netlink I/O, user-space needs three main changes: - -- ring setup -- conversion of the RX path to get messages from the ring instead of recvmsg() -- conversion of the TX path to construct messages into the ring - -Ring setup is done using setsockopt() to provide the ring parameters to the -kernel, then a call to mmap() to map the ring into the processes address space: - -- setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, ¶ms, sizeof(params)); -- setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, ¶ms, sizeof(params)); -- ring = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) - -Usage of either ring is optional, but even if only the RX ring is used the -mapping still needs to be writable in order to update the frame status after -processing. - -Conversion of the reception path involves calling poll() on the file -descriptor, once the socket is readable the frames from the ring are -processed in order until no more messages are available, as indicated by -a status word in the frame header. - -On kernel side, in order to make use of memory mapped I/O on receive, the -originating netlink subsystem needs to support memory mapped I/O, otherwise -it will use an allocated socket buffer as usual and the contents will be - copied to the ring on transmission, nullifying most of the performance gains. -Dumps of kernel databases automatically support memory mapped I/O. - -Conversion of the transmit path involves changing message construction to -use memory from the TX ring instead of (usually) a buffer declared on the -stack and setting up the frame header appropriately. Optionally poll() can -be used to wait for free frames in the TX ring. - -Structured and definitions for using memory mapped I/O are contained in -. - -RX and TX rings ----------------- - -Each ring contains a number of continuous memory blocks, containing frames of -fixed size dependent on the parameters used for ring setup. - -Ring: [ block 0 ] - [ frame 0 ] - [ frame 1 ] - [ block 1 ] - [ frame 2 ] - [ frame 3 ] - ... - [ block n ] - [ frame 2 * n ] - [ frame 2 * n + 1 ] - -The blocks are only visible to the kernel, from the point of view of user-space -the ring just contains the frames in a continuous memory zone. - -The ring parameters used for setting up the ring are defined as follows: - -struct nl_mmap_req { - unsigned int nm_block_size; - unsigned int nm_block_nr; - unsigned int nm_frame_size; - unsigned int nm_frame_nr; -}; - -Frames are grouped into blocks, where each block is a continuous region of memory -and holds nm_block_size / nm_frame_size frames. The total number of frames in -the ring is nm_frame_nr. The following invariants hold: - -- frames_per_block = nm_block_size / nm_frame_size - -- nm_frame_nr = frames_per_block * nm_block_nr - -Some parameters are constrained, specifically: - -- nm_block_size must be a multiple of the architectures memory page size. - The getpagesize() function can be used to get the page size. - -- nm_frame_size must be equal or larger to NL_MMAP_HDRLEN, IOW a frame must be - able to hold at least the frame header - -- nm_frame_size must be smaller or equal to nm_block_size - -- nm_frame_size must be a multiple of NL_MMAP_MSG_ALIGNMENT - -- nm_frame_nr must equal the actual number of frames as specified above. - -When the kernel can't allocate physically continuous memory for a ring block, -it will fall back to use physically discontinuous memory. This might affect -performance negatively, in order to avoid this the nm_frame_size parameter -should be chosen to be as small as possible for the required frame size and -the number of blocks should be increased instead. - -Ring frames ------------- - -Each frames contain a frame header, consisting of a synchronization word and some -meta-data, and the message itself. - -Frame: [ header message ] - -The frame header is defined as follows: - -struct nl_mmap_hdr { - unsigned int nm_status; - unsigned int nm_len; - __u32 nm_group; - /* credentials */ - __u32 nm_pid; - __u32 nm_uid; - __u32 nm_gid; -}; - -- nm_status is used for synchronizing processing between the kernel and user- - space and specifies ownership of the frame as well as the operation to perform - -- nm_len contains the length of the message contained in the data area - -- nm_group specified the destination multicast group of message - -- nm_pid, nm_uid and nm_gid contain the netlink pid, UID and GID of the sending - process. These values correspond to the data available using SOCK_PASSCRED in - the SCM_CREDENTIALS cmsg. - -The possible values in the status word are: - -- NL_MMAP_STATUS_UNUSED: - RX ring: frame belongs to the kernel and contains no message - for user-space. Approriate action is to invoke poll() - to wait for new messages. - - TX ring: frame belongs to user-space and can be used for - message construction. - -- NL_MMAP_STATUS_RESERVED: - RX ring only: frame is currently used by the kernel for message - construction and contains no valid message yet. - Appropriate action is to invoke poll() to wait for - new messages. - -- NL_MMAP_STATUS_VALID: - RX ring: frame contains a valid message. Approriate action is - to process the message and release the frame back to - the kernel by setting the status to - NL_MMAP_STATUS_UNUSED or queue the frame by setting the - status to NL_MMAP_STATUS_SKIP. - - TX ring: the frame contains a valid message from user-space to - be processed by the kernel. After completing processing - the kernel will release the frame back to user-space by - setting the status to NL_MMAP_STATUS_UNUSED. - -- NL_MMAP_STATUS_COPY: - RX ring only: a message is ready to be processed but could not be - stored in the ring, either because it exceeded the - frame size or because the originating subsystem does - not support memory mapped I/O. Appropriate action is - to invoke recvmsg() to receive the message and release - the frame back to the kernel by setting the status to - NL_MMAP_STATUS_UNUSED. - -- NL_MMAP_STATUS_SKIP: - RX ring only: user-space queued the message for later processing, but - processed some messages following it in the ring. The - kernel should skip this frame when looking for unused - frames. - -The data area of a frame begins at a offset of NL_MMAP_HDRLEN relative to the -frame header. - -TX limitations --------------- - -As of Jan 2015 the message is always copied from the ring frame to an -allocated buffer due to unresolved security concerns. -See commit 4682a0358639b29cf ("netlink: Always copy on mmap TX."). - -Example -------- - -Ring setup: - - unsigned int block_size = 16 * getpagesize(); - struct nl_mmap_req req = { - .nm_block_size = block_size, - .nm_block_nr = 64, - .nm_frame_size = 16384, - .nm_frame_nr = 64 * block_size / 16384, - }; - unsigned int ring_size; - void *rx_ring, *tx_ring; - - /* Configure ring parameters */ - if (setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0) - exit(1); - if (setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0) - exit(1) - - /* Calculate size of each individual ring */ - ring_size = req.nm_block_nr * req.nm_block_size; - - /* Map RX/TX rings. The TX ring is located after the RX ring */ - rx_ring = mmap(NULL, 2 * ring_size, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); - if ((long)rx_ring == -1L) - exit(1); - tx_ring = rx_ring + ring_size: - -Message reception: - -This example assumes some ring parameters of the ring setup are available. - - unsigned int frame_offset = 0; - struct nl_mmap_hdr *hdr; - struct nlmsghdr *nlh; - unsigned char buf[16384]; - ssize_t len; - - while (1) { - struct pollfd pfds[1]; - - pfds[0].fd = fd; - pfds[0].events = POLLIN | POLLERR; - pfds[0].revents = 0; - - if (poll(pfds, 1, -1) < 0 && errno != -EINTR) - exit(1); - - /* Check for errors. Error handling omitted */ - if (pfds[0].revents & POLLERR) - - - /* If no new messages, poll again */ - if (!(pfds[0].revents & POLLIN)) - continue; - - /* Process all frames */ - while (1) { - /* Get next frame header */ - hdr = rx_ring + frame_offset; - - if (hdr->nm_status == NL_MMAP_STATUS_VALID) { - /* Regular memory mapped frame */ - nlh = (void *)hdr + NL_MMAP_HDRLEN; - len = hdr->nm_len; - - /* Release empty message immediately. May happen - * on error during message construction. - */ - if (len == 0) - goto release; - } else if (hdr->nm_status == NL_MMAP_STATUS_COPY) { - /* Frame queued to socket receive queue */ - len = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); - if (len <= 0) - break; - nlh = buf; - } else - /* No more messages to process, continue polling */ - break; - - process_msg(nlh); -release: - /* Release frame back to the kernel */ - hdr->nm_status = NL_MMAP_STATUS_UNUSED; - - /* Advance frame offset to next frame */ - frame_offset = (frame_offset + frame_size) % ring_size; - } - } - -Message transmission: - -This example assumes some ring parameters of the ring setup are available. -A single message is constructed and transmitted, to send multiple messages -at once they would be constructed in consecutive frames before a final call -to sendto(). - - unsigned int frame_offset = 0; - struct nl_mmap_hdr *hdr; - struct nlmsghdr *nlh; - struct sockaddr_nl addr = { - .nl_family = AF_NETLINK, - }; - - hdr = tx_ring + frame_offset; - if (hdr->nm_status != NL_MMAP_STATUS_UNUSED) - /* No frame available. Use poll() to avoid. */ - exit(1); - - nlh = (void *)hdr + NL_MMAP_HDRLEN; - - /* Build message */ - build_message(nlh); - - /* Fill frame header: length and status need to be set */ - hdr->nm_len = nlh->nlmsg_len; - hdr->nm_status = NL_MMAP_STATUS_VALID; - - if (sendto(fd, NULL, 0, 0, &addr, sizeof(addr)) < 0) - exit(1); - - /* Advance frame offset to next frame */ - frame_offset = (frame_offset + frame_size) % ring_size; diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt index 302b5ed616a6b2a5360e88e519140284b2f0e0d0..35e17f748ca78a927df127289ccd20689382aa73 100644 --- a/Documentation/sysctl/fs.txt +++ b/Documentation/sysctl/fs.txt @@ -265,6 +265,13 @@ aio-nr can grow to. ============================================================== +mount-max: + +This denotes the maximum number of mounts that may exist +in a mount namespace. + +============================================================== + 2. /proc/sys/fs/binfmt_misc ---------------------------------------------------------- diff --git a/Makefile b/Makefile index 3a8de39e582351dc4ca3f60a1cc462e7ea470012..13486839df5b3024fdc014d4b7c5778c5630cb42 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 4 -SUBLEVEL = 55 +SUBLEVEL = 67 EXTRAVERSION = NAME = Blurry Fish Butt @@ -146,7 +146,7 @@ PHONY += $(MAKECMDGOALS) sub-make $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make @: -sub-make: FORCE +sub-make: $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \ -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS)) @@ -1005,7 +1005,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \ archprepare: archheaders archscripts prepare1 scripts_basic -prepare0: archprepare FORCE +prepare0: archprepare $(Q)$(MAKE) $(build)=. # All the preparing.. @@ -1050,7 +1050,7 @@ INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware export INSTALL_FW_PATH PHONY += firmware_install -firmware_install: FORCE +firmware_install: @mkdir -p $(objtree)/firmware $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install @@ -1070,7 +1070,7 @@ PHONY += archscripts archscripts: PHONY += __headers -__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE +__headers: $(version_h) scripts_basic asm-generic archheaders archscripts $(Q)$(MAKE) $(build)=scripts build_unifdef PHONY += headers_install_all diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index 7f672485f9c266ff34f87de006a5dc81e9058d18..73429a4b25b10200e5687a4413405c3a4f374650 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -1,10 +1,12 @@ # KEEP ALPHABETICALLY SORTED # CONFIG_DEVKMEM is not set # CONFIG_DEVMEM is not set +# CONFIG_FHANDLE is not set # CONFIG_INET_LRO is not set # CONFIG_MODULES is not set # CONFIG_OABI_COMPAT is not set # CONFIG_SYSVIPC is not set +# CONFIG_USELIB is not set CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDER_DEVICES=binder,hwbinder,vndbinder @@ -12,7 +14,6 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y CONFIG_ARMV8_DEPRECATED=y CONFIG_ASHMEM=y CONFIG_AUDIT=y -CONFIG_BLK_DEV_DM=y CONFIG_BLK_DEV_INITRD=y CONFIG_CGROUPS=y CONFIG_CGROUP_CPUACCT=y @@ -20,13 +21,13 @@ CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_SCHED=y CONFIG_CP15_BARRIER_EMULATION=y -CONFIG_DM_CRYPT=y -CONFIG_DM_VERITY=y -CONFIG_DM_VERITY_FEC=y +CONFIG_DEFAULT_SECURITY_SELINUX=y CONFIG_EMBEDDED=y CONFIG_FB=y CONFIG_HARDENED_USERCOPY=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y @@ -43,7 +44,6 @@ CONFIG_IPV6=y CONFIG_IPV6_MIP6=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y CONFIG_IP_ADVANCED_ROUTER=y @@ -65,10 +65,12 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_NETMAP=y CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y CONFIG_NET=y CONFIG_NETDEVICES=y CONFIG_NETFILTER=y -CONFIG_NETFILTER_TPROXY=y CONFIG_NETFILTER_XT_MATCH_COMMENT=y CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y CONFIG_NETFILTER_XT_MATCH_CONNMARK=y @@ -158,16 +160,15 @@ CONFIG_STAGING=y CONFIG_SWP_EMULATION=y CONFIG_SYNC=y CONFIG_TUN=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_UNIX=y -CONFIG_USB_GADGET=y CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MIDI=y CONFIG_USB_CONFIGFS_F_MTP=y CONFIG_USB_CONFIGFS_F_PTP=y -CONFIG_USB_CONFIGFS_F_ACC=y -CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_UEVENT=y -CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_OTG_WAKELOCK=y +CONFIG_USB_GADGET=y CONFIG_XFRM_USER=y diff --git a/android/configs/android-recommended.cfg b/android/configs/android-recommended.cfg index 70aaae17ad29035323edcc34ae609b1c723e8369..11df0892301bf1d63ebe4085a806614037e23e4d 100644 --- a/android/configs/android-recommended.cfg +++ b/android/configs/android-recommended.cfg @@ -7,16 +7,22 @@ # CONFIG_PM_WAKELOCKS_GC is not set # CONFIG_VT is not set CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_ARM_KERNMEM_PERMS=y CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BLK_DEV_DM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_COMPACTION=y +CONFIG_CPU_SW_DOMAIN_PAN=y CONFIG_DEBUG_RODATA=y +CONFIG_DM_CRYPT=y CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y CONFIG_DRAGONRISE_FF=y CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_EXT4_FS=y @@ -92,6 +98,7 @@ CONFIG_LOGIRUMBLEPAD2_FF=y CONFIG_LOGITECH_FF=y CONFIG_MD=y CONFIG_MEDIA_SUPPORT=y +CONFIG_MEMORY_STATE_TIME=y CONFIG_MSDOS_FS=y CONFIG_PANIC_TIMEOUT=5 CONFIG_PANTHERLORD_FF=y @@ -121,7 +128,6 @@ CONFIG_TIMER_STATS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_UHID=y -CONFIG_MEMORY_STATE_TIME=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_HIDDEV=y diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index b5ff87e6f4b71352fc8990624114c025b6c5ccb0..aee1a77934cf694e37ae579347a37bc167e43762 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -16,6 +16,7 @@ ; ; Now manually save: r12, sp, fp, gp, r25 + PUSH r30 PUSH r12 ; Saving pt_regs->sp correctly requires some extra work due to the way @@ -72,6 +73,7 @@ POPAX AUX_USER_SP 1: POP r12 + POP r30 .endm diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 69095da1fcfd1e35f16234aaf473896194064d38..47111d565a959d117ab9e2c7c9eea3b852137971 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -84,7 +84,7 @@ struct pt_regs { unsigned long fp; unsigned long sp; /* user/kernel sp depending on where we came from */ - unsigned long r12; + unsigned long r12, r30; /*------- Below list auto saved by h/w -----------*/ unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 8849c2d20ac5a1adca8494baec25a5cefc9f059e..a5278293bd158decf610cd051b201a9752fa6a40 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -69,7 +69,7 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS) FORCE $(call if_changed,cat) - @echo ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 0b60560281c7de067a77cef29e8bfd17b926c76c..8e7f26bc85ae6c9ef780fdcb9468280089374fc8 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ msm8996-v2-liquid.dtb \ msm8996-v2-dtp.dtb \ msm8996-v3-auto-cdp.dtb \ + msm8996-v3-auto-adp.dtb \ msm8996-v3-pmi8994-cdp.dtb \ msm8996-v3-pmi8994-mtp.dtb \ msm8996-v3-pmi8994-pmk8001-cdp.dtb \ @@ -27,6 +28,10 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ msm8996-v3-dtp.dtb \ msm8996-v3-pm8004-mmxf-adp.dtb \ msm8996-v3-pm8004-agave-adp.dtb \ + msm8996-v3-pm8004-agave-adp-lite.dtb \ + msm8996pro-auto-adp.dtb \ + msm8996pro-auto-adp-lite.dtb \ + msm8996pro-auto-cdp.dtb \ msm8996pro-pmi8994-cdp.dtb \ msm8996pro-pmi8994-mtp.dtb \ msm8996pro-pmi8994-pmk8001-cdp.dtb \ @@ -39,6 +44,7 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ msm8996pro-pmi8996-mtp.dtb \ msm8996pro-pmi8996-pmk8001-cdp.dtb \ msm8996pro-pmi8996-pmk8001-mtp.dtb \ + msm8996pro-v1.1-auto-cdp.dtb \ msm8996pro-v1.1-pmi8994-cdp.dtb \ msm8996pro-v1.1-pmi8994-mtp.dtb \ msm8996pro-v1.1-pmi8994-pmk8001-cdp.dtb \ @@ -51,7 +57,11 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ msm8996pro-v1.1-pmi8996-mtp.dtb \ msm8996pro-v1.1-pmi8996-pmk8001-cdp.dtb \ msm8996pro-v1.1-pmi8996-pmk8001-mtp.dtb \ + apq8096pro-auto-cdp.dtb \ + apq8096pro-v1.1-auto-adp.dtb \ + apq8096pro-v1.1-auto-adp-lite.dtb \ apq8096pro-liquid.dtb \ + apq8096pro-v1.1-auto-cdp.dtb \ msm8996-v3.0-pmi8994-cdp.dtb \ msm8996-v3.0-pmi8994-mtp.dtb \ msm8996-v3.0-pmi8994-pm8004-cdp.dtb \ @@ -82,6 +92,8 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ apq8096-v3-dragonboard.dtb \ apq8096-v3-sbc.dtb \ apq8096-v3-auto-dragonboard.dtb \ + apq8096-v3-auto-adp.dtb \ + apq8096-v3-auto-cdp.dtb \ apq8096-v3.0-pmi8994-cdp.dtb \ apq8096-v3.0-pmi8994-mtp.dtb \ apq8096-v3.0-pmi8994-pm8004-cdp.dtb \ @@ -109,7 +121,10 @@ dtbo-$(CONFIG_ARCH_MSM8998) += \ msm8998-v2-cdp-overlay.dtbo \ msm8998-v2-mtp-overlay.dtbo \ msm8998-v2.1-cdp-overlay.dtbo \ - msm8998-v2.1-mtp-overlay.dtbo + msm8998-v2.1-mtp-overlay.dtbo \ + msm8998-qrd-overlay.dtbo \ + msm8998-qrd-vr1-overlay.dtbo \ + msm8998-qrd-skuk-overlay.dtbo msm8998-cdp-overlay.dtbo-base := msm8998.dtb msm8998-mtp-overlay.dtbo-base := msm8998.dtb @@ -117,6 +132,9 @@ msm8998-v2-cdp-overlay.dtbo-base := msm8998-v2.dtb msm8998-v2-mtp-overlay.dtbo-base := msm8998-v2.dtb msm8998-v2.1-cdp-overlay.dtbo-base := msm8998-v2.1.dtb msm8998-v2.1-mtp-overlay.dtbo-base := msm8998-v2.1.dtb +msm8998-qrd-overlay.dtbo-base := msm8998-qrd.dtb +msm8998-qrd-vr1-overlay.dtbo-base := msm8998-qrd-vr1.dtb +msm8998-qrd-skuk-overlay.dtbo-base := msm8998-qrd-skuk.dtb else dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ msm8998-rumi.dtb \ @@ -141,6 +159,7 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ apq8098-v2-qrd.dtb \ apq8098-v2-qrd-skuk-hdk.dtb \ msm8998-v2.1-mtp.dtb \ + msm8998-v2.1-mtp-4k-display.dtb \ msm8998-v2.1-cdp.dtb \ msm8998-v2.1-qrd.dtb \ apq8098-v2.1-mtp.dtb \ @@ -178,6 +197,7 @@ dtb-$(CONFIG_ARCH_SDM660) += sdm660-sim.dtb \ sda660-pm660a-cdp.dtb \ sda660-pm660a-mtp.dtb \ sda660-pm660a-rcm.dtb \ + sda660-pm660a-qrd-hdk.dtb \ sdm660-headset-jacktype-no-cdp.dtb \ sdm660-headset-jacktype-no-rcm.dtb \ sdm660-pm660a-headset-jacktype-no-cdp.dtb \ @@ -228,6 +248,7 @@ dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \ sda630-pm660a-mtp.dtb \ sda630-pm660a-cdp.dtb \ sda630-pm660a-rcm.dtb \ + sda630-pm660a-qrd-hdk.dtb \ sdm630-headset-jacktype-no-cdp.dtb \ sdm630-headset-jacktype-no-rcm.dtb \ sdm630-pm660a-headset-jacktype-no-cdp.dtb \ diff --git a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi index 57a0467c6fc22720f06cc1dbf4a9ae6b761201ce..ea8fc87c9b676a53e8176a028aec749c6198632e 100644 --- a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi +++ b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi @@ -528,6 +528,19 @@ }; &soc { + qcom,ntn_avb { + compatible = "qcom,ntn_avb"; + + ntn-rst-gpio = <&pm8994_gpios 13 0>; + + vdd-ntn-hsic-supply = <&pm8994_l25>; + vdd-ntn-pci-supply = <&pm8994_s4>; + vdd-ntn-io-supply = <&pm8994_s4>; + + qcom,ntn-rst-delay-msec = <100>; + qcom,ntn-rc-num = <1>; + }; + qcom,cnss { wlan-bootstrap-gpio = <&tlmm 46 0>; wlan-en-gpio = <&pm8994_gpios 8 0>; @@ -692,22 +705,9 @@ }; qcom,msm-dai-tdm-tert-rx { - qcom,msm-cpudai-tdm-group-num-ports = <5>; - qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 - 36902 36904>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&tert_tdm_dout_active>; pinctrl-1 = <&tert_tdm_dout_sleep>; - dai_tert_tdm_rx_4: qcom,msm-dai-q6-tdm-tert-rx-4 { - compatible = "qcom,msm-dai-q6-tdm"; - qcom,msm-cpudai-tdm-dev-id = <36904>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; - qcom,msm-cpudai-tdm-data-align = <0>; - }; }; qcom,msm-dai-tdm-quat-rx { @@ -789,11 +789,14 @@ status = "okay"; }; - gpio@cc00 { /* GPIO 13 */ - qcom,mode = <1>; /* DIGITAL OUT */ - qcom,vin-sel = <2>; /* 1.8 */ - qcom,src-sel = <0>; /* GPIO */ - qcom,master-en = <1>; /* Enable GPIO */ + gpio@cc00 { /* GPIO 13 - NTN_RST */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,pull = <5>; + qcom,vin-sel = <2>; /* 1.8 */ + qcom,out-strength = <1>; + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* Enable GPIO */ status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts new file mode 100644 index 0000000000000000000000000000000000000000..a91ec5eeb2e74a4262aa60b8c5b0fb880edfa3f4 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts @@ -0,0 +1,161 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "apq8096-v3.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096 v3 AUTO ADP"; + compatible = "qcom,apq8096-adp", "qcom,apq8096", "qcom,adp"; + qcom,msm-id = <311 0x30001>; + qcom,board-id = <0x02010019 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <122 0>; + spi-max-frequency = <5000000>; + }; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&hl7509_en_vreg { + status = "ok"; +}; + +&hl7509_vreg { + status = "ok"; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + +&gfx_cpr { + vdd-supply = <&hl7509_vreg>; + qcom,cpr-step-quot-init-min = <20>; + qcom,cpr-step-quot-init-max = <26>; + qcom,voltage-step = <10000>; + /delete-property/ qcom,cpr-enable; +}; + +&gfx_vreg { + qcom,cpr-voltage-ceiling = + <600000 670000 670000 750000 830000 + 910000 960000 1020000>; + qcom,cpr-voltage-floor = + <600000 600000 600000 600000 600000 + 600000 600000 600000>; +}; + +&pm8994_l3 { + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <875000>; + qcom,init-voltage = <875000>; +}; + +&pm8994_l11 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + qcom,init-voltage = <850000>; +}; + +&pm8994_l17 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; +}; + +&pm8994_l23 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; +}; + +&pm8994_l27 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + qcom,init-voltage = <800000>; +}; + +&pm8994_l29 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + qcom,init-voltage = <2500000>; +}; + +&rpm_bus { + rpm-regulator-ldoa26 { + /delete-node/ pm8994_l26_corner; + /delete-node/ pm8994_l26_floor_corner; + + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts new file mode 100644 index 0000000000000000000000000000000000000000..e59003f2d31616a86be83253156cb40967dd3bbb --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts @@ -0,0 +1,44 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "apq8096-v3.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-auto-cdp.dtsi" +#include "msm8996v3-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096 v3 AUTO CDP"; + compatible = "qcom,apq8096-cdp", "qcom,apq8096", "qcom,cdp"; + qcom,msm-id = <311 0x30001>; + qcom,board-id = <0x03010001 0>; +}; + +&soc { + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <127 0>; + spi-max-frequency = <5000000>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts new file mode 100644 index 0000000000000000000000000000000000000000..d438bbe828ed1bcadb87ef8038832e38b169c433 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts @@ -0,0 +1,44 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "apq8096pro.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-auto-cdp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096 pro AUTO CDP"; + compatible = "qcom,apq8096-cdp", "qcom,apq8096", "qcom,cdp"; + qcom,msm-id = <316 0x10000>; + qcom,board-id = <0x03010001 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <127 0>; + spi-max-frequency = <5000000>; + }; +}; + +&soc { + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp-lite.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp-lite.dts new file mode 100644 index 0000000000000000000000000000000000000000..9c4ff9f184e7e16a44a2100cd69f0fa2e08d5233 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp-lite.dts @@ -0,0 +1,86 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "apq8096pro.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096pro V1.1 AUTO ADP LITE"; + compatible = "qcom,apq8096-adp", "qcom,msm8996", "qcom,adp"; + qcom,msm-id = <316 0x10001>; + qcom,board-id = <0x03010019 0>; +}; + +&spi_9 { + status = "disabled"; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; + + i2c@75b6000 { /* BLSP8 */ + /* ADV7533 HDMI Bridge Chip removed on ADP Lite */ + adv7533@3d { + status = "disabled"; + }; + adv7533@39 { + status = "disabled"; + }; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts new file mode 100644 index 0000000000000000000000000000000000000000..497f3f10fe24f69832856aa7f1025eb5163117e7 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts @@ -0,0 +1,88 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "apq8096pro-v1.1.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996pro AUTO ADP"; + compatible = "qcom,apq8096-adp", "qcom,msm8996", "qcom,adp"; + qcom,msm-id = <316 0x10001>; + qcom,board-id = <0x02010019 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <122 0>; + spi-max-frequency = <5000000>; + }; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; + + qcom,adv7481@70 { + qcom,cam-vreg-min-voltage = <1300000 0 1800000>; + qcom,cam-vreg-max-voltage = <1300000 0 1800000>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts new file mode 100644 index 0000000000000000000000000000000000000000..2c54dfe19e1821846b657b886ddecaaa4d7d427b --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts @@ -0,0 +1,37 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "apq8096pro-v1.1.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-auto-cdp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096 pro v1.1 AUTO CDP"; + compatible = "qcom,msm8996-cdp", "qcom,msm8996", "qcom,cdp"; + qcom,msm-id = <316 0x10001>; + qcom,board-id = <0x03010001 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <127 0>; + spi-max-frequency = <5000000>; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1.dtsi b/arch/arm/boot/dts/qcom/apq8096pro-v1.1.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..043309f47bc697e4bdfa0da31cc2e5c1159be273 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1.dtsi @@ -0,0 +1,34 @@ +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * As a general rule, only version-specific property overrides should be placed + * inside this file. Common device definitions should be placed inside the + * msm8996.dtsi file. + */ + +#include "msm8996pro-v1.1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8096 pro v1.1"; + qcom,msm-id = <312 0x10001>; +}; + +&soc { + qcom,rmnet-ipa { + status = "disabled"; + }; +}; + +&ipa_hw { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/apq8098-cdp.dts b/arch/arm/boot/dts/qcom/apq8098-cdp.dts index c8011ff957c015eb10ba43ec695dfb975c654f72..54a41ab044987e04d72bfd75bb2bbce4d0811928 100644 --- a/arch/arm/boot/dts/qcom/apq8098-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-cdp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-mtp.dts b/arch/arm/boot/dts/qcom/apq8098-mtp.dts index 7af82a91e9358f9cecff64efbcbd959819e40be4..afb0f7b3fb9185e2e11a71d1d4a9254413c6bbb5 100644 --- a/arch/arm/boot/dts/qcom/apq8098-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-mtp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2-cdp.dts b/arch/arm/boot/dts/qcom/apq8098-v2-cdp.dts index b01c85bdbac6683fe473a574be4ba092e37f33ad..764847846a5bec03b9947806d924f04fc1679181 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2-cdp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2-mtp.dts b/arch/arm/boot/dts/qcom/apq8098-v2-mtp.dts index a6e6f15bfa340b21c310e581c4c3622392b99090..77bae625e2418b0fd069fa7d2e487d3b361db456 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2-mtp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/apq8098-v2-qrd-skuk-hdk.dts index 7aeb8e36cca267e1cce1cb76af41348f6e618058..2207ab694917693d61f00d7286bc6b668182d780 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2-qrd-skuk-hdk.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2-qrd-skuk-hdk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "apq8098-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-skuk-hdk.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2-qrd.dts b/arch/arm/boot/dts/qcom/apq8098-v2-qrd.dts index 0b808e47c915f80e1c478228bd5cf9e07b606839..9e7b88a2d78cc001ff30f1a0cbd7e8d2bae7e122 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2-qrd.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2-qrd.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-cdp.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-cdp.dts index e41a66eff10363d9e0363a836d44680420d9bfc5..a24835e592499553be10747e20c8751b56064497 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2.1-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-cdp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts index d9b1cb8741eb60f752fc08dde7ba8867257e1b3c..03e1e05a3739e48df0872f9509a8773f200a9e84 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { @@ -34,10 +35,6 @@ qcom,mdss-pref-prim-intf = "hdmi"; }; -&msm_gpu { - dma-coherent; -}; - &sde_hdmi { qcom,display-type = "primary"; }; diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-mtp.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-mtp.dts index 5684e1849b0d06c4135863f79dbd5254b5085e28..93887a39eecf43ed85b4b4d22f14f4867bd1d851 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2.1-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-mtp.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-qrd.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-qrd.dts index 0f315d7c893d7868b66a8cf659340576a9185dac..fb5e4579abb65598ba618e52360c96721647f15f 100644 --- a/arch/arm/boot/dts/qcom/apq8098-v2.1-qrd.dts +++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-qrd.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "apq8098-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/dsi-panel-jdi-a407-dualmipi-wqhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-jdi-a407-dualmipi-wqhd-cmd.dtsi index 62115cf6f98a0d6f8d09b10e3a6dfbd8f38b1780..0ff02042600d7928ecf351a03922ae3180216c73 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-jdi-a407-dualmipi-wqhd-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-jdi-a407-dualmipi-wqhd-cmd.dtsi @@ -15,6 +15,7 @@ qcom,mdss-dsi-panel-name = "JDI a407 wqhd cmd mode dsi panel"; qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-panel-clockrate = <838600000>; qcom,mdss-dsi-virtual-channel-id = <0>; qcom,mdss-dsi-stream = <0>; qcom,mdss-dsi-panel-width = <720>; @@ -79,6 +80,8 @@ qcom,adjust-timer-wakeup-ms = <1>; qcom,mdss-dsi-reset-sequence = <1 20>, <0 10>, <1 20>; + qcom,dcs-cmd-by-left; + qcom,config-select = <&dsi_dual_jdi_a407_cmd_config0>; dsi_dual_jdi_a407_cmd_config0: config0 { diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi index 7774a28ff49574ecac0f1471638822f7f222691c..1d7836ca475973ea4ac2dae9c8fdc764708049c1 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi @@ -192,8 +192,8 @@ 15 01 00 00 00 00 02 0b 55 15 01 00 00 00 00 02 0c 14 15 01 00 00 00 00 02 0d 28 - 15 01 00 00 00 00 02 0e 00 - 15 01 00 00 00 00 02 0f 00 + 15 01 00 00 00 00 02 0e 40 + 15 01 00 00 00 00 02 0f 80 15 01 00 00 00 00 02 10 00 15 01 00 00 00 00 02 11 22 15 01 00 00 00 00 02 12 0a @@ -208,17 +208,17 @@ 15 01 00 00 00 00 02 1d 00 15 01 00 00 00 00 02 1e 80 15 01 00 00 00 00 02 1f 00 - 15 01 00 00 00 00 02 20 00 + 15 01 00 00 00 00 02 20 03 15 01 00 00 00 00 02 21 03 - 15 01 00 00 00 00 02 22 22 + 15 01 00 00 00 00 02 22 25 15 01 00 00 00 00 02 23 25 15 01 00 00 00 00 02 24 00 15 01 00 00 00 00 02 25 a7 - 15 01 00 00 00 00 02 26 00 + 15 01 00 00 00 00 02 26 80 15 01 00 00 00 00 02 27 a5 15 01 00 00 00 00 02 28 06 15 01 00 00 00 00 02 29 85 - 15 01 00 00 00 00 02 2a 3f + 15 01 00 00 00 00 02 2a 30 15 01 00 00 00 00 02 2b 97 15 01 00 00 00 00 02 2f 25 15 01 00 00 00 00 02 30 26 @@ -240,7 +240,7 @@ 15 01 00 00 00 00 02 45 00 15 01 00 00 00 00 02 46 00 15 01 00 00 00 00 02 47 00 - 15 01 00 00 00 00 02 48 00 + 15 01 00 00 00 00 02 48 03 15 01 00 00 00 00 02 49 03 15 01 00 00 00 00 02 4a 00 15 01 00 00 00 00 02 4b 00 @@ -250,7 +250,7 @@ 15 01 00 00 00 00 02 4f 4c 15 01 00 00 00 00 02 50 0d 15 01 00 00 00 00 02 51 0e - 15 01 00 00 00 00 02 52 23 + 15 01 00 00 00 00 02 52 20 15 01 00 00 00 00 02 53 97 15 01 00 00 00 00 02 54 4b 15 01 00 00 00 00 02 55 4c diff --git a/arch/arm/boot/dts/qcom/dsi-panel-rm67195-amoled-fhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-rm67195-amoled-fhd-cmd.dtsi index 49ae94e7a97579f15eec4191802c6019f371eb04..6ed6a1b3da6c4e4f8bde8f0c5510f460e7bdc6a8 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-rm67195-amoled-fhd-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-rm67195-amoled-fhd-cmd.dtsi @@ -37,6 +37,7 @@ qcom,mdss-dsi-color-order = "rgb_swap_rgb"; qcom,mdss-dsi-on-command = [ 15 01 00 00 00 00 02 fe 0d + 15 01 00 00 00 00 02 0b c0 15 01 00 00 00 00 02 42 00 15 01 00 00 00 00 02 18 08 15 01 00 00 00 00 02 08 41 @@ -52,8 +53,12 @@ 15 01 00 00 00 00 02 28 40 15 01 00 00 02 00 02 29 4f 15 01 00 00 00 00 02 fe 04 + 15 01 00 00 00 00 02 0a d8 + 15 01 00 00 00 00 02 0c e6 + 15 01 00 00 00 00 02 4e 20 15 01 00 00 00 00 02 4f 1b - 15 01 00 00 02 00 02 50 2f + 15 01 00 00 00 00 02 50 2f + 15 01 00 00 02 00 02 51 08 15 01 00 00 00 00 02 fe 09 15 01 00 00 00 00 02 00 08 15 01 00 00 00 00 02 01 08 diff --git a/arch/arm/boot/dts/qcom/external-mdm9640.dtsi b/arch/arm/boot/dts/qcom/external-mdm9640.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..4c0170a70bf5f747194d43e95068098a1cd86c72 --- /dev/null +++ b/arch/arm/boot/dts/qcom/external-mdm9640.dtsi @@ -0,0 +1,52 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdm0: qcom,mdm0 { + compatible = "qcom,ext-mdm9x45"; + cell-index = <0>; + #address-cells = <0>; + interrupt-parent = <&mdm0>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-names = + "err_fatal_irq", + "status_irq"; + status = "disabled"; + }; + + mdm1: qcom,mdm1 { + compatible = "qcom,ext-mdm9x45"; + cell-index = <0>; + #address-cells = <0>; + interrupt-parent = <&mdm1>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-names = + "err_fatal_irq", + "status_irq"; + status = "disabled"; + }; + + mdm2: qcom,mdm2 { + compatible = "qcom,ext-mdm9x45"; + cell-index = <0>; + #address-cells = <0>; + interrupt-parent = <&mdm2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-names = + "err_fatal_irq", + "status_irq"; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi index ecfff13f93556f54cf0a3ebbbb41bf7bf91b9ba7..da28e56bc2dfa51294864ef7a8e5e248a1278a38 100644 --- a/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi @@ -176,4 +176,16 @@ */ iommus = <&mmss_smmu 42>; }; + + iommu_coherent_test_device { + compatible = "iommu-debug-test"; + /* + * 43 shouldn't be used by anyone on the mmss_smmu. We just + * need _something_ here to get this node recognized by the + * SMMU driver. Our test uses ATOS, which doesn't use SIDs + * anyways, so using a dummy value is ok. + */ + iommus = <&mmss_smmu 43>; + dma-coherent; + }; }; diff --git a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi index 97a134b46713127f69fdd5c60e5dee13986bda87..d4962df321ed836f5db2717b9c3fcccd8ed73fe8 100644 --- a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi @@ -377,14 +377,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36864>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_pri_tdm_rx_0: qcom,msm-dai-q6-tdm-pri-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36864>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -395,14 +396,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36865>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36865>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -413,14 +415,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36880>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_sec_tdm_rx_0: qcom,msm-dai-q6-tdm-sec-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36880>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -431,14 +434,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36881>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_sec_tdm_tx_0: qcom,msm-dai-q6-tdm-sec-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36881>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -449,14 +453,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36896>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -467,14 +472,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36897 >; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897 >; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -485,14 +491,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36912>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -503,14 +510,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36913 >; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913 >; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index d450f43f8c22d4cb4002724efcf7b7717c8a5cad..3a7514397139fab6252d889363d29a1d16e50a66 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -445,14 +445,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36864>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_pri_tdm_rx_0: qcom,msm-dai-q6-tdm-pri-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36864>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -463,14 +464,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36865>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36865>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -481,14 +483,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36880>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_sec_tdm_rx_0: qcom,msm-dai-q6-tdm-sec-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36880>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -499,14 +502,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36881>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_sec_tdm_tx_0: qcom,msm-dai-q6-tdm-sec-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36881>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -517,14 +521,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36896>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -535,14 +540,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36897 >; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897 >; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -553,14 +559,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36912>; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -571,14 +578,15 @@ qcom,msm-cpudai-tdm-group-num-ports = <1>; qcom,msm-cpudai-tdm-group-port-id = <36913 >; qcom,msm-cpudai-tdm-clk-rate = <1536000>; + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913 >; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <1>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <1>; - qcom,msm-cpudai-tdm-data-delay = <1>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi index f20238123bcaf9072c1baeb3c66f95a72b9c0ff7..7fde74f3d570968359e2f2a1f47d9f031ce7d697 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi @@ -41,6 +41,7 @@ interrupt-names = "kpdpwr", "resin", "resin-bark", "kpdpwr-resin-bark"; qcom,pon-dbc-delay = <15625>; + qcom,kpdpwr-sw-debounce; qcom,system-reset; qcom,store-hard-reset-reason; @@ -546,6 +547,7 @@ qcom,rradc-base = <0x4500>; qcom,fg-esr-timer-awake = <96>; qcom,fg-esr-timer-asleep = <256>; + qcom,fg-esr-timer-charging = <96>; qcom,cycle-counter-en; status = "okay"; diff --git a/arch/arm/boot/dts/qcom/msm-pm660l.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l.dtsi index fdc04b9726b41561286368aaaeeb8282f8f1c5e4..0f18ba5c94c74de96e0dfcaf8dae0259a1075de2 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660l.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660l.dtsi @@ -380,9 +380,6 @@ qcom,led-name = "led:switch_1"; qcom,led-mask = <4>; qcom,default-led-trigger = "switch1_trigger"; - pinctrl-names = "led_enable","led_disable"; - pinctrl-0 = <&led_enable>; - pinctrl-1 = <&led_disable>; }; }; @@ -415,7 +412,9 @@ compatible = "qcom,qpnp-oledb-regulator"; #address-cells = <1>; #size-cells = <1>; + qcom,pmic-revid = <&pm660l_revid>; reg = <0xe000 0x100>; + qcom,pbs-client = <&pm660l_pbs>; label = "oledb"; regulator-name = "regulator-oledb"; @@ -463,6 +462,8 @@ qcom,qpnp-lab-slew-rate = <5000>; qcom,qpnp-lab-init-voltage = <4600000>; qcom,qpnp-lab-init-amoled-voltage = <4600000>; + + qcom,notify-lab-vreg-ok-sts; }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi index 2d2b628ca815031616b9e6f2947058c142c1bf48..ad32ab01c5fb7e22d83361574316b0e0a27ecd1e 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi @@ -762,9 +762,6 @@ qcom,led-name = "led:switch_1"; qcom,led-mask = <4>; qcom,default-led-trigger = "switch1_trigger"; - pinctrl-names = "led_enable","led_disable"; - pinctrl-0 = <&led_enable>; - pinctrl-1 = <&led_disable>; }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi index c1fa33f5ca322198eb763a8fa0cf01c924918388..eae8c29fe21e9be2d3c499916360d195b42e3067 100644 --- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi @@ -44,6 +44,258 @@ status = "ok"; }; +&pcie0 { + qcom,phy-sequence = <0x404 0x01 0x00 + 0x034 0x1c 0x00 + 0x038 0x10 0x00 + 0x174 0x33 0x00 + 0x194 0x06 0x00 + 0x0c8 0x42 0x00 + 0x128 0x00 0x00 + 0x144 0xff 0x00 + 0x148 0x1f 0x00 + 0x178 0x01 0x00 + 0x19c 0x01 0x00 + 0x18c 0x00 0x00 + 0x184 0x0a 0x00 + 0x00c 0x09 0x00 + 0x0d0 0x82 0x00 + 0x0e4 0x03 0x00 + 0x0e0 0x55 0x00 + 0x0dc 0x55 0x00 + 0x054 0x00 0x00 + 0x050 0x1a 0x00 + 0x04c 0x0a 0x00 + 0x174 0x33 0x00 + 0x03c 0x02 0x00 + 0x040 0x1f 0x00 + 0x0ac 0x04 0x00 + 0x078 0x0b 0x00 + 0x084 0x16 0x00 + 0x090 0x28 0x00 + 0x10c 0x00 0x00 + 0x108 0x80 0x00 + 0x010 0x01 0x00 + 0x01c 0x31 0x00 + 0x020 0x01 0x00 + 0x014 0x02 0x00 + 0x018 0x00 0x00 + 0x024 0x2f 0x00 + 0x028 0x19 0x00 + 0x0c4 0x15 0x00 + 0x070 0x0f 0x00 + 0x048 0x0f 0x00 + 0x074 0x19 0x00 + 0x038 0x10 0x00 + 0x178 0x00 0x00 + 0x0c4 0x40 0x00 + 0x400 0x00 0x00 + 0x408 0x03 0x00>; + + qcom,port-phy-sequence = <0x1068 0x45 0x00 + 0x1094 0x06 0x00 + 0x1310 0x1c 0x00 + 0x1318 0x17 0x00 + 0x12d8 0x01 0x00 + 0x12dc 0x00 0x00 + 0x12e0 0xdb 0x00 + 0x1320 0x18 0x00 + 0x121c 0x04 0x00 + 0x1210 0x04 0x00 + 0x1458 0x4c 0x00 + 0x14a0 0x00 0x00 + 0x14a4 0x01 0x00 + 0x14a8 0x05 0x00 + 0x1248 0x4b 0x00 + 0x131c 0x14 0x00 + 0x1454 0x05 0x00 + 0x1404 0x02 0x00 + 0x146c 0x00 0x00 + 0x1460 0xa3 0x00 + 0x1318 0x19 0x00 + 0x1428 0x0e 0x00 + 0x1054 0x08 0x00 + 0x14f8 0x04 0x00 + 0x14ec 0x06 0x00 + 0x104c 0x2e 0x00 + 0x1404 0x03 0x0a + 0x1400 0x00 0x00 + 0x1408 0x0a 0x00>; + + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; +}; + +&pcie1 { + qcom,phy-sequence = <0x404 0x01 0x00 + 0x034 0x1c 0x00 + 0x038 0x10 0x00 + 0x174 0x33 0x00 + 0x194 0x06 0x00 + 0x0c8 0x42 0x00 + 0x128 0x00 0x00 + 0x144 0xff 0x00 + 0x148 0x1f 0x00 + 0x178 0x01 0x00 + 0x19c 0x01 0x00 + 0x18c 0x00 0x00 + 0x184 0x0a 0x00 + 0x00c 0x09 0x00 + 0x0d0 0x82 0x00 + 0x0e4 0x03 0x00 + 0x0e0 0x55 0x00 + 0x0dc 0x55 0x00 + 0x054 0x00 0x00 + 0x050 0x1a 0x00 + 0x04c 0x0a 0x00 + 0x174 0x33 0x00 + 0x03c 0x02 0x00 + 0x040 0x1f 0x00 + 0x0ac 0x04 0x00 + 0x078 0x0b 0x00 + 0x084 0x16 0x00 + 0x090 0x28 0x00 + 0x10c 0x00 0x00 + 0x108 0x80 0x00 + 0x010 0x01 0x00 + 0x01c 0x31 0x00 + 0x020 0x01 0x00 + 0x014 0x02 0x00 + 0x018 0x00 0x00 + 0x024 0x2f 0x00 + 0x028 0x19 0x00 + 0x0c4 0x15 0x00 + 0x070 0x0f 0x00 + 0x048 0x0f 0x00 + 0x074 0x19 0x00 + 0x038 0x10 0x00 + 0x178 0x00 0x00 + 0x0c4 0x40 0x00 + 0x400 0x00 0x00 + 0x408 0x03 0x00>; + + qcom,port-phy-sequence = <0x2068 0x45 0x00 + 0x2094 0x06 0x00 + 0x2310 0x1c 0x00 + 0x2318 0x17 0x00 + 0x22d8 0x01 0x00 + 0x22dc 0x00 0x00 + 0x22e0 0xdb 0x00 + 0x2320 0x18 0x00 + 0x221c 0x04 0x00 + 0x2210 0x04 0x00 + 0x2458 0x4c 0x00 + 0x24a0 0x00 0x00 + 0x24a4 0x01 0x00 + 0x24a8 0x05 0x00 + 0x2248 0x4b 0x00 + 0x231c 0x14 0x00 + 0x2454 0x05 0x00 + 0x2404 0x02 0x00 + 0x246c 0x00 0x00 + 0x2460 0xa3 0x00 + 0x2318 0x19 0x00 + 0x2428 0x0e 0x00 + 0x2054 0x08 0x00 + 0x24f8 0x04 0x00 + 0x24ec 0x06 0x00 + 0x204c 0x2e 0x00 + 0x2404 0x03 0x0a + 0x2400 0x00 0x00 + 0x2408 0x0a 0x00>; + + qcom,msi-gicm-addr = <0x09BD0040>; + qcom,msi-gicm-base = <0x240>; + + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; +}; + +&pcie2 { + qcom,phy-sequence = <0x404 0x01 0x00 + 0x034 0x1c 0x00 + 0x038 0x10 0x00 + 0x174 0x33 0x00 + 0x194 0x06 0x00 + 0x0c8 0x42 0x00 + 0x128 0x00 0x00 + 0x144 0xff 0x00 + 0x148 0x1f 0x00 + 0x178 0x01 0x00 + 0x19c 0x01 0x00 + 0x18c 0x00 0x00 + 0x184 0x0a 0x00 + 0x00c 0x09 0x00 + 0x0d0 0x82 0x00 + 0x0e4 0x03 0x00 + 0x0e0 0x55 0x00 + 0x0dc 0x55 0x00 + 0x054 0x00 0x00 + 0x050 0x1a 0x00 + 0x04c 0x0a 0x00 + 0x174 0x33 0x00 + 0x03c 0x02 0x00 + 0x040 0x1f 0x00 + 0x0ac 0x04 0x00 + 0x078 0x0b 0x00 + 0x084 0x16 0x00 + 0x090 0x28 0x00 + 0x10c 0x00 0x00 + 0x108 0x80 0x00 + 0x010 0x01 0x00 + 0x01c 0x31 0x00 + 0x020 0x01 0x00 + 0x014 0x02 0x00 + 0x018 0x00 0x00 + 0x024 0x2f 0x00 + 0x028 0x19 0x00 + 0x0c4 0x15 0x00 + 0x070 0x0f 0x00 + 0x048 0x0f 0x00 + 0x074 0x19 0x00 + 0x038 0x10 0x00 + 0x178 0x00 0x00 + 0x0c4 0x40 0x00 + 0x400 0x00 0x00 + 0x408 0x03 0x00>; + + qcom,port-phy-sequence = <0x3068 0x45 0x00 + 0x3094 0x06 0x00 + 0x3310 0x1c 0x00 + 0x3318 0x17 0x00 + 0x32d8 0x01 0x00 + 0x32dc 0x00 0x00 + 0x32e0 0xdb 0x00 + 0x3320 0x18 0x00 + 0x321c 0x04 0x00 + 0x3210 0x04 0x00 + 0x3458 0x4c 0x00 + 0x34a0 0x00 0x00 + 0x34a4 0x01 0x00 + 0x34a8 0x05 0x00 + 0x3248 0x4b 0x00 + 0x331c 0x14 0x00 + 0x3454 0x05 0x00 + 0x3404 0x02 0x00 + 0x346c 0x00 0x00 + 0x3460 0xa3 0x00 + 0x3318 0x19 0x00 + 0x3428 0x0e 0x00 + 0x3054 0x08 0x00 + 0x34f8 0x04 0x00 + 0x34ec 0x06 0x00 + 0x304c 0x2e 0x00 + 0x3404 0x03 0x0a + 0x3400 0x00 0x00 + 0x3408 0x0a 0x00>; + + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; +}; + &uartblsp2dm1 { status = "ok"; pinctrl-names = "default"; @@ -292,12 +544,68 @@ &mdss_hdmi_cec_suspend>; }; -#include "msm8996-mdss-panels.dtsi" +#include "msm8996-sde-display.dtsi" &mdss_mdp { qcom,mdss-pref-prim-intf = "dsi"; }; +&dsi_adv_7533_1 { + qcom,dsi-display-active; + qcom,dsi-panel = <&dsi_adv7533_1080p>; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <3300000>; + qcom,supply-max-voltage = <3300000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + }; +}; + +&dsi_adv_7533_2 { + qcom,dsi-display-active; + qcom,dsi-panel = <&dsi_adv7533_1080p>; + + qcom,panel-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdd"; + qcom,supply-min-voltage = <3300000>; + qcom,supply-max-voltage = <3300000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1800000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + }; +}; + &mdss_dsi { hw-config = "dual_dsi"; }; @@ -478,6 +786,19 @@ }; &soc { + qcom,ntn_avb { + compatible = "qcom,ntn_avb"; + + ntn-rst-gpio = <&pm8994_gpios 13 0>; + + vdd-ntn-hsic-supply = <&pm8994_l25>; + vdd-ntn-pci-supply = <&pm8994_s4>; + vdd-ntn-io-supply = <&pm8994_s4>; + + qcom,ntn-rst-delay-msec = <100>; + qcom,ntn-rc-num = <1>; + }; + i2c@75ba000 { synaptics@20 { compatible = "synaptics,dsx"; @@ -499,6 +820,7 @@ clock-names = "iface_clk", "core_clk"; clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, <&clock_gcc clk_gcc_blsp2_qup6_i2c_apps_clk>; + status = "disabled"; }; }; @@ -645,9 +967,17 @@ asoc-codec-names = "msm-stub-codec.1"; }; - usb_detect { + usb_detect: usb_detect { compatible = "qcom,gpio-usbdetect"; - qcom,vbus-det-irq = <&pm8994_gpios 17 0>; + qcom,vbus-det-gpio = <&pm8994_gpios 17 0>; + interrupt-parent = <&spmi_bus>; + interrupts = <0x0 0x9 0x0 IRQ_TYPE_NONE>; + interrupt-names ="pmic_id_irq"; + }; + + loopback1: qcom,msm-pcm-loopback-low-latency { + compatible = "qcom,msm-pcm-loopback"; + qcom,msm-pcm-loopback-low-latency; }; loopback1: qcom,msm-pcm-loopback-low-latency { @@ -680,22 +1010,9 @@ }; qcom,msm-dai-tdm-tert-rx { - qcom,msm-cpudai-tdm-group-num-ports = <5>; - qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 - 36902 36904>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&tert_tdm_dout_active>; pinctrl-1 = <&tert_tdm_dout_sleep>; - dai_tert_tdm_rx_4: qcom,msm-dai-q6-tdm-tert-rx-4 { - compatible = "qcom,msm-dai-q6-tdm"; - qcom,msm-cpudai-tdm-dev-id = <36904>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; - qcom,msm-cpudai-tdm-data-align = <0>; - }; }; qcom,msm-dai-tdm-quat-rx { @@ -788,14 +1105,14 @@ status = "okay"; }; - gpio@cc00 { /* GPIO 13 - HPH_EN0 */ - qcom,mode = <1>; - qcom,output-type = <0>; + gpio@cc00 { /* GPIO 13 - NTN_RST */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,output-type = <0>; /* CMOS logic */ qcom,pull = <5>; - qcom,vin-sel = <2>; + qcom,vin-sel = <2>; /* 1.8 */ qcom,out-strength = <1>; - qcom,src-sel = <2>; - qcom,master-en = <1>; + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* Enable GPIO */ status = "okay"; }; @@ -849,15 +1166,7 @@ }; &usb3 { - interrupt-parent = <&usb3>; - interrupts = <0 1 2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0x0 0xffffffff>; - interrupt-map = <0x0 0 &intc 0 133 0 - 0x0 1 &intc 0 180 0 - 0x0 2 &spmi_bus 0x0 0x0 0x9 0x0>; - interrupt-names = "hs_phy_irq", "pwr_event_irq", "pmic_id_irq"; - + extcon = <&usb_detect>; vbus_dwc3-supply = <&usb_otg_switch>; vdda33-supply = <&pm8994_l24>; vdda18-supply = <&pm8994_l12>; @@ -920,6 +1229,7 @@ pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>; clocks = <&clock_gcc clk_bb_clk2_pin>; clock-names = "ref_clk"; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi index a5a6bad1617628400c2e45b443df548c7a27fcb3..3e28f21eaac1063472d72fff0fa282f1eeb78e86 100644 --- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi @@ -454,6 +454,19 @@ }; &soc { + qcom,ntn_avb { + compatible = "qcom,ntn_avb"; + + ntn-rst-gpio = <&pm8994_gpios 13 0>; + + vdd-ntn-hsic-supply = <&pm8994_l25>; + vdd-ntn-pci-supply = <&pm8994_s4>; + vdd-ntn-io-supply = <&pm8994_s4>; + + qcom,ntn-rst-delay-msec = <100>; + qcom,ntn-rc-num = <1>; + }; + i2c@75ba000 { synaptics@20 { compatible = "synaptics,dsx"; @@ -712,22 +725,9 @@ }; qcom,msm-dai-tdm-tert-rx { - qcom,msm-cpudai-tdm-group-num-ports = <5>; - qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 - 36902 36904>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&tert_tdm_dout_active>; pinctrl-1 = <&tert_tdm_dout_sleep>; - dai_tert_tdm_rx_4: qcom,msm-dai-q6-tdm-tert-rx-4 { - compatible = "qcom,msm-dai-q6-tdm"; - qcom,msm-cpudai-tdm-dev-id = <36904>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; - qcom,msm-cpudai-tdm-data-align = <0>; - }; }; qcom,msm-dai-tdm-quat-rx { @@ -820,14 +820,14 @@ status = "okay"; }; - gpio@cc00 { /* GPIO 13 - HPH_EN0 */ - qcom,mode = <1>; - qcom,output-type = <0>; + gpio@cc00 { /* GPIO 13 - NTN_RST */ + qcom,mode = <1>; /* DIGITAL OUT */ + qcom,output-type = <0>; /* CMOS logic */ qcom,pull = <5>; - qcom,vin-sel = <2>; + qcom,vin-sel = <2>; /* 1.8 */ qcom,out-strength = <1>; - qcom,src-sel = <2>; - qcom,master-en = <1>; + qcom,src-sel = <0>; /* GPIO */ + qcom,master-en = <1>; /* Enable GPIO */ status = "okay"; }; @@ -994,8 +994,21 @@ /delete-property/ vin-supply; }; +&pcie0 { + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; +}; + &pcie1 { + qcom,msi-gicm-addr = <0x09BD0040>; + qcom,msi-gicm-base = <0x240>; + /delete-property/ qcom,boot-option; + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; + /delete-property/ qcom,ep-wakeirq; }; &pcie2 { @@ -1003,6 +1016,10 @@ wake-gpio = <&tlmm 54 0>; /delete-property/ qcom,boot-option; + /delete-property/ qcom,l1-supported; + /delete-property/ qcom,l1ss-supported; + /delete-property/ qcom,aux-clk-sync; + /delete-property/ qcom,ep-wakeirq; }; &wsa881x_211 { @@ -1021,87 +1038,4 @@ /delete-property/ qcom,spkr-sd-n-gpio; }; -&hl7509_en_vreg { - status = "ok"; -}; -&hl7509_vreg { - status = "ok"; -}; - -&gfx_cpr { - vdd-supply = <&hl7509_vreg>; - qcom,cpr-step-quot-init-min = <20>; - qcom,cpr-step-quot-init-max = <26>; - qcom,voltage-step = <10000>; - /delete-property/ qcom,cpr-enable; -}; - -&gfx_vreg { - qcom,cpr-voltage-ceiling = - <600000 670000 670000 750000 830000 - 910000 960000 1020000>; - qcom,cpr-voltage-floor = - <600000 600000 600000 600000 600000 - 600000 600000 600000>; -}; - -&pm8994_l3 { - regulator-min-microvolt = <875000>; - regulator-max-microvolt = <875000>; - qcom,init-voltage = <875000>; -}; - -&pm8994_l11 { - regulator-min-microvolt = <850000>; - regulator-max-microvolt = <850000>; - qcom,init-voltage = <850000>; -}; - -&pm8994_l17 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - qcom,init-voltage = <1800000>; -}; - -&pm8994_l23 { - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - qcom,init-voltage = <1100000>; -}; - -&pm8994_l27 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <800000>; - qcom,init-voltage = <800000>; -}; - -&pm8994_l29 { - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; - qcom,init-voltage = <2500000>; -}; - -&rpm_bus { - rpm-regulator-ldoa26 { - /delete-node/ pm8994_l26_corner; - /delete-node/ pm8994_l26_floor_corner; - - pm8994_l26: regulator-l26 { - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - qcom,init-voltage = <1100000>; - status = "okay"; - }; - }; - - rpm-regulator-ldoa31 { - status = "okay"; - pm8994_l31: regulator-l31 { - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - qcom,init-voltage = <1100000>; - status = "okay"; - }; - }; -}; diff --git a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi index 215608959dc56dad6c4a9eac9511606e8ddf098c..27f692bb14af9f54e73bb1f2665ecb5aeb1aa570 100644 --- a/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-gpu.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -89,6 +89,13 @@ coresight-child-list = <&funnel_in0>; coresight-child-ports = <4>; + /* DRM settings */ + qcom,gpmu-tsens = <0x00060007>; + qcom,lm-max-power = <5448>; + qcom,gpmu-firmware = "a530v3_gpmu.fw2"; + qcom,gpmu-version = <1 0>; + qcom,zap-shader = "a530_zap"; + clocks = <&clock_gpu clk_gpu_gx_gfx3d_clk>, <&clock_gpu clk_gpu_ahb_clk>, <&clock_gpu clk_gpu_gx_rbbmtimer_clk>, diff --git a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi index c5b6e7d0a3dce8a2dbf7ad98b50863cc48c44869..53c3c7e727bccd7bcb54dcab0a98af58b2b4c6c7 100644 --- a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi @@ -595,22 +595,9 @@ }; qcom,msm-dai-tdm-tert-rx { - qcom,msm-cpudai-tdm-group-num-ports = <5>; - qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 - 36902 36904>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&tert_tdm_dout_active>; pinctrl-1 = <&tert_tdm_dout_sleep>; - dai_tert_tdm_rx_4: qcom,msm-dai-q6-tdm-tert-rx-4 { - compatible = "qcom,msm-dai-q6-tdm"; - qcom,msm-cpudai-tdm-dev-id = <36904>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; - qcom,msm-cpudai-tdm-data-align = <0>; - }; }; qcom,msm-dai-tdm-quat-rx { diff --git a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi index 0b7be6a056f37fadd3326c8bce2860730b29e554..ff128acb376a1f896387ccfca21c7a7d60d4de81 100644 --- a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi @@ -20,6 +20,20 @@ interrupt-controller; #interrupt-cells = <2>; + /* pin governing mux between QSPI and modem on auto boards */ + modem_mux: mdm_mux { + mux { + pins = "gpio121"; + function = "gpio"; + }; + + config { + pins = "gpio121"; + drive-strength = <2>; + bias-pull-up; + output-high; + }; + }; /* add pingrp for adv7533 */ pmx_adv7533: pmx_adv7533 { adv7533_0_int_active: adv7533_0_int_active { diff --git a/arch/arm/boot/dts/qcom/msm8996-pm.dtsi b/arch/arm/boot/dts/qcom/msm8996-pm.dtsi index c09b18b51656c1f983d830b27115db986fedb01d..74c964bc466dce708125e79e6ab1b7e674f2403d 100644 --- a/arch/arm/boot/dts/qcom/msm8996-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-pm.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -161,7 +161,7 @@ qcom,psci-cpu-mode = <4>; qcom,latency-us = <80>; qcom,ss-power = <196>; - qcom,energy-overhead = <45300>; + qcom,energy-overhead = <62248>; qcom,time-overhead = <210>; qcom,reset-level = ; @@ -250,7 +250,7 @@ qcom,psci-cpu-mode = <4>; qcom,latency-us = <80>; qcom,ss-power = <196>; - qcom,energy-overhead = <45300>; + qcom,energy-overhead = <62248>; qcom,time-overhead = <210>; qcom,reset-level = ; @@ -276,6 +276,8 @@ qcom,gic-map = <2 216>, /* tsens_upper_lower_int */ <79 379>, /* qusb2phy_dmse_hv_prim */ <80 384>, /* qusb2phy_dmse_hv_sec */ + <81 379>, /* qusb2phy_dpse_hv_prim */ + <82 384>, /* qusb2phy_dpse_hv_sec */ <52 275>, /* qmp_usb3_lfps_rxterm_irq */ <87 358>, /* ee0_krait_hlos_spmi_periph_irq */ <0xff 16>, /* APCj_qgicdrCpu0HwFaultIrptReq */ @@ -314,6 +316,7 @@ <0xff 94>, /* osmmu_CIrpt[0] */ <0xff 97>, /* iommu_nonsecure_irq */ <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */ + <0xff 101>, /* camss_jpeg_mmu_cirpt */ <0xff 102>, /* osmmu_CIrpt[1] */ <0xff 105>, /* iommu_pmon_nonsecure_irq */ <0xff 108>, /* osmmu_PMIrpt */ @@ -327,6 +330,7 @@ <0xff 132>, /* blsp1_qup_irq(5) */ <0xff 133>, /* blsp2_qup_irq(0) */ <0xff 134>, /* blsp2_qup_irq(1) */ + <0xff 135>, /* blsp2_qup_irq(2) */ <0xff 138>, /* blsp2_qup_irq(5) */ <0xff 140>, /* blsp1_uart_irq(1) */ <0xff 146>, /* blsp2_uart_irq(1) */ @@ -337,6 +341,8 @@ <0xff 165>, /* usb30_hs_phy_irq */ <0xff 166>, /* sdc1_pwr_cmd_irq */ <0xff 170>, /* sdcc_pwr_cmd_irq */ + <0xff 171>, /* usb20_hs_phy_irq */ + <0xff 172>, /* usb20_power_event_irq */ <0xff 173>, /* sdc1_irq[0] */ <0xff 174>, /* o_wcss_apss_smd_med */ <0xff 175>, /* o_wcss_apss_smd_low */ @@ -368,6 +374,7 @@ <0xff 208>, <0xff 210>, <0xff 211>, /* usb_dwc3_otg */ + <0xff 212>, /* usb30_power_event_irq */ <0xff 215>, /* o_bimc_intr(0) */ <0xff 224>, /* spdm_realtime_irq[1] */ <0xff 238>, /* crypto_bam_irq[0] */ @@ -386,6 +393,7 @@ <0xff 295>, /* camss_cpp_mmu_cirpt[0] */ <0xff 296>, /* camss_cpp_mmu_pmirpt */ <0xff 297>, /* ufs_intrq */ + <0xff 298>, /* camss_cpp_mmu_cirpt */ <0xff 302>, /* qdss_etrbytecnt_irq */ <0xff 310>, /* pcie20_1_int_pls_err */ <0xff 311>, /* pcie20_1_int_aer_legacy */ @@ -400,6 +408,7 @@ <0xff 330>, /* camss_irq4 */ <0xff 331>, /* camss_irq5 */ <0xff 332>, /* sps */ + <0xff 341>, /* camss_irq6 */ <0xff 346>, /* camss_irq8 */ <0xff 347>, /* camss_irq9 */ <0xff 352>, /* mdss_mmu_cirpt[0] */ diff --git a/arch/arm/boot/dts/qcom/msm8996-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8996-regulator.dtsi index c70003a0a6ddf06949cd5129586841b4db155596..b86542a174da955ebaa05cbe9645cac973209d96 100644 --- a/arch/arm/boot/dts/qcom/msm8996-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-regulator.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1950,4 +1950,21 @@ regulator-ramp-delay = <500>; status = "disabled"; }; + + ncp6335d_vreg: ncp6335d-regulator@68 { + compatible = "onnn,ncp6335d-regulator"; + reg = <0x68>; + vin-supply = <&hl7509_en_vreg>; + onnn,vsel = <0>; + onnn,slew-ns = <2666>; + onnn,step-size = <6250>; + onnn,min-slew-ns = <333>; + onnn,max-slew-ns = <2666>; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1143750>; + onnn,min-setpoint = <600000>; + onnn,discharge-enable; + onnn,restore-reg; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi b/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi index 1396f27159dfb52cbe0aa55d6126c6b609080196..061301f1c4796837f0700da7a1dd85762910b0ba 100644 --- a/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi @@ -10,21 +10,7 @@ * GNU General Public License for more details. */ -#include "dsi-panel-toshiba-720p-video.dtsi" -#include "dsi-panel-sharp-dualmipi-wqxga-video.dtsi" -#include "dsi-panel-nt35597-dualmipi-wqxga-video.dtsi" -#include "dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi" -#include "dsi-panel-nt35597-dsc-wqxga-video.dtsi" -#include "dsi-panel-jdi-dualmipi-video.dtsi" -#include "dsi-panel-jdi-dualmipi-cmd.dtsi" -#include "dsi-panel-jdi-4k-dualmipi-video-nofbc.dtsi" -#include "dsi-panel-sim-video.dtsi" -#include "dsi-panel-sim-dualmipi-video.dtsi" -#include "dsi-panel-sim-cmd.dtsi" -#include "dsi-panel-sim-dualmipi-cmd.dtsi" -#include "dsi-panel-nt35597-dsc-wqxga-cmd.dtsi" -#include "dsi-panel-hx8379a-truly-fwvga-video.dtsi" -#include "dsi-panel-r69007-dualdsi-wqxga-cmd.dtsi" +#include "msm8996-mdss-panels.dtsi" #include "dsi-panel-jdi-1080p-video.dtsi" #include "dsi-panel-sharp-1080p-cmd.dtsi" @@ -122,9 +108,9 @@ qcom,dsi-panel = <&dsi_dual_sharp_video>; vddio-supply = <&pm8994_l14>; - lab-supply = <&lab_regulator>; - ibb-supply = <&ibb_regulator>; - qcom,dsi-display-active; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; + /delete-property/ qcom,dsi-display-active; }; single_dsi_sim_vid: qcom,dsi-display@1 { @@ -145,8 +131,8 @@ qcom,dsi-panel = <&dsi_sim_vid>; vddio-supply = <&pm8994_l14>; - lab-supply = <&lab_regulator>; - ibb-supply = <&ibb_regulator>; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; }; dsi_toshiba_720p_vid: qcom,dsi-display@2 { @@ -207,8 +193,8 @@ qcom,dsi-panel = <&dsi_sharp_1080_cmd>; vddio-supply = <&pm8994_l14>; vdd-supply = <&pm8994_l19>; - lab-supply = <&lab_regulator>; - ibb-supply = <&ibb_regulator>; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; }; sde_wb: qcom,wb-display@0 { @@ -236,8 +222,8 @@ qcom,dsi-panel = <&dsi_dual_nt35597_cmd>; vddio-supply = <&pm8994_l14>; - lab-supply = <&lab_regulator>; - ibb-supply = <&ibb_regulator>; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; }; dsi_dual_nt35597_video_1: qcom,dsi-display@6 { @@ -258,14 +244,61 @@ qcom,dsi-panel = <&dsi_dual_nt35597_video>; vddio-supply = <&pm8994_l14>; - lab-supply = <&lab_regulator>; - ibb-supply = <&ibb_regulator>; + /delete-property/ lab-supply; + /delete-property/ ibb-supply; + }; + + dsi_adv_7533_1: qcom,dsi-display@7 { + compatible = "qcom,dsi-display"; + label = "dsi_adv_7533_1"; + qcom,display-type = "secondary"; + + qcom,dsi-ctrl = <&mdss_dsi0>; + qcom,dsi-phy = <&mdss_dsi_phy0>; + clocks = <&clock_mmss clk_ext_byte0_clk_src>, + <&clock_mmss clk_ext_pclk0_clk_src>; + clock-names = "src_byte_clk", "src_pixel_clk"; + + qcom,dsi-panel = <&dsi_adv7533_720p>; + vddio-supply = <&pm8994_l14>; + qcom,bridge-index = <0>; + }; + + dsi_adv_7533_2: qcom,dsi-display@8 { + compatible = "qcom,dsi-display"; + label = "dsi_adv_7533_2"; + qcom,display-type = "tertiary"; + + qcom,dsi-ctrl = <&mdss_dsi1>; + qcom,dsi-phy = <&mdss_dsi_phy1>; + clocks = <&clock_mmss clk_ext_byte1_clk_src>, + <&clock_mmss clk_ext_pclk1_clk_src>; + clock-names = "src_byte_clk", "src_pixel_clk"; + + qcom,dsi-panel = <&dsi_adv7533_720p>; + vddio-supply = <&pm8994_l14>; + qcom,bridge-index = <1>; + }; + + msm_ext_disp: qcom,msm_ext_disp { + compatible = "qcom,msm-ext-disp"; + + ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx { + compatible = "qcom,msm-ext-disp-audio-codec-rx"; + qcom,msm_ext_disp = <&msm_ext_disp>; + }; + }; + + sde_hdmi: qcom,hdmi-display { + compatible = "qcom,hdmi-display"; + label = "sde_hdmi"; + qcom,display-type = "primary"; + qcom,msm_ext_disp = <&msm_ext_disp>; }; }; &mdss_mdp { - connectors = <&dsi_dual_sharp_video_1 - &sde_wb>; + connectors = <&mdss_hdmi &sde_hdmi &dsi_adv_7533_1 &dsi_adv_7533_2>; }; &dsi_dual_sharp_video { diff --git a/arch/arm/boot/dts/qcom/msm8996-sde.dtsi b/arch/arm/boot/dts/qcom/msm8996-sde.dtsi index 8aebac3b0e22d111b68fd1ef0b9e49d18a9cab2a..f0fa5dcb22240363df4a93ff0a3ad16fc99132c6 100644 --- a/arch/arm/boot/dts/qcom/msm8996-sde.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-sde.dtsi @@ -51,6 +51,8 @@ #interrupt-cells = <1>; iommus = <&mdp_smmu 0>; + gpus = <&msm_gpu>; + /* hw blocks */ qcom,sde-off = <0x1000>; qcom,sde-ctl-off = <0x2000 0x2200 0x2400 @@ -183,21 +185,6 @@ iommus = <&mdp_smmu 0>; }; - smmu_rot_unsec: qcom,smmu_rot_unsec_cb { - compatible = "qcom,smmu_rot_unsec"; - iommus = <&rot_smmu 0>; - }; - - smmu_mdp_sec: qcom,smmu_mdp_sec_cb { - compatible = "qcom,smmu_mdp_sec"; - iommus = <&mdp_smmu 1>; - }; - - smmu_rot_sec: qcom,smmu_rot_sec_cb { - compatible = "qcom,smmu_rot_sec"; - iommus = <&rot_smmu 1>; - }; - /* data and reg bus scale settings */ qcom,sde-data-bus { qcom,msm-bus,name = "mdss_sde"; diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts new file mode 100644 index 0000000000000000000000000000000000000000..68956d71b74dec5033a9098f1ba05328dcdc1027 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts @@ -0,0 +1,83 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "msm8996-v3.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" +#include "msm8996v3-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996 v3 AUTO ADP"; + compatible = "qcom,msm8996-adp", "qcom,msm8996", "qcom,adp"; + qcom,msm-id = <310 0x30001>; + qcom,board-id = <0x02010019 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <122 0>; + spi-max-frequency = <5000000>; + }; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts index 1c92a9a1a8c10805f96d1907510ce3ec11caeca4..8ca2b30b37798d63998d5bce55bbc1d8931886e7 100644 --- a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts @@ -15,6 +15,7 @@ #include "msm8996-v3.dtsi" #include "msm8996-pm8994.dtsi" #include "msm8996-auto-cdp.dtsi" +#include "msm8996v3-auto.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8996 v3 AUTO CDP"; @@ -23,6 +24,19 @@ qcom,board-id = <0x03010001 0>; }; +&soc { + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + &spi_9 { status = "ok"; can-controller@0 { diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp-lite.dts b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp-lite.dts new file mode 100644 index 0000000000000000000000000000000000000000..eb8591b4ded7fedb4fd8fda5df524fdf39cf3a22 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp-lite.dts @@ -0,0 +1,27 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8996-v3.dtsi" +#include "msm8996-pm8994-pm8004.dtsi" +#include "msm8996-agave-adp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996 v3 + PM8004 ADP LITE"; + compatible = "qcom,msm8996-adp", "qcom,msm8996", "qcom,adp"; + qcom,board-id = <0x03010019 0>; +}; + +&spi_9 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index c73a2ff23369030b6e272f1594db1bba1d43cdea..ee069f5d8bdfb308913876d22953b0d55ef610a3 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -21,6 +21,10 @@ qcom,pmic-id = <0x20009 0x2000A 0x0 0x0>; interrupt-parent = <&intc>; + chosen { + bootargs = "fpsimd.fpsimd_settings=1 app_setting.use_app_setting=1 app_setting.use_32bit_app_setting=1"; + }; + aliases { sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ sdhc2 = &sdhc_2; /* SDC2 SD card slot */ @@ -298,13 +302,23 @@ intc: interrupt-controller@09bc0000 { compatible = "arm,gic-v3"; + reg = <0x9bc0000 0x10000>, /* GICD */ + <0x9c00000 0x100000>; /* GICR * 4 */ #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + ranges; interrupt-controller; #redistributor-regions = <1>; redistributor-stride = <0x0 0x40000>; - reg = <0x09bc0000 0x10000>, /* GICD */ - <0x09c00000 0x100000>; /* GICR * 4 */ + interrupts = <1 9 4>; + + gic-its@09BE0000 { + compatible = "arm,gic-v3-its"; + msi-contoller; + reg = <0x9be0000 0x20000>; + }; }; timer { @@ -1284,50 +1298,50 @@ 39 40 41 42 43>; #interrupt-cells = <1>; interrupt-map-mask = <0x0 0x0 0x0 0xffffffff>; - interrupt-map = <0x0 0x0 0x0 0 &intc 0 405 0 - 0x0 0x0 0x0 1 &intc 0 244 0 - 0x0 0x0 0x0 2 &intc 0 245 0 - 0x0 0x0 0x0 3 &intc 0 247 0 - 0x0 0x0 0x0 4 &intc 0 248 0 - 0x0 0x0 0x0 5 &intc 0 249 0 - 0x0 0x0 0x0 6 &intc 0 250 0 - 0x0 0x0 0x0 7 &intc 0 251 0 - 0x0 0x0 0x0 8 &intc 0 252 0 - 0x0 0x0 0x0 9 &intc 0 253 0 - 0x0 0x0 0x0 10 &intc 0 254 0 - 0x0 0x0 0x0 11 &intc 0 255 0 - 0x0 0x0 0x0 12 &intc 0 512 0 - 0x0 0x0 0x0 13 &intc 0 513 0 - 0x0 0x0 0x0 14 &intc 0 514 0 - 0x0 0x0 0x0 15 &intc 0 515 0 - 0x0 0x0 0x0 16 &intc 0 516 0 - 0x0 0x0 0x0 17 &intc 0 517 0 - 0x0 0x0 0x0 18 &intc 0 518 0 - 0x0 0x0 0x0 19 &intc 0 519 0 - 0x0 0x0 0x0 20 &intc 0 520 0 - 0x0 0x0 0x0 21 &intc 0 521 0 - 0x0 0x0 0x0 22 &intc 0 522 0 - 0x0 0x0 0x0 23 &intc 0 523 0 - 0x0 0x0 0x0 24 &intc 0 524 0 - 0x0 0x0 0x0 25 &intc 0 525 0 - 0x0 0x0 0x0 26 &intc 0 526 0 - 0x0 0x0 0x0 27 &intc 0 527 0 - 0x0 0x0 0x0 28 &intc 0 528 0 - 0x0 0x0 0x0 29 &intc 0 529 0 - 0x0 0x0 0x0 30 &intc 0 530 0 - 0x0 0x0 0x0 31 &intc 0 531 0 - 0x0 0x0 0x0 32 &intc 0 532 0 - 0x0 0x0 0x0 33 &intc 0 533 0 - 0x0 0x0 0x0 34 &intc 0 534 0 - 0x0 0x0 0x0 35 &intc 0 535 0 - 0x0 0x0 0x0 36 &intc 0 536 0 - 0x0 0x0 0x0 37 &intc 0 537 0 - 0x0 0x0 0x0 38 &intc 0 538 0 - 0x0 0x0 0x0 39 &intc 0 539 0 - 0x0 0x0 0x0 40 &intc 0 540 0 - 0x0 0x0 0x0 41 &intc 0 541 0 - 0x0 0x0 0x0 42 &intc 0 542 0 - 0x0 0x0 0x0 43 &intc 0 543 0>; + interrupt-map = <0x0 0x0 0x0 0 &intc 0 0 405 0 + 0x0 0x0 0x0 1 &intc 0 0 244 0 + 0x0 0x0 0x0 2 &intc 0 0 245 0 + 0x0 0x0 0x0 3 &intc 0 0 247 0 + 0x0 0x0 0x0 4 &intc 0 0 248 0 + 0x0 0x0 0x0 5 &intc 0 0 249 0 + 0x0 0x0 0x0 6 &intc 0 0 250 0 + 0x0 0x0 0x0 7 &intc 0 0 251 0 + 0x0 0x0 0x0 8 &intc 0 0 252 0 + 0x0 0x0 0x0 9 &intc 0 0 253 0 + 0x0 0x0 0x0 10 &intc 0 0 254 0 + 0x0 0x0 0x0 11 &intc 0 0 255 0 + 0x0 0x0 0x0 12 &intc 0 0 512 0 + 0x0 0x0 0x0 13 &intc 0 0 513 0 + 0x0 0x0 0x0 14 &intc 0 0 514 0 + 0x0 0x0 0x0 15 &intc 0 0 515 0 + 0x0 0x0 0x0 16 &intc 0 0 516 0 + 0x0 0x0 0x0 17 &intc 0 0 517 0 + 0x0 0x0 0x0 18 &intc 0 0 518 0 + 0x0 0x0 0x0 19 &intc 0 0 519 0 + 0x0 0x0 0x0 20 &intc 0 0 520 0 + 0x0 0x0 0x0 21 &intc 0 0 521 0 + 0x0 0x0 0x0 22 &intc 0 0 522 0 + 0x0 0x0 0x0 23 &intc 0 0 523 0 + 0x0 0x0 0x0 24 &intc 0 0 524 0 + 0x0 0x0 0x0 25 &intc 0 0 525 0 + 0x0 0x0 0x0 26 &intc 0 0 526 0 + 0x0 0x0 0x0 27 &intc 0 0 527 0 + 0x0 0x0 0x0 28 &intc 0 0 528 0 + 0x0 0x0 0x0 29 &intc 0 0 529 0 + 0x0 0x0 0x0 30 &intc 0 0 530 0 + 0x0 0x0 0x0 31 &intc 0 0 531 0 + 0x0 0x0 0x0 32 &intc 0 0 532 0 + 0x0 0x0 0x0 33 &intc 0 0 533 0 + 0x0 0x0 0x0 34 &intc 0 0 534 0 + 0x0 0x0 0x0 35 &intc 0 0 535 0 + 0x0 0x0 0x0 36 &intc 0 0 536 0 + 0x0 0x0 0x0 37 &intc 0 0 537 0 + 0x0 0x0 0x0 38 &intc 0 0 538 0 + 0x0 0x0 0x0 39 &intc 0 0 539 0 + 0x0 0x0 0x0 40 &intc 0 0 540 0 + 0x0 0x0 0x0 41 &intc 0 0 541 0 + 0x0 0x0 0x0 42 &intc 0 0 542 0 + 0x0 0x0 0x0 43 &intc 0 0 543 0>; interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", "int_pls_pme", "int_pme_legacy", "int_pls_err", @@ -1440,50 +1454,50 @@ 39 40 41 42 43>; #interrupt-cells = <1>; interrupt-map-mask = <0x0 0x0 0x0 0xffffffff>; - interrupt-map = <0x0 0x0 0x0 0 &intc 0 413 0 - 0x0 0x0 0x0 1 &intc 0 272 0 - 0x0 0x0 0x0 2 &intc 0 273 0 - 0x0 0x0 0x0 3 &intc 0 274 0 - 0x0 0x0 0x0 4 &intc 0 275 0 - 0x0 0x0 0x0 5 &intc 0 276 0 - 0x0 0x0 0x0 6 &intc 0 277 0 - 0x0 0x0 0x0 7 &intc 0 278 0 - 0x0 0x0 0x0 8 &intc 0 279 0 - 0x0 0x0 0x0 9 &intc 0 280 0 - 0x0 0x0 0x0 10 &intc 0 281 0 - 0x0 0x0 0x0 11 &intc 0 282 0 - 0x0 0x0 0x0 12 &intc 0 544 0 - 0x0 0x0 0x0 13 &intc 0 545 0 - 0x0 0x0 0x0 14 &intc 0 546 0 - 0x0 0x0 0x0 15 &intc 0 547 0 - 0x0 0x0 0x0 16 &intc 0 548 0 - 0x0 0x0 0x0 17 &intc 0 549 0 - 0x0 0x0 0x0 18 &intc 0 550 0 - 0x0 0x0 0x0 19 &intc 0 551 0 - 0x0 0x0 0x0 20 &intc 0 552 0 - 0x0 0x0 0x0 21 &intc 0 553 0 - 0x0 0x0 0x0 22 &intc 0 554 0 - 0x0 0x0 0x0 23 &intc 0 555 0 - 0x0 0x0 0x0 24 &intc 0 556 0 - 0x0 0x0 0x0 25 &intc 0 557 0 - 0x0 0x0 0x0 26 &intc 0 558 0 - 0x0 0x0 0x0 27 &intc 0 559 0 - 0x0 0x0 0x0 28 &intc 0 560 0 - 0x0 0x0 0x0 29 &intc 0 561 0 - 0x0 0x0 0x0 30 &intc 0 562 0 - 0x0 0x0 0x0 31 &intc 0 563 0 - 0x0 0x0 0x0 32 &intc 0 564 0 - 0x0 0x0 0x0 33 &intc 0 565 0 - 0x0 0x0 0x0 34 &intc 0 566 0 - 0x0 0x0 0x0 35 &intc 0 567 0 - 0x0 0x0 0x0 36 &intc 0 568 0 - 0x0 0x0 0x0 37 &intc 0 569 0 - 0x0 0x0 0x0 38 &intc 0 570 0 - 0x0 0x0 0x0 39 &intc 0 571 0 - 0x0 0x0 0x0 40 &intc 0 572 0 - 0x0 0x0 0x0 41 &intc 0 573 0 - 0x0 0x0 0x0 42 &intc 0 574 0 - 0x0 0x0 0x0 43 &intc 0 575 0>; + interrupt-map = <0x0 0x0 0x0 0 &intc 0 0 413 0 + 0x0 0x0 0x0 1 &intc 0 0 272 0 + 0x0 0x0 0x0 2 &intc 0 0 273 0 + 0x0 0x0 0x0 3 &intc 0 0 274 0 + 0x0 0x0 0x0 4 &intc 0 0 275 0 + 0x0 0x0 0x0 5 &intc 0 0 276 0 + 0x0 0x0 0x0 6 &intc 0 0 277 0 + 0x0 0x0 0x0 7 &intc 0 0 278 0 + 0x0 0x0 0x0 8 &intc 0 0 279 0 + 0x0 0x0 0x0 9 &intc 0 0 280 0 + 0x0 0x0 0x0 10 &intc 0 0 281 0 + 0x0 0x0 0x0 11 &intc 0 0 282 0 + 0x0 0x0 0x0 12 &intc 0 0 544 0 + 0x0 0x0 0x0 13 &intc 0 0 545 0 + 0x0 0x0 0x0 14 &intc 0 0 546 0 + 0x0 0x0 0x0 15 &intc 0 0 547 0 + 0x0 0x0 0x0 16 &intc 0 0 548 0 + 0x0 0x0 0x0 17 &intc 0 0 549 0 + 0x0 0x0 0x0 18 &intc 0 0 550 0 + 0x0 0x0 0x0 19 &intc 0 0 551 0 + 0x0 0x0 0x0 20 &intc 0 0 552 0 + 0x0 0x0 0x0 21 &intc 0 0 553 0 + 0x0 0x0 0x0 22 &intc 0 0 554 0 + 0x0 0x0 0x0 23 &intc 0 0 555 0 + 0x0 0x0 0x0 24 &intc 0 0 556 0 + 0x0 0x0 0x0 25 &intc 0 0 557 0 + 0x0 0x0 0x0 26 &intc 0 0 558 0 + 0x0 0x0 0x0 27 &intc 0 0 559 0 + 0x0 0x0 0x0 28 &intc 0 0 560 0 + 0x0 0x0 0x0 29 &intc 0 0 561 0 + 0x0 0x0 0x0 30 &intc 0 0 562 0 + 0x0 0x0 0x0 31 &intc 0 0 563 0 + 0x0 0x0 0x0 32 &intc 0 0 564 0 + 0x0 0x0 0x0 33 &intc 0 0 565 0 + 0x0 0x0 0x0 34 &intc 0 0 566 0 + 0x0 0x0 0x0 35 &intc 0 0 567 0 + 0x0 0x0 0x0 36 &intc 0 0 568 0 + 0x0 0x0 0x0 37 &intc 0 0 569 0 + 0x0 0x0 0x0 38 &intc 0 0 570 0 + 0x0 0x0 0x0 39 &intc 0 0 571 0 + 0x0 0x0 0x0 40 &intc 0 0 572 0 + 0x0 0x0 0x0 41 &intc 0 0 573 0 + 0x0 0x0 0x0 42 &intc 0 0 574 0 + 0x0 0x0 0x0 43 &intc 0 0 575 0>; interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", "int_pls_pme", "int_pme_legacy", "int_pls_err", @@ -1592,50 +1606,50 @@ 39 40 41 42 43>; #interrupt-cells = <1>; interrupt-map-mask = <0x0 0x0 0x0 0xffffffff>; - interrupt-map = <0x0 0x0 0x0 0 &intc 0 421 0 - 0x0 0x0 0x0 1 &intc 0 142 0 - 0x0 0x0 0x0 2 &intc 0 143 0 - 0x0 0x0 0x0 3 &intc 0 144 0 - 0x0 0x0 0x0 4 &intc 0 145 0 - 0x0 0x0 0x0 5 &intc 0 146 0 - 0x0 0x0 0x0 6 &intc 0 147 0 - 0x0 0x0 0x0 7 &intc 0 148 0 - 0x0 0x0 0x0 8 &intc 0 149 0 - 0x0 0x0 0x0 9 &intc 0 260 0 - 0x0 0x0 0x0 10 &intc 0 261 0 - 0x0 0x0 0x0 11 &intc 0 262 0 - 0x0 0x0 0x0 12 &intc 0 576 0 - 0x0 0x0 0x0 13 &intc 0 577 0 - 0x0 0x0 0x0 14 &intc 0 578 0 - 0x0 0x0 0x0 15 &intc 0 579 0 - 0x0 0x0 0x0 16 &intc 0 580 0 - 0x0 0x0 0x0 17 &intc 0 581 0 - 0x0 0x0 0x0 18 &intc 0 582 0 - 0x0 0x0 0x0 19 &intc 0 583 0 - 0x0 0x0 0x0 20 &intc 0 584 0 - 0x0 0x0 0x0 21 &intc 0 585 0 - 0x0 0x0 0x0 22 &intc 0 586 0 - 0x0 0x0 0x0 23 &intc 0 587 0 - 0x0 0x0 0x0 24 &intc 0 588 0 - 0x0 0x0 0x0 25 &intc 0 589 0 - 0x0 0x0 0x0 26 &intc 0 590 0 - 0x0 0x0 0x0 27 &intc 0 591 0 - 0x0 0x0 0x0 28 &intc 0 592 0 - 0x0 0x0 0x0 29 &intc 0 593 0 - 0x0 0x0 0x0 30 &intc 0 594 0 - 0x0 0x0 0x0 31 &intc 0 595 0 - 0x0 0x0 0x0 32 &intc 0 596 0 - 0x0 0x0 0x0 33 &intc 0 597 0 - 0x0 0x0 0x0 34 &intc 0 598 0 - 0x0 0x0 0x0 35 &intc 0 599 0 - 0x0 0x0 0x0 36 &intc 0 600 0 - 0x0 0x0 0x0 37 &intc 0 601 0 - 0x0 0x0 0x0 38 &intc 0 602 0 - 0x0 0x0 0x0 39 &intc 0 603 0 - 0x0 0x0 0x0 40 &intc 0 604 0 - 0x0 0x0 0x0 41 &intc 0 605 0 - 0x0 0x0 0x0 42 &intc 0 606 0 - 0x0 0x0 0x0 43 &intc 0 607 0>; + interrupt-map = <0x0 0x0 0x0 0 &intc 0 0 421 0 + 0x0 0x0 0x0 1 &intc 0 0 142 0 + 0x0 0x0 0x0 2 &intc 0 0 143 0 + 0x0 0x0 0x0 3 &intc 0 0 144 0 + 0x0 0x0 0x0 4 &intc 0 0 145 0 + 0x0 0x0 0x0 5 &intc 0 0 146 0 + 0x0 0x0 0x0 6 &intc 0 0 147 0 + 0x0 0x0 0x0 7 &intc 0 0 148 0 + 0x0 0x0 0x0 8 &intc 0 0 149 0 + 0x0 0x0 0x0 9 &intc 0 0 260 0 + 0x0 0x0 0x0 10 &intc 0 0 261 0 + 0x0 0x0 0x0 11 &intc 0 0 262 0 + 0x0 0x0 0x0 12 &intc 0 0 576 0 + 0x0 0x0 0x0 13 &intc 0 0 577 0 + 0x0 0x0 0x0 14 &intc 0 0 578 0 + 0x0 0x0 0x0 15 &intc 0 0 579 0 + 0x0 0x0 0x0 16 &intc 0 0 580 0 + 0x0 0x0 0x0 17 &intc 0 0 581 0 + 0x0 0x0 0x0 18 &intc 0 0 582 0 + 0x0 0x0 0x0 19 &intc 0 0 583 0 + 0x0 0x0 0x0 20 &intc 0 0 584 0 + 0x0 0x0 0x0 21 &intc 0 0 585 0 + 0x0 0x0 0x0 22 &intc 0 0 586 0 + 0x0 0x0 0x0 23 &intc 0 0 587 0 + 0x0 0x0 0x0 24 &intc 0 0 588 0 + 0x0 0x0 0x0 25 &intc 0 0 589 0 + 0x0 0x0 0x0 26 &intc 0 0 590 0 + 0x0 0x0 0x0 27 &intc 0 0 591 0 + 0x0 0x0 0x0 28 &intc 0 0 592 0 + 0x0 0x0 0x0 29 &intc 0 0 593 0 + 0x0 0x0 0x0 30 &intc 0 0 594 0 + 0x0 0x0 0x0 31 &intc 0 0 595 0 + 0x0 0x0 0x0 32 &intc 0 0 596 0 + 0x0 0x0 0x0 33 &intc 0 0 597 0 + 0x0 0x0 0x0 34 &intc 0 0 598 0 + 0x0 0x0 0x0 35 &intc 0 0 599 0 + 0x0 0x0 0x0 36 &intc 0 0 600 0 + 0x0 0x0 0x0 37 &intc 0 0 601 0 + 0x0 0x0 0x0 38 &intc 0 0 602 0 + 0x0 0x0 0x0 39 &intc 0 0 603 0 + 0x0 0x0 0x0 40 &intc 0 0 604 0 + 0x0 0x0 0x0 41 &intc 0 0 605 0 + 0x0 0x0 0x0 42 &intc 0 0 606 0 + 0x0 0x0 0x0 43 &intc 0 0 607 0>; interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d", "int_pls_pme", "int_pme_legacy", "int_pls_err", @@ -3342,48 +3356,34 @@ qcom,msm-cpudai-tdm-group-id = <37137>; qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36881 36883 36885 36887>; - qcom,msm-cpudai-tdm-clk-rate = <0>; + qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <0>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; dai_sec_tdm_tx_0: qcom,msm-dai-q6-tdm-sec-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36881>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_sec_tdm_tx_1: qcom,msm-dai-q6-tdm-sec-tx-1 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36883>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_sec_tdm_tx_2: qcom,msm-dai-q6-tdm-sec-tx-2 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36885>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_sec_tdm_tx_3: qcom,msm-dai-q6-tdm-sec-tx-3 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36887>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -3391,50 +3391,43 @@ qcom,msm-dai-tdm-tert-rx { compatible = "qcom,msm-dai-tdm"; qcom,msm-cpudai-tdm-group-id = <37152>; - qcom,msm-cpudai-tdm-group-num-ports = <4>; - qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 36902>; - qcom,msm-cpudai-tdm-clk-rate = <0>; + qcom,msm-cpudai-tdm-group-num-ports = <5>; + qcom,msm-cpudai-tdm-group-port-id = <36896 36898 36900 + 36902 36904>; + qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <0>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36896>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_rx_1: qcom,msm-dai-q6-tdm-tert-rx-1 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36898>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_rx_2: qcom,msm-dai-q6-tdm-tert-rx-2 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36900>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_rx_3: qcom,msm-dai-q6-tdm-tert-rx-3 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36902>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + + dai_tert_tdm_rx_4: qcom,msm-dai-q6-tdm-tert-rx-4 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36904>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -3444,48 +3437,34 @@ qcom,msm-cpudai-tdm-group-id = <37153>; qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36897 36899 36901 36903>; - qcom,msm-cpudai-tdm-clk-rate = <0>; + qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <0>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36897>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_tx_1: qcom,msm-dai-q6-tdm-tert-tx-1 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36899>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_tx_2: qcom,msm-dai-q6-tdm-tert-tx-2 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36901>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_tert_tdm_tx_3: qcom,msm-dai-q6-tdm-tert-tx-3 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36903>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -3495,48 +3474,34 @@ qcom,msm-cpudai-tdm-group-id = <37168>; qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36912 36914 36916 36918>; - qcom,msm-cpudai-tdm-clk-rate = <0>; + qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <0>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36912>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_rx_1: qcom,msm-dai-q6-tdm-quat-rx-1 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36914>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_rx_2: qcom,msm-dai-q6-tdm-quat-rx-2 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36916>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_rx_3: qcom,msm-dai-q6-tdm-quat-rx-3 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36918>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; @@ -3546,48 +3511,34 @@ qcom,msm-cpudai-tdm-group-id = <37169>; qcom,msm-cpudai-tdm-group-num-ports = <4>; qcom,msm-cpudai-tdm-group-port-id = <36913 36915 36917 36919>; - qcom,msm-cpudai-tdm-clk-rate = <0>; + qcom,msm-cpudai-tdm-clk-rate = <12288000>; + qcom,msm-cpudai-tdm-clk-internal = <0>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <0>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <0>; + qcom,msm-cpudai-tdm-data-delay = <0>; dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36913>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_tx_1: qcom,msm-dai-q6-tdm-quat-tx-1 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36915>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_tx_2: qcom,msm-dai-q6-tdm-quat-tx-2 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36917>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; dai_quat_tdm_tx_3: qcom,msm-dai-q6-tdm-quat-tx-3 { compatible = "qcom,msm-dai-q6-tdm"; qcom,msm-cpudai-tdm-dev-id = <36919>; - qcom,msm-cpudai-tdm-sync-mode = <1>; - qcom,msm-cpudai-tdm-sync-src = <0>; - qcom,msm-cpudai-tdm-data-out = <0>; - qcom,msm-cpudai-tdm-invert-sync = <0>; - qcom,msm-cpudai-tdm-data-delay = <0>; qcom,msm-cpudai-tdm-data-align = <0>; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp-lite.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp-lite.dts new file mode 100644 index 0000000000000000000000000000000000000000..668cb28443631b8032c0df2382ad3908f374ffc8 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp-lite.dts @@ -0,0 +1,86 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "msm8996pro.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996pro AUTO ADP LITE"; + compatible = "qcom,msm8996-adp", "qcom,msm8996", "qcom,adp"; + qcom,msm-id = <315 0x10000>; + qcom,board-id = <0x03010019 0>; +}; + +&spi_9 { + status = "disabled"; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; + + i2c@75b6000 { /* BLSP8 */ + /* ADV7533 HDMI Bridge Chip removed on ADP Lite */ + adv7533@3d { + status = "disabled"; + }; + adv7533@39 { + status = "disabled"; + }; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts new file mode 100644 index 0000000000000000000000000000000000000000..1ab8ee9cd538233ddd2f15ffdf8db9c3dc252294 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts @@ -0,0 +1,83 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include +#include "msm8996pro.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-agave-adp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996pro AUTO ADP"; + compatible = "qcom,msm8996-adp", "qcom,msm8996", "qcom,adp"; + qcom,msm-id = <315 0x10000>; + qcom,board-id = <0x02010019 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <122 0>; + spi-max-frequency = <5000000>; + }; +}; + +&soc { + qcom,msm-ssc-sensors { + status = "disabled"; + }; + + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&slim_msm { + status = "disabled"; +}; + +&pm8994_mpps { + mpp@a500 { /* MPP 6 */ + qcom,mode = <1>; /* Digital output */ + qcom,output-type = <0>; /* CMOS logic */ + qcom,vin-sel = <2>; /* S4 1.8V */ + qcom,src-sel = <0>; /* Constant */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "okay"; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off + &sdc2_cd_on_sbc>; +}; + +&i2c_7 { + silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/ + status = "disabled"; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts new file mode 100644 index 0000000000000000000000000000000000000000..e104be7c2742ff1998509baaba8c55e8939fa81c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts @@ -0,0 +1,49 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8996pro.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-auto-cdp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996pro AUTO CDP"; + compatible = "qcom,msm8996-cdp", "qcom,msm8996", "qcom,cdp"; + qcom,msm-id = <315 0x10000>; + qcom,board-id = <0x03010001 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <127 0>; + spi-max-frequency = <5000000>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + +&soc { + qcom,msm-thermal { + qcom,hotplug-temp = <115>; + qcom,hotplug-temp-hysteresis = <25>; + qcom,therm-reset-temp = <119>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi b/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..48d544e18889a7c12b0f31f7568ffd3ec5067dff --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi @@ -0,0 +1,461 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8996v3-auto.dtsi" + +&gfx_vreg { + qcom,cpr-fuse-combos = <24>; + qcom,cpr-speed-bins = <3>; + qcom,cpr-speed-bin-corners = <8 8 8>; + qcom,cpr-corners = <8>; + + qcom,cpr-corner-fmax-map = + <2 4 6 8>; + + qcom,cpr-voltage-ceiling = + <600000 670000 670000 750000 830000 910000 960000 + 1020000>; + + qcom,cpr-voltage-floor = + <600000 600000 600000 600000 600000 600000 600000 + 600000>; + + qcom,mem-acc-voltage = + <1 1 1 1 2 2 2 2>; + + qcom,corner-frequencies = + <0 133000000 214000000 315000000 401800000 510000000 560000000 + 624000000>; + + qcom,cpr-target-quotients = + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>, + <0 0 0 0 0 0 185 179 291 299 304 319 0 0 0 0>, + <0 0 0 0 0 0 287 273 425 426 443 453 0 0 0 0>, + <0 0 0 0 0 0 414 392 584 576 608 612 0 0 0 0>, + <0 0 0 0 0 0 459 431 684 644 692 679 0 0 0 0>, + <0 0 0 0 0 0 577 543 798 768 823 810 0 0 0 0>, + <0 0 0 0 0 0 669 629 886 864 924 911 0 0 0 0>, + <0 0 0 0 0 0 771 725 984 970 1036 1024 0 0 0 0>; + + qcom,cpr-ro-scaling-factor = + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>, + <0 0 0 0 0 0 2035 1917 1959 2131 2246 2253 0 0 0 0>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + <0 (-20000) (-20000) (-40000)>; + + qcom,cpr-closed-loop-voltage-adjustment = + <0 0 30000 10000 10000 45000 25000 25000>; + + qcom,cpr-floor-to-ceiling-max-range = + <0 70000 70000 75000 80000 90000 95000 100000>; + + qcom,cpr-fused-closed-loop-voltage-adjustment-map = + <0 2 2 2 2 0 0 4>; +}; + +&apcc_cpr { + /delete-property/ qcom,cpr-enable; +}; + +&apc0_pwrcl_vreg { + regulator-max-microvolt = <19>; + qcom,cpr-fuse-combos = <24>; + qcom,cpr-speed-bins = <3>; + qcom,cpr-speed-bin-corners = <19 19 19>; + qcom,cpr-corners = <19>; + + qcom,cpr-corner-fmax-map = + <3 6 9 14 19>; + + qcom,cpr-voltage-ceiling = + <670000 670000 670000 670000 670000 670000 745000 745000 + 745000 905000 905000 905000 905000 905000 1140000 1140000 + 1140000 1140000 1140000>; + + qcom,cpr-voltage-floor = + <470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000>; + + qcom,cpr-floor-to-ceiling-max-range = + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; + + qcom,corner-frequencies = + <307200000 384000000 460800000 537600000 614400000 + 691200000 768000000 844800000 902400000 979200000 + 1056000000 1132800000 1209600000 1286400000 1363200000 + 1440000000 1516800000 1593600000 1785600000>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + <0 0 0 0 0 >; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + <0 0 0 0 0 >; + + qcom,cpr-open-loop-voltage-adjustment = + <0 0 0 0 0 0 0 0 0 (-2000) (-4000) (-6000) (-8000) (-10000) + (-11000) (-12000) (-12000) (-13000) (-15000)>; + + qcom,cpr-open-loop-voltage-min-diff = + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; + + qcom,cpr-closed-loop-voltage-adjustment = + <0 0 0 0 0 0 0 0 0 (-2000) (-4000) (-6000) (-8000) (-10000) + (-11000) (-12000) (-12000) (-13000) (-15000)>; + + qcom,allow-aging-voltage-adjustment = <0>; + qcom,allow-aging-open-loop-voltage-adjustment = <0>; +}; + +&apc0_cbf_vreg { + qcom,cpr-fuse-combos = <24>; + qcom,cpr-speed-bins = <3>; + qcom,cpr-speed-bin-corners = <19 19 19>; + qcom,cpr-corners = <19>; + + qcom,cpr-corner-fmax-map = + <1 4 7 14 19>; + + qcom,cpr-voltage-ceiling = + <670000 670000 670000 670000 745000 745000 745000 905000 + 905000 905000 905000 905000 905000 905000 1140000 1140000 + 1140000 1140000 1140000>; + + qcom,cpr-voltage-floor = + <470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000>; + + qcom,cpr-floor-to-ceiling-max-range = + <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; + + qcom,corner-frequencies = + <192000000 307200000 384000000 441600000 537600000 + 614400000 691200000 768000000 844800000 902400000 + 979200000 1056000000 1132800000 1190400000 1286400000 + 1363200000 1440000000 1516800000 1593600000>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + <0 0 0 15000 0 >; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + <0 0 0 0 0 >; + + qcom,allow-aging-voltage-adjustment = <0>; + qcom,allow-aging-open-loop-voltage-adjustment = <0>; +}; + +&apc1_vreg { + qcom,cpr-fuse-combos = <24>; + qcom,cpr-speed-bins = <3>; + qcom,cpr-speed-bin-corners = <25 25 25>; + qcom,cpr-corners = <25>; + + qcom,cpr-corner-fmax-map = + <4 7 10 15 25>; + + qcom,cpr-voltage-ceiling = + <670000 670000 670000 670000 670000 670000 670000 745000 + 745000 745000 905000 905000 905000 905000 905000 1140000 + 1140000 1140000 1140000 1140000 1140000 1140000 1140000 1140000 + 1140000>; + + qcom,cpr-voltage-floor = + <470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000 470000 470000 470000 470000 470000 + 470000 470000 470000 470000 470000 470000 470000 470000 + 470000>; + + qcom,cpr-floor-to-ceiling-max-range = + <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>; + + qcom,corner-frequencies = + <307200000 384000000 460800000 537600000 614400000 + 691200000 748800000 825600000 902400000 979200000 + 1056000000 1132800000 1209600000 1286400000 1363200000 + 1440000000 1516800000 1593600000 1670400000 1747200000 + 1824000000 1900800000 1977600000 2054400000 2150400000>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + <0 0 0 0 0 >; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + <0 0 0 0 0 >; + + qcom,cpr-open-loop-voltage-adjustment = + <0 0 0 0 0 0 0 0 0 0 (-2000) (-4000) (-6000) (-8000) (-10000) + (-10000) (-11000) (-11000) (-12000) (-12000) (-13000) (-13000) + (-14000) (-14000) (-15000)>; + + qcom,cpr-open-loop-voltage-min-diff = + <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>; + + qcom,cpr-closed-loop-voltage-adjustment = + <0 0 0 0 0 0 0 0 0 0 (-2000) (-4000) (-6000) (-8000) (-10000) + (-10000) (-11000) (-11000) (-12000) (-12000) (-13000) (-13000) + (-14000) (-14000) (-15000)>; + + qcom,allow-aging-voltage-adjustment = <0>; + qcom,allow-aging-open-loop-voltage-adjustment = <0>; +}; + +&clock_cpu { + compatible = "qcom,cpu-clock-8996-auto"; + qcom,pwrcl-early-boot-freq = < 1286400000 >; + qcom,perfcl-early-boot-freq = < 1363200000 >; + + qcom,pwrcl-speedbin0-v0 = + < 0 0 >, + < 768000000 7 >, + < 844800000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >; + + qcom,pwrcl-speedbin1-v0 = + < 0 0 >, + < 768000000 7 >, + < 844800000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >; + + qcom,pwrcl-speedbin2-v0 = + < 0 0 >, + < 768000000 7 >, + < 844800000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >; + + qcom,perfcl-speedbin0-v0 = + < 0 0 >, + < 825600000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >, + < 1670400000 19 >, + < 1747200000 20 >, + < 1824000000 21 >, + < 1900800000 22 >, + < 1977600000 23 >, + < 2054400000 24 >; + + qcom,perfcl-speedbin1-v0 = + < 0 0 >, + < 825600000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >, + < 1670400000 19 >; + + qcom,perfcl-speedbin2-v0 = + < 0 0 >, + < 825600000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >; + + qcom,cbf-speedbin0-v0 = + < 0 0 >, + < 537600000 5 >, + < 614400000 6 >, + < 691200000 7 >, + < 768000000 8 >, + < 844800000 9 >, + < 902400000 10 >, + < 979200000 11 >, + < 1056000000 12 >, + < 1132800000 13 >, + < 1190400000 14 >, + < 1286400000 15 >, + < 1363200000 16 >, + < 1440000000 17 >, + < 1516800000 18 >, + < 1593600000 19 >; + + qcom,cbf-speedbin1-v0 = + < 0 0 >, + < 537600000 5 >, + < 614400000 6 >, + < 691200000 7 >, + < 768000000 8 >, + < 844800000 9 >, + < 902400000 10 >, + < 979200000 11 >, + < 1056000000 12 >, + < 1132800000 13 >, + < 1190400000 14 >, + < 1286400000 15 >, + < 1363200000 16 >, + < 1440000000 17 >, + < 1516800000 18 >, + < 1593600000 19 >; + + qcom,cbf-speedbin2-v0 = + < 0 0 >, + < 537600000 5 >, + < 614400000 6 >, + < 691200000 7 >, + < 768000000 8 >, + < 844800000 9 >, + < 902400000 10 >, + < 979200000 11 >, + < 1056000000 12 >, + < 1132800000 13 >, + < 1190400000 14 >; +}; + +&msm_cpufreq { + qcom,cpufreq-table-0 = + < 768000 >, + < 844800 >, + < 902400 >, + < 979200 >, + < 1056000 >, + < 1132800 >, + < 1209600 >, + < 1286400 >, + < 1363200 >, + < 1440000 >, + < 1516800 >, + < 1593600 >; + qcom,cpufreq-table-2 = + < 825600 >, + < 902400 >, + < 979200 >, + < 1056000 >, + < 1132800 >, + < 1209600 >, + < 1286400 >, + < 1363200 >, + < 1440000 >, + < 1516800 >, + < 1593600 >, + < 1670400 >, + < 1747200 >, + < 1824000 >, + < 1900800 >, + < 1977600 >, + < 2054400 >; +}; + +&m4m_cache { + freq-tbl-khz = + < 537600 >, + < 614400 >, + < 691200 >, + < 768000 >, + < 844800 >, + < 902400 >, + < 979200 >, + < 1056000 >, + < 1132800 >, + < 1190400 >, + < 1286400 >, + < 1363200 >, + < 1440000 >, + < 1516800 >, + < 1593600 >; +}; + +&devfreq_cpufreq { + mincpubw-cpufreq { + cpu-to-dev-map-0 = + < 1593600 1525 >; + cpu-to-dev-map-2 = + < 1977600 1525 >, + < 2054400 5195 >; + }; +}; + +&clock_gpu { + qcom,gfxfreq-speedbin0 = + < 0 0 0 >, + < 315000000 4 4 >, + < 401800000 5 5 >, + < 510000000 6 5 >, + < 560000000 7 7 >, + < 624000000 8 7 >; + + qcom,gfxfreq-mx-speedbin0 = + < 0 0 >, + < 315000000 4 >, + < 401800000 5 >, + < 510000000 5 >, + < 560000000 7 >, + < 624000000 7 >; + + qcom,gfxfreq-speedbin1 = + < 0 0 0 >, + < 315000000 4 4 >, + < 401800000 5 5 >, + < 510000000 6 5 >; + + qcom,gfxfreq-mx-speedbin1 = + < 0 0 >, + < 315000000 4 >, + < 401800000 5 >, + < 510000000 5 >; + + qcom,gfxfreq-speedbin2 = + < 0 0 0 >, + < 315000000 4 4 >; + + qcom,gfxfreq-mx-speedbin2 = + < 0 0 >, + < 315000000 4 >; +}; diff --git a/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts new file mode 100644 index 0000000000000000000000000000000000000000..06d040aa6bcb589424cf3b289f94ff38d8a57c2b --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts @@ -0,0 +1,42 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "msm8996pro-v1.1.dtsi" +#include "msm8996-pm8994.dtsi" +#include "msm8996-auto-cdp.dtsi" +#include "msm8996pro-auto.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996pro v1.1 AUTO CDP"; + compatible = "qcom,msm8996-cdp", "qcom,msm8996", "qcom,cdp"; + qcom,msm-id = <315 0x10001>; + qcom,board-id = <0x03010001 0>; +}; + +&spi_9 { + status = "ok"; + can-controller@0 { + compatible = "renesas,rh850"; + reg = <0>; + interrupt-parent = <&tlmm>; + interrupts = <127 0>; + spi-max-frequency = <5000000>; + }; +}; + +&pil_modem { + pinctrl-names = "default"; + pinctrl-0 = <&modem_mux>; +}; + diff --git a/arch/arm/boot/dts/qcom/msm8996pro.dtsi b/arch/arm/boot/dts/qcom/msm8996pro.dtsi index 28577dc6d72f67f568dbd2a37bbeec8360e486c1..ca89a517df5c11dd690ec99c6b77d61595e0fb3b 100644 --- a/arch/arm/boot/dts/qcom/msm8996pro.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996pro.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,6 +20,10 @@ / { model = "Qualcomm Technologies, Inc. MSM 8996pro"; qcom,msm-id = <305 0x10000>; + + chosen { + bootargs = "fpsimd.fpsimd_settings=1 app_setting.use_app_setting=0 app_setting.use_32bit_app_setting_pro=1"; + }; }; &apc_apm { @@ -958,6 +962,26 @@ < 1516800000 17 >, < 1593600000 18 >, < 1996800000 20 >; + qcom,pwrcl-speedbin2-v0 = + < 0 0 >, + < 307200000 1 >, + < 384000000 2 >, + < 460800000 3 >, + < 537600000 4 >, + < 614400000 5 >, + < 691200000 6 >, + < 768000000 7 >, + < 844800000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >; qcom,perfcl-speedbin0-v0 = < 0 0 >, < 307200000 1 >, @@ -1014,6 +1038,30 @@ < 1977600000 23 >, < 2054400000 24 >, < 2150400000 25 >; + qcom,perfcl-speedbin2-v0 = + < 0 0 >, + < 307200000 1 >, + < 384000000 2 >, + < 460800000 3 >, + < 537600000 4 >, + < 614400000 5 >, + < 691200000 6 >, + < 748800000 7 >, + < 825600000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >, + < 1670400000 19 >, + < 1747200000 20 >, + < 1824000000 21 >, + < 1900800000 22 >; qcom,cbf-speedbin0-v0 = < 0 0 >, < 192000000 1 >, @@ -1056,6 +1104,27 @@ < 1440000000 17 >, < 1516800000 18 >, < 1593600000 19 >; + qcom,cbf-speedbin2-v0 = + < 0 0 >, + < 192000000 1 >, + < 307200000 2 >, + < 384000000 3 >, + < 441600000 4 >, + < 537600000 5 >, + < 614400000 6 >, + < 691200000 7 >, + < 768000000 8 >, + < 844800000 9 >, + < 902400000 10 >, + < 979200000 11 >, + < 1056000000 12 >, + < 1132800000 13 >, + < 1190400000 14 >, + < 1286400000 15 >, + < 1363200000 16 >, + < 1440000000 17 >, + < 1516800000 18 >, + < 1593600000 19 >; }; &clock_mmss { @@ -1106,6 +1175,20 @@ < 510000000 5 >, < 560000000 7 >, < 624000000 7 >; + qcom,gfxfreq-speedbin2 = + < 0 0 0 >, + < 133000000 2 4 >, + < 214000000 3 4 >, + < 315000000 4 4 >, + < 401800000 5 5 >, + < 510000000 6 5 >; + qcom,gfxfreq-mx-speedbin2 = + < 0 0 >, + < 133000000 4 >, + < 214000000 4 >, + < 315000000 4 >, + < 401800000 5 >, + < 510000000 5 >; }; &msm_cpufreq { @@ -1422,5 +1505,62 @@ qcom,bus-max = <0>; }; }; + + qcom,gpu-pwrlevels-2 { + #address-cells = <1>; + #size-cells = <0>; + + qcom,speed-bin = <2>; + + qcom,initial-pwrlevel = <3>; + + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <510000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <11>; + qcom,bus-max = <11>; + }; + + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <401800000>; + qcom,bus-freq = <8>; + qcom,bus-min = <7>; + qcom,bus-max = <9>; + }; + + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <315000000>; + qcom,bus-freq = <6>; + qcom,bus-min = <5>; + qcom,bus-max = <7>; + }; + + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <214000000>; + qcom,bus-freq = <4>; + qcom,bus-min = <3>; + qcom,bus-max = <5>; + }; + + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <133000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <4>; + }; + + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <27000000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi b/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..32adb9a36dd4eef3722dbef30a62bd55733b39ad --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi @@ -0,0 +1,169 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&hl7509_en_vreg { + status = "ok"; +}; + +&hl7509_vreg { + status = "ok"; +}; + +&gfx_cpr { + vdd-supply = <&hl7509_vreg>; + qcom,cpr-step-quot-init-min = <20>; + qcom,cpr-step-quot-init-max = <26>; + qcom,voltage-step = <10000>; + /delete-property/ qcom,cpr-enable; +}; + +&gfx_vreg { + qcom,cpr-voltage-ceiling = + <600000 670000 670000 750000 830000 + 910000 960000 1020000>; + qcom,cpr-voltage-floor = + <600000 600000 600000 600000 600000 + 600000 600000 600000>; +}; + +&pm8994_l3 { + regulator-min-microvolt = <875000>; + regulator-max-microvolt = <875000>; + qcom,init-voltage = <875000>; +}; + +&pm8994_l11 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + qcom,init-voltage = <850000>; +}; + +&pm8994_l17 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,init-voltage = <1800000>; +}; + +&pm8994_l23 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; +}; + +&pm8994_l27 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + qcom,init-voltage = <800000>; +}; + +&pm8994_l29 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + qcom,init-voltage = <2500000>; +}; + +&rpm_bus { + rpm-regulator-ldoa26 { + /delete-node/ pm8994_l26_corner; + /delete-node/ pm8994_l26_floor_corner; + + pm8994_l26: regulator-l26 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; + status = "okay"; + }; + }; + + rpm-regulator-ldoa31 { + status = "okay"; + pm8994_l31: regulator-l31 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + qcom,init-voltage = <1100000>; + status = "okay"; + }; + }; +}; + +&clock_cpu { + qcom,pwrcl-speedbin0-v0 = + < 0 0 >, + < 768000000 7 >, + < 844800000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >; + + qcom,perfcl-speedbin0-v0 = + < 0 0 >, + < 825600000 8 >, + < 902400000 9 >, + < 979200000 10 >, + < 1056000000 11 >, + < 1132800000 12 >, + < 1209600000 13 >, + < 1286400000 14 >, + < 1363200000 15 >, + < 1440000000 16 >, + < 1516800000 17 >, + < 1593600000 18 >, + < 1670400000 19 >, + < 1747200000 20 >, + < 1824000000 21 >, + < 1900800000 22 >, + < 1977600000 23 >, + < 2054400000 24 >; + + qcom,cbf-speedbin0-v0 = + < 0 0 >, + < 537600000 5 >, + < 614400000 6 >, + < 691200000 7 >, + < 768000000 8 >, + < 844800000 9 >, + < 902400000 10 >, + < 979200000 11 >, + < 1056000000 12 >, + < 1132800000 13 >, + < 1190400000 14 >, + < 1286400000 15 >, + < 1363200000 16 >, + < 1440000000 17 >, + < 1516800000 18 >, + < 1593600000 19 >; +}; + +&clock_gpu { + qcom,gfxfreq-speedbin0 = + < 0 0 0 >, + < 315000000 4 4 >, + < 401800000 5 5 >, + < 510000000 6 5 >, + < 560000000 7 7 >, + < 624000000 8 7 >; + + qcom,gfxfreq-mx-speedbin0 = + < 0 0 >, + < 315000000 4 >, + < 401800000 5 >, + < 510000000 5 >, + < 560000000 7 >, + < 624000000 7 >; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi index d7372f2bb2e4e17820c3b6e7f99a15bda185209b..2095b4e0706985b35d33509a739acb0e1844721c 100644 --- a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi @@ -334,19 +334,22 @@ qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_active - &cam_sensor_front_active>; + &cam_sensor_front_active &led_enable>; pinctrl-1 = <&cam_sensor_mclk1_suspend - &cam_sensor_front_suspend>; + &cam_sensor_front_suspend &led_disable>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pm8998_gpios 9 0>; + <&pm8998_gpios 9 0>, + <&tlmm 21 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-flash-en = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2", - "CAM_VDIG"; + "CAM_VDIG", + "FLASH_EN"; qcom,sensor-position = <1>; qcom,sensor-mode = <0>; qcom,cci-master = <1>; @@ -356,6 +359,45 @@ clock-names = "cam_src_clk", "cam_clk"; qcom,clock-rates = <24000000 0>; }; + + qcom,camera@3 { + cell-index = <3>; + compatible = "qcom,camera"; + reg = <0x03>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <270>; + qcom,led-flash-src = <&led_flash1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-max-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_front_iris_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_front_iris_suspend>; + gpios = <&tlmm 16 0>, + <&tlmm 23 0>; + qcom,gpio-reset = <1>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + clocks = <&clock_mmss clk_mclk3_clk_src>, + <&clock_mmss clk_mmss_camss_mclk3_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; }; &pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ diff --git a/arch/arm/boot/dts/qcom/msm8998-cdp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-cdp-overlay.dts index 5fe0d0176618aedcaf928bce3fdbebb1c4b3a815..9cf94012695ece950dbd7b10a515bf95d289c60f 100644 --- a/arch/arm/boot/dts/qcom/msm8998-cdp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-cdp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-cdp.dts index 487d71d4b6a845263aa57a829e3ddbfe684b6be2..3d8ccbd39c95eb9b01795e590bc12ee8a3a3aa5b 100644 --- a/arch/arm/boot/dts/qcom/msm8998-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-cdp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi index 722c18a2638879ce16254fc9ddaea5a4bfe88746..d00ae0f3730cc9d6a576f3ca6cce2414b7021971 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi @@ -11,6 +11,12 @@ * GNU General Public License for more details. */ +&soc { + /delete-node/qcom,camera-flash@0; + /delete-node/qcom,camera-flash@1; + /delete-node/gpio-regulator@0; +}; + &soc { tlmm: pinctrl@03400000 { cam_sensor_rear_active: cam_sensor_rear_active { @@ -132,19 +138,17 @@ }; }; -&soc { - /delete-node/gpio-regulator@0; -}; - &cci { /delete-node/qcom,camera@0; /delete-node/qcom,camera@1; /delete-node/qcom,camera@2; + /delete-node/qcom,camera@3; /delete-node/qcom,eeprom@0; /delete-node/qcom,eeprom@1; /delete-node/qcom,eeprom@2; /delete-node/qcom,actuator@0; /delete-node/qcom,actuator@1; + /delete-node/qcom,tof@0; /delete-node/qcom,ois@0; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-qrd.dtsi index 8b68ece2239ff9e15831a105e8b2eb6151530503..42414db3cc4853d1bb8966e93d9350fe0688d132 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-qrd.dtsi @@ -11,6 +11,12 @@ * GNU General Public License for more details. */ +&soc { + /delete-node/qcom,camera-flash@0; + /delete-node/qcom,camera-flash@1; + /delete-node/gpio-regulator@0; +}; + &soc { tlmm: pinctrl@03400000 { cam_sensor_rear_active: cam_sensor_rear_active { @@ -170,19 +176,17 @@ }; }; -&soc { - /delete-node/gpio-regulator@0; -}; - &cci { /delete-node/qcom,camera@0; /delete-node/qcom,camera@1; /delete-node/qcom,camera@2; + /delete-node/qcom,camera@3; /delete-node/qcom,eeprom@0; /delete-node/qcom,eeprom@1; /delete-node/qcom,eeprom@2; /delete-node/qcom,actuator@0; /delete-node/qcom,actuator@1; + /delete-node/qcom,tof@0; /delete-node/qcom,ois@0; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi index d0d13332595aa5ecd5f1726db65903958f14b678..64f377f1a576b26f6e332c8e1f778d9ae0fa3dd7 100644 --- a/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi @@ -10,8 +10,6 @@ * GNU General Public License for more details. */ -#include "dsi-panel-sim-video.dtsi" -#include "dsi-panel-sim-dualmipi-video.dtsi" #include "dsi-panel-nt35597-dualmipi-wqxga-video.dtsi" #include "dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi" #include "dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi index 24186aca22be6477a8795c0f202bc30c919c7863..1b746a5935795f52bea32bc7698613d5e761ca3c 100644 --- a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi @@ -335,6 +335,7 @@ qcom,supply-max-voltage = <0>; qcom,supply-enable-load = <0>; qcom,supply-disable-load = <0>; + qcom,supply-lp-mode-disable-allowed; }; }; @@ -363,6 +364,7 @@ qcom,supply-max-voltage = <880000>; qcom,supply-enable-load = <73400>; qcom,supply-disable-load = <32>; + qcom,supply-lp-mode-disable-allowed; }; }; @@ -502,7 +504,16 @@ qcom,msm_ext_disp = <&msm_ext_disp>; - qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03]; + qcom,aux-cfg0-settings = [1c 00]; + qcom,aux-cfg1-settings = [20 13 23 1d]; + qcom,aux-cfg2-settings = [24 00]; + qcom,aux-cfg3-settings = [28 00]; + qcom,aux-cfg4-settings = [2c 0a]; + qcom,aux-cfg5-settings = [30 26]; + qcom,aux-cfg6-settings = [34 0a]; + qcom,aux-cfg7-settings = [38 03]; + qcom,aux-cfg8-settings = [3c bb]; + qcom,aux-cfg9-settings = [40 03]; qcom,logical2physical-lane-map = [02 03 01 00]; qcom,core-supply-entries { @@ -651,5 +662,3 @@ qcom,pluggable; }; }; - -#include "msm8998-mdss-panels.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-mtp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-mtp-overlay.dts index 8525d781aae2908a602c686cb75ea279972f6cfa..0659ced82a5605bba64b017d93f5b88d07cfdb9d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-mtp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-mtp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-mtp.dts index f608f5f59a8067b68f19a17db8f627f031d4f981..8a38d1eeea5089505f7afc024316b25bbd7a43cc 100644 --- a/arch/arm/boot/dts/qcom/msm8998-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi index 220bad31d7f81c8f7fe378ee4c0b1fddcf588fa4..318dc5d7c791b7e9e2110152822245a4a3cdbe08 100644 --- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi @@ -585,6 +585,19 @@ bias-pull-down; }; }; + + pcie0_wake_sleep: pcie0_wake_sleep { + mux { + pins = "gpio37"; + function = "gpio"; + }; + + config { + pins = "gpio37"; + drive-strength = <2>; + bias-disable; + }; + }; }; hph_en0_ctrl { @@ -983,7 +996,7 @@ cam_sensor_mclk0_active: cam_sensor_mclk0_active { /* MCLK0 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio13"; function = "cam_mclk"; }; @@ -998,7 +1011,7 @@ cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { /* MCLK0 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio13"; function = "cam_mclk"; }; @@ -1292,7 +1305,7 @@ cam_sensor_mclk1_active: cam_sensor_mclk1_active { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio14"; function = "cam_mclk"; }; @@ -1307,7 +1320,7 @@ cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio14"; function = "cam_mclk"; }; @@ -1319,6 +1332,36 @@ }; }; + cam_sensor_mclk3_active: cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + /* CLK */ + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + /* CLK */ + pins = "gpio16"; + function = "cam_mclk"; + }; + + config { + pins = "gpio16"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + cam_sensor_rear2_active: cam_sensor_rear2_active { /* RESET, STANDBY */ mux { @@ -1455,7 +1498,7 @@ cam_sensor_mclk2_active: cam_sensor_mclk2_active { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio15"; function = "cam_mclk"; }; @@ -1470,7 +1513,7 @@ cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio15"; function = "cam_mclk"; }; @@ -1496,6 +1539,21 @@ }; }; + + cam_sensor_front_iris_active: cam_sensor_front_iris_active { + /* RESET */ + mux { + pins = "gpio23"; + function = "gpio"; + }; + + config { + pins = "gpio23"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + blsp2_uart1_active: blsp2_uart1_active { mux { pins = "gpio53", "gpio54", "gpio55", "gpio56"; @@ -1562,6 +1620,20 @@ }; }; + cam_sensor_front_iris_suspend: cam_sensor_front_iris_suspend { + /* RESET */ + mux { + pins = "gpio23"; + function = "gpio"; + }; + + config { + pins = "gpio23"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + pmx_mdss: pmx_mdss { mdss_dsi_active: mdss_dsi_active { mux { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-overlay.dts new file mode 100644 index 0000000000000000000000000000000000000000..55255261a8277550763779bc80efa4b457b1fbed --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-overlay.dts @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; +/plugin/; + +#include +#include + +#include "msm8998-qrd.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 QRD"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,msm-id = <292 0x0>; + qcom,board-id = <11 0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk-overlay.dts new file mode 100644 index 0000000000000000000000000000000000000000..408a067dbeeefa4ecfe5b85c74051f999bcbc960 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk-overlay.dts @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; +/plugin/; + +#include +#include + +#include "msm8998-qrd-skuk.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 QRD SKUK"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,msm-id = <292 0x0>; + qcom,board-id = <0x01000b 0x80>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts index 753f01ea2ea706b17f87f2aa1dcbd1f684eb435a..b3062c48e0510acbf2831e417f709407fcdbb365 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-skuk.dtsi" #include "msm8998-camera-sensor-skuk.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1-overlay.dts new file mode 100644 index 0000000000000000000000000000000000000000..ff0e24dd0371e6286d84dad246dd2bf78bc10b46 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1-overlay.dts @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; +/plugin/; + +#include +#include + +#include "msm8998-qrd-vr1.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 QRD VR1 Board"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,msm-id = <292 0x0>; + qcom,board-id = <0x02000b 0x80>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts index f5780529c99ab60f4e2dfcc6247638f66c38c4d1..9b8e631f80a695c1782a9cdcdd011a6684c17369 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-vr1.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-qrd.dts index 952b9a5cec6fa3449411ddad624180222068f435..4d50d8611050e38dae57265598ad3e1caf90527d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi index 045cdda09d185ed1cb4bfba10af639ddfc6d67d2..be70f129e272242082c6b50aaba46c13d39649eb 100644 --- a/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi @@ -84,6 +84,8 @@ pm8998_s5: regulator-s5 { regulator-min-microvolt = <1904000>; regulator-max-microvolt = <2040000>; + qcom,init-pin-ctrl-mode = <8>; /* PMIC_AWAKE */ + qcom,send-defaults; status = "okay"; }; }; @@ -93,6 +95,8 @@ pm8998_s7: regulator-s7 { regulator-min-microvolt = <900000>; regulator-max-microvolt = <1028000>; + qcom,init-pin-ctrl-mode = <8>; /* PMIC_AWAKE */ + qcom,send-defaults; status = "okay"; }; }; @@ -407,7 +411,7 @@ rpm-regulator-ldoa24 { status = "okay"; pm8998_l24: regulator-l24 { - regulator-min-microvolt = <3088000>; + regulator-min-microvolt = <1848000>; regulator-max-microvolt = <3088000>; parent-supply = <&pm8998_l12>; status = "okay"; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-cdp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-v2-cdp-overlay.dts index c602459815b238699e9c5d94d1fa244def815f5e..1ae671663edb51e26c8a86ffa7aeee911e3c0a2d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-cdp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-cdp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts index 0f5ad5366c843906bb131fdee36b6556e175fad3..f54017dcae9ef9814415c785a2ccd872f428cec8 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-mtp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-v2-mtp-overlay.dts index 660fc4d51f9fcec67b4f6cc423e24457eeb508a7..c446a6a78f4229f696e5e27f080a8e6412515081 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-mtp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-mtp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts index 0708573934f3119306db39cbffdd8417329787fe..0375ee29984c3a996583bc2ae887835ee38b6655 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts index a64f620f399966feb45f19ef0c7ba794a8cdfb3f..b1d00eda89ef9f3a0ca126f5f28fdede24b761c2 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-skuk.dtsi" #include "msm8998-camera-sensor-skuk-evt3.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts index f3ba42e4dfd93de5b41cce82c285f0edd27cbf5a..4e75d161ec721a8006ee437a66a6844b90561bb5 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts @@ -13,6 +13,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-skuk-hdk.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts index 7e7eb96c01d6f33acdd8e59304f841e9fdd4a5ce..5727f3312a49d1640a789b62d88b1c612edd0ca6 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-skuk.dtsi" #include "msm8998-camera-sensor-skuk.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts index 58c7dc3bac11891b984a60c343852a832a924909..ebd5b307388cd9dd75e7862255e1714295b13e8d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd-vr1.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts index 37ad18278e5c3e020e6a40110209083b5260c407..ed3a73e0b811d0ec8c264cdf3a2330b72dcbfb6a 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,6 +13,7 @@ /dts-v1/; #include "msm8998-v2.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp-overlay.dts index 47c55a04501718e590cdee0144c331e83e58a108..f57238978baf63bffa3867a3f0a1d1e5ab61c5cd 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts index 871d13bdaa1aee0764deca131f4f63f71c953bd6..5d007dd559103a3b5d449e9cbb616da29fb3f545 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-cdp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-cdp.dts index 6884397bf0ba8928ce0d2cccfd128cf16be63af4..6e4247fd884f6a4108251f9bf0f3c9013de8ef89 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-cdp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.1-interposer-sdm660.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-interposer-sdm660-cdp.dtsi" #include "msm8998-interposer-pm660.dtsi" #include "msm8998-interposer-sdm660-audio.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-mtp.dts index 2e5de95de0c556e909632697c07c034ac2c4ad61..cb7ee2266d5284dfdff0e312a438cf9675a58f4d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.1-interposer-sdm660.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-interposer-sdm660-mtp.dtsi" #include "msm8998-interposer-pm660.dtsi" #include "msm8998-interposer-sdm660-audio.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-qrd.dts index 180cc9128f53a044dfbd57c76fde89f87559d05e..9376f52e0737add32be283896bc0643b26a35212 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-sdm660-qrd.dts @@ -13,6 +13,8 @@ /dts-v1/; +#include "msm8998-v2.1-interposer-sdm660.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-v2.1-interposer-sdm660-qrd.dtsi" #include "msm8998-interposer-pm660.dtsi" #include "msm8998-interposer-sdm660-audio.dtsi" diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-4k-display.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-4k-display.dts new file mode 100644 index 0000000000000000000000000000000000000000..eb2d812aa1f8f0387697264c6d8b655cf8fc1c06 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-4k-display.dts @@ -0,0 +1,52 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8998-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" +#include "msm8998-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 MTP, 4k display"; + compatible = "qcom,msm8998-mtp", "qcom,msm8998", "qcom,mtp"; + qcom,board-id = <8 4>; +}; + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "split_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_sharp_4k_dsc_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; + +&mdss_dsi1 { + qcom,dsi-pref-prim-pan = <&dsi_sharp_4k_dsc_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-overlay.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-overlay.dts index 54a0e98cdce7b6e8c4fda973d5004d3a4974a3e3..5f17f73df8d6635b0d6a21cc4be41b13ef2d0ce1 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-overlay.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp-overlay.dts @@ -18,6 +18,7 @@ #include #include +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts index 9d7cbc93d9df48194a0e0eb72d651c55554fb6a2..0bf3e62766c44eae1b89359a7659769733f89f98 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-mtp.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts index b20c888ad9331093c2fa451bb538a2618d617b56..4d64740143e8d2c021a70606821d0e87174fc9e6 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,6 +14,7 @@ /dts-v1/; #include "msm8998-v2.1.dtsi" +#include "msm8998-mdss-panels.dtsi" #include "msm8998-qrd.dtsi" / { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi index 348faf9b69c39c57108ca99ef39e4f4fe1606db8..b2f30de94bbc9e1251c7cebe9ce5da7a98e4b6c5 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi @@ -591,53 +591,53 @@ qcom,cpr-open-loop-voltage-adjustment = /* Speed bin 0 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-12000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) (-20000) (-24000) (-28000) (-28000)>, /* Speed bin 1 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-12000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) (-20000) (-24000) (-28000) (-28000)>, /* Speed bin 2 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-12000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) (-20000) (-24000) (-28000) (-28000)>, /* Speed bin 3 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-12000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) (-20000) (-24000) (-28000) (-28000)>; qcom,cpr-closed-loop-voltage-adjustment = /* Speed bin 0 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-7000) (-8000) - (-10000) (-10000) (-11000) (-12000) (-13000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-11000) (-12000) (-13000) (-14000) (-14000) (-15000) (-21000) (-24000) (-26000) (-28000)>, /* Speed bin 1 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-7000) (-8000) - (-10000) (-10000) (-11000) (-12000) (-13000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-11000) (-12000) (-13000) (-14000) (-14000) (-15000) (-21000) (-24000) (-26000) (-28000)>, /* Speed bin 2 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-7000) (-8000) - (-10000) (-10000) (-11000) (-12000) (-13000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-11000) (-12000) (-13000) (-14000) (-14000) (-15000) (-21000) (-24000) (-26000) (-28000)>, /* Speed bin 3 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-7000) (-8000) - (-10000) (-10000) (-11000) (-12000) (-13000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-11000) (-12000) (-13000) (-14000) (-14000) (-15000) (-21000) (-24000) (-26000) (-28000)>; @@ -926,65 +926,65 @@ qcom,cpr-open-loop-voltage-adjustment = /* Speed bin 0 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-8000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-8000) (-12000) (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) - (-20000) (-20000) (-24000) (-24000) (-24000) + (-20000) (-16000) (-16000) (-16000) (-12000) (-28000) (-28000) (-28000) (-28000) (-28000) (-28000) (-28000)>, /* Speed bin 1 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-8000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-8000) (-12000) (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) - (-20000) (-20000) (-24000) (-24000) (-28000) + (-20000) (-16000) (-16000) (-16000) (-16000) (-28000)>, /* Speed bin 2 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-8000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-8000) (-12000) (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) - (-20000) (-20000) (-24000) (-24000) (-24000) + (-20000) (-16000) (-16000) (-16000) (-12000) (-28000) (-28000) (-28000) (-28000) (-28000)>, /* Speed bin 3 */ - <(-4000) (-4000) (-4000) (-4000) (-4000) - (-4000) (-4000) (-4000) (-8000) (-8000) - (-8000) (-8000) (-12000) (-12000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-8000) (-12000) (-12000) (-12000) (-12000) (-12000) (-12000) (-16000) (-16000) - (-20000) (-20000) (-24000) (-24000) (-24000) + (-20000) (-16000) (-16000) (-16000) (-12000) (-28000) (-28000) (-28000) (-28000) (-28000) (-28000)>; qcom,cpr-closed-loop-voltage-adjustment = /* Speed bin 0 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-6000) (-7000) - (-9000) (-10000) (-10000) (-11000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-10000) (-11000) (-12000) (-12000) (-13000) (-14000) (-14000) (-15000) - (-18000) (-21000) (-24000) (-25000) (-25000) + (-16000) (-16000) (-17000) (-15000) (-13000) (-26000) (-26000) (-27000) (-27000) (-28000) (-28000) (-28000)>, /* Speed bin 1 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-6000) (-7000) - (-9000) (-10000) (-10000) (-11000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-10000) (-11000) (-12000) (-12000) (-13000) (-14000) (-14000) (-15000) - (-18000) (-21000) (-24000) (-26000) (-27000) + (-16000) (-16000) (-17000) (-16000) (-15000) (-28000)>, /* Speed bin 2 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-6000) (-7000) - (-9000) (-10000) (-10000) (-11000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-10000) (-11000) (-12000) (-12000) (-13000) (-14000) (-14000) (-15000) - (-18000) (-21000) (-24000) (-25000) (-26000) + (-16000) (-16000) (-17000) (-15000) (-14000) (-27000) (-27000) (-28000) (-28000) (-28000)>, /* Speed bin 3 */ - <(-5000) (-5000) (-5000) (-5000) (-5000) - (-5000) (-5000) (-5000) (-6000) (-7000) - (-9000) (-10000) (-10000) (-11000) (-12000) + < 0 0 0 0 0 + 0 0 0 0 0 + 0 (-10000) (-10000) (-11000) (-12000) (-12000) (-13000) (-14000) (-14000) (-15000) - (-18000) (-21000) (-24000) (-25000) (-26000) + (-16000) (-16000) (-17000) (-15000) (-14000) (-26000) (-27000) (-27000) (-28000) (-28000) (-28000)>; diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 85142c6c755e350bc604878a0ef362991eda58f7..c1d785e426691f9b7be925ca0dc110978d8f4af2 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -441,6 +441,7 @@ interrupts = ; qcom,ee = <0>; qcom,channel = <0>; + qcom,reserved-chan = <511>; #address-cells = <2>; #size-cells = <0>; interrupt-controller; @@ -2661,10 +2662,13 @@ 0x800 0x00 0x00 0x808 0x03 0x00>; - pinctrl-names = "default"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; + pinctrl-1 = <&pcie0_clkreq_default + &pcie0_perst_default + &pcie0_wake_sleep>; perst-gpio = <&tlmm 35 0>; wake-gpio = <&tlmm 37 0>; @@ -3196,6 +3200,10 @@ <&clock_gcc clk_rf_clk3_pin>; clock-names = "rf_clk3_clk", "rf_clk3_pin_clk"; qcom,smmu-support; + qcom,smmu-s1-en; + qcom,smmu-fast-map; + qcom,smmu-coherent; + qcom,smmu-mapping = <0x20000000 0xe0000000>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/qcom/sda630-pm660a-qrd-hdk.dts b/arch/arm/boot/dts/qcom/sda630-pm660a-qrd-hdk.dts new file mode 100644 index 0000000000000000000000000000000000000000..480a69601541a37130c6787d29c47f023b038c6c --- /dev/null +++ b/arch/arm/boot/dts/qcom/sda630-pm660a-qrd-hdk.dts @@ -0,0 +1,85 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "sda630.dtsi" +#include "sdm630-qrd.dtsi" +#include "msm-pm660a.dtsi" +#include "sdm660-internal-codec.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660A QRD HDK630"; + compatible = "qcom,sda630-qrd", "qcom,sda630", "qcom,qrd"; + qcom,board-id = <0x0006000b 0x00>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; + +&int_codec { + qcom,model = "sdm660-snd-card-skush"; + /delete-property/ qcom,us-euro-gpios; + qcom,audio-routing = + "RX_BIAS", "INT_MCLK0", + "SPK_RX_BIAS", "INT_MCLK0", + "INT_LDO_H", "INT_MCLK0", + "MIC BIAS External2", "Headset Mic", + "AMIC2", "MIC BIAS External2", + "MIC BIAS External", "Digital Mic1", + "DMIC1", "MIC BIAS External", + "MIC BIAS External", "Digital Mic3", + "DMIC3", "MIC BIAS External", + "MIC BIAS External", "Digital Mic4", + "DMIC4", "MIC BIAS External", + "SpkrLeft IN", "SPK1 OUT", + "PDM_IN_RX1", "PDM_OUT_RX1", + "PDM_IN_RX2", "PDM_OUT_RX2", + "PDM_IN_RX3", "PDM_OUT_RX3", + "ADC1_IN", "ADC1_OUT", + "ADC2_IN", "ADC2_OUT", + "ADC3_IN", "ADC3_OUT"; + qcom,wsa-max-devs = <1>; + qcom,wsa-devs = <&wsa881x_211_en>, <&wsa881x_213_en>; + qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft"; +}; + +&pm660a_oledb { + status = "okay"; + qcom,oledb-default-voltage-mv = <6400>; +}; + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + oledb-supply = <&pm660a_oledb>; + lab-supply = <&lab_regulator>; + ibb-supply = <&ibb_regulator>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&dsi_rm67195_amoled_fhd_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; diff --git a/arch/arm/boot/dts/qcom/sda660-pm660a-qrd-hdk.dts b/arch/arm/boot/dts/qcom/sda660-pm660a-qrd-hdk.dts new file mode 100644 index 0000000000000000000000000000000000000000..c2bf2c4a088ef671483a37148c0202b0c70eb9b6 --- /dev/null +++ b/arch/arm/boot/dts/qcom/sda660-pm660a-qrd-hdk.dts @@ -0,0 +1,193 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "sda660.dtsi" +#include "sdm660-qrd.dtsi" +#include "msm-pm660a.dtsi" + +&smb1351_charger { + status = "disabled"; +}; + +&i2c_2 { + smb138x: qcom,smb138x@8 { + compatible = "qcom,i2c-pmic"; + reg = <0x8>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&tlmm>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + interrupt_names = "smb138x"; + interrupt-controller; + #interrupt-cells = <3>; + qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; + pinctrl-names = "default"; + pinctrl-0 = <&smb_int_default>; + + smb138x_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + smb138x_tadc: qcom,tadc@3600 { + compatible = "qcom,tadc"; + reg = <0x3600 0x100>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + interrupt-parent = <&smb138x>; + interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "eoc"; + + batt_temp@0 { + reg = <0>; + qcom,rbias = <68100>; + qcom,rtherm-at-25degc = <68000>; + qcom,beta-coefficient = <3450>; + }; + + skin_temp@1 { + reg = <1>; + qcom,rbias = <33000>; + qcom,rtherm-at-25degc = <68000>; + qcom,beta-coefficient = <3450>; + }; + + die_temp@2 { + reg = <2>; + qcom,scale = <(-1306)>; + qcom,offset = <397904>; + }; + + batt_i@3 { + reg = <3>; + qcom,channel = <3>; + qcom,scale = <(-20000000)>; + }; + + batt_v@4 { + reg = <4>; + qcom,scale = <5000000>; + }; + + input_i@5 { + reg = <5>; + qcom,scale = <14285714>; + }; + + input_v@6 { + reg = <6>; + qcom,scale = <25000000>; + }; + + otg_i@7 { + reg = <7>; + qcom,scale = <5714286>; + }; + }; + + smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 { + compatible = "qcom,smb138x-parallel-slave"; + qcom,pmic-revid = <&smb138x_revid>; + reg = <0x1000 0x700>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&smb138x>; + io-channels = + <&smb138x_tadc 1>, + <&smb138x_tadc 2>, + <&smb138x_tadc 3>, + <&smb138x_tadc 14>, + <&smb138x_tadc 15>, + <&smb138x_tadc 16>, + <&smb138x_tadc 17>; + io-channel-names = + "connector_temp", + "charger_temp", + "batt_i", + "connector_temp_thr1", + "connector_temp_thr2", + "connector_temp_thr3", + "charger_temp_max"; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x10 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "chg-state-change"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>, + <0x16 0x6 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog-bark", + "temperature-change"; + }; + }; + }; +}; + +&tlmm { + smb_int_default: smb_int_default { + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + +/ { + model = "Qualcomm Technologies, Inc. SDA 660 PM660 + PM660A QRD HDK660"; + compatible = "qcom,sda660-qrd", "qcom,sda660", "qcom,qrd"; + qcom,board-id = <0x0006000b 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; + +&pm660a_oledb { + status = "okay"; + qcom,oledb-default-voltage-mv = <6400>; +}; + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "single_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + lab-supply = <&lab_regulator>; + ibb-supply = <&ibb_regulator>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&dsi_rm67195_amoled_fhd_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi index 55e6943bf32742ad0b2b0f1899f3ff97b8e8a937..fd109450ad8154426bf96d73339a5ddf11b1aa66 100644 --- a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi @@ -192,3 +192,30 @@ qcom,partial-update-enabled = "single_roi"; qcom,panel-roi-alignment = <2 2 4 2 1080 2>; }; + +&pm660l_pwm_4 { + qcom,dtest-line = <2>; /* DTEST2 */ + qcom,dtest-output = <2>; /* OUTPUT PWM */ +}; + +&pm660l_gpios { + gpio@c500 { + qcom,mode = <1>; /* DIG_OUT */ + qcom,output-type = <0>; /* CMOS */ + qcom,src-sel = <7>; /* DTEST2 */ + qcom,master-en = <1>; /* Enable MPP */ + qcom,invert = <0>; /* Enable MPP */ + }; +}; + +&dsi_sharp_split_link_wuxga_video { + pwms = <&pm660l_pwm_4 0 0>; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm"; + qcom,mdss-dsi-bl-pwm-pmi; + qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>; + qcom,panel-supply-entries = <&dsi_panel_split_link_pwr_supply>; +}; + +&dsi_rm67195_amoled_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/sdm630-mdss-panels.dtsi index dfed9ec80a34246031adc1dcd7815b223e9fad90..4e3ebd445814ab3df81e9e5b98ed1c1cc282b5dd 100644 --- a/arch/arm/boot/dts/qcom/sdm630-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-mdss-panels.dtsi @@ -16,6 +16,7 @@ #include "dsi-panel-truly-1080p-cmd.dtsi" #include "dsi-panel-truly-1080p-video.dtsi" #include "dsi-panel-rm67195-amoled-fhd-cmd.dtsi" +#include "dsi-panel-sharp-split-link-wuxga-video.dtsi" &soc { dsi_panel_pwr_supply: dsi_panel_pwr_supply { @@ -51,6 +52,48 @@ }; }; + dsi_panel_split_link_pwr_supply: dsi_panel_split_link_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "wqhd-vddio"; + qcom,supply-min-voltage = <1800000>; + qcom,supply-max-voltage = <1950000>; + qcom,supply-enable-load = <32000>; + qcom,supply-disable-load = <80>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "vdda-3p3"; + qcom,supply-min-voltage = <3300000>; + qcom,supply-max-voltage = <3300000>; + qcom,supply-enable-load = <13900>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@2 { + reg = <2>; + qcom,supply-name = "lab"; + qcom,supply-min-voltage = <5500000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@3 { + reg = <3>; + qcom,supply-name = "ibb"; + qcom,supply-min-voltage = <5500000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <10>; + }; + }; + dsi_panel_pwr_supply_labibb_amoled: dsi_panel_pwr_supply_labibb_amoled { #address-cells = <1>; @@ -114,7 +157,14 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_nt35695b_truly_fhd_cmd { @@ -124,7 +174,14 @@ 24 1e 08 09 05 03 04 a0 24 1a 08 09 05 03 04 a0]; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_truly_1080_vid { @@ -138,7 +195,14 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x1c>; + qcom,mdss-dsi-panel-on-check-value = <0x1c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_truly_1080_cmd { @@ -148,7 +212,14 @@ 23 1e 08 09 05 03 04 a0 23 1a 08 09 05 03 04 a0]; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x1c>; + qcom,mdss-dsi-panel-on-check-value = <0x1c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_rm67195_amoled_fhd_cmd { @@ -160,3 +231,15 @@ qcom,mdss-dsi-t-clk-post = <0x0d>; qcom,mdss-dsi-t-clk-pre = <0x2f>; }; + +&dsi_sharp_split_link_wuxga_video { + qcom,mdss-dsi-panel-timings-phy-v2 = [25 1f 09 0a 06 03 04 a0 + 25 1f 09 0a 06 03 04 a0 + 25 1f 09 0a 06 03 04 a0 + 25 1f 09 0a 06 03 04 a0 + 25 1f 08 0a 06 03 04 a0]; + qcom,mdss-dsi-min-refresh-rate = <48>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-mdss.dtsi b/arch/arm/boot/dts/qcom/sdm630-mdss.dtsi index d35704224f455e39809de41583264be3e78e0f5e..49e4fd7e5ba7957d849c180742b35c8902355495 100644 --- a/arch/arm/boot/dts/qcom/sdm630-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-mdss.dtsi @@ -112,13 +112,14 @@ clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_MDSS_AHB_CLK>, <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MMSS_THROTTLE_MDSS_AXI_CLK>, <&clock_mmss MDP_CLK_SRC>, <&clock_mmss MMSS_MDSS_MDP_CLK>, <&clock_mmss MMSS_MDSS_VSYNC_CLK>, <&clock_mmss MDP_CLK_SRC>; clock-names = "mnoc_clk", "iface_clk", "bus_clk", - "core_clk_src", "core_clk", "vsync_clk", - "lut_clk"; + "throttle_bus_clk", "core_clk_src", + "core_clk", "vsync_clk", "lut_clk"; qcom,mdp-settings = <0x01190 0x00000000>, <0x012ac 0xc0000ccc>, diff --git a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi index 9e61f48e35037b8bac232d22bc839cef99ecc653..bb50f23d812685a02a644d0224915d48b1f4a1fe 100644 --- a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi @@ -202,3 +202,7 @@ qcom,parallel-en-pin-polarity = <1>; }; }; + +&dsi_rm67195_amoled_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-cdp.dts index d9b6a8ae9d34ba57aa57b2cbd6c7c03fd018073d..7e3e9a0cca591258081a99c7ca0e7d51182abcf4 100644 --- a/arch/arm/boot/dts/qcom/sdm630-pm660a-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-cdp.dts @@ -34,3 +34,10 @@ qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; }; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; + oledb-supply = <&pm660a_oledb>; + lab-supply = <&lab_regulator>; + ibb-supply = <&ibb_regulator>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-mtp.dts index 8ebdbc08a00c146347276c3253c20ae37969c30d..a522b7ad1d5f3bac90d96d0595a1f0a4388b04fa 100644 --- a/arch/arm/boot/dts/qcom/sdm630-pm660a-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-mtp.dts @@ -28,3 +28,10 @@ &tavil_snd { qcom,msm-mbhc-moist-cfg = <0>, <0>, <3>; }; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; + oledb-supply = <&pm660a_oledb>; + lab-supply = <&lab_regulator>; + ibb-supply = <&ibb_regulator>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi index fb24f727fb495e3eabbb2cf10a7bac8352c9b617..c24a41656f3ab4b988317fb58109683daa1eb557 100644 --- a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi @@ -22,11 +22,13 @@ #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&tlmm>; - interrupts = <21 0x0>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; interrupt_names = "smb138x"; interrupt-controller; #interrupt-cells = <3>; qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; + pinctrl-names = "default"; + pinctrl-0 = <&smb_int_default>; smb138x_revid: qcom,revid@100 { compatible = "qcom,qpnp-revid"; @@ -131,6 +133,21 @@ }; }; +&tlmm { + smb_int_default: smb_int_default { + mux { + pins = "gpio21"; + function = "gpio"; + }; + + config { + pins = "gpio21"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + / { qrd_batterydata: qcom,battery-data { qcom,batt-id-range-pct = <15>; @@ -142,6 +159,7 @@ &pm660_fg { qcom,battery-data = <&qrd_batterydata>; qcom,fg-jeita-thresholds = <0 5 55 55>; + qcom,battery-thermal-coefficients = [9d 50 ff]; }; &uartblsp1dm1 { @@ -378,3 +396,16 @@ qcom,afe-power-off-delay-us = <6>; }; }; + +&qusb_phy0 { + qcom,qusb-phy-init-seq = <0xf8 0x80 + 0x80 0x84 + 0x83 0x88 + 0xc7 0x8c + 0x30 0x08 + 0x79 0x0c + 0x21 0x10 + 0x14 0x9c + 0x9f 0x1c + 0x00 0x18>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-regulator.dtsi b/arch/arm/boot/dts/qcom/sdm630-regulator.dtsi index bcce317d34aed92b16b492afcf54e4e8451b85a2..c4adcfe1bdfb236edf7b4f5400e5d70ea6844688 100644 --- a/arch/arm/boot/dts/qcom/sdm630-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-regulator.dtsi @@ -657,6 +657,7 @@ qcom,cpr-up-error-step-limit = <1>; qcom,cpr-corner-switch-delay-time = <1042>; qcom,cpr-voltage-settling-time = <1760>; + qcom,cpr-reset-step-quot-loop-en; qcom,apm-threshold-voltage = <872000>; qcom,apm-crossover-voltage = <872000>; @@ -665,6 +666,9 @@ qcom,voltage-base = <400000>; qcom,cpr-saw-use-unit-mV; + qcom,cpr-enable; + qcom,cpr-hw-closed-loop; + qcom,cpr-panic-reg-addr-list = <0x179cbaa4 0x17912c18>; qcom,cpr-panic-reg-name-list = @@ -705,6 +709,24 @@ qcom,allow-voltage-interpolation; qcom,allow-quotient-interpolation; qcom,cpr-scaled-open-loop-voltage-as-ceiling; + + qcom,cpr-ro-scaling-factor = + <3600 3600 3830 2430 2520 2700 1790 + 1760 1970 1880 2110 2010 2510 4900 + 4370 4780>, + <3600 3600 3830 2430 2520 2700 1790 + 1760 1970 1880 2110 2010 2510 4900 + 4370 4780>, + <3600 3600 3830 2430 2520 2700 1790 + 1760 1970 1880 2110 2010 2510 4900 + 4370 4780>; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + <(-30000) (-30000) (-30000)>; + + qcom,cpr-floor-to-ceiling-max-range = + <32000 32000 32000 40000 44000 + 40000 40000 40000>; }; }; }; @@ -731,6 +753,7 @@ qcom,cpr-up-error-step-limit = <1>; qcom,cpr-corner-switch-delay-time = <1042>; qcom,cpr-voltage-settling-time = <1760>; + qcom,cpr-reset-step-quot-loop-en; qcom,apm-threshold-voltage = <872000>; qcom,apm-crossover-voltage = <872000>; @@ -739,6 +762,9 @@ qcom,voltage-base = <400000>; qcom,cpr-saw-use-unit-mV; + qcom,cpr-enable; + qcom,cpr-hw-closed-loop; + qcom,cpr-panic-reg-addr-list = <0x179c7aa4 0x17812c18>; qcom,cpr-panic-reg-name-list = @@ -834,6 +860,46 @@ qcom,allow-voltage-interpolation; qcom,allow-quotient-interpolation; qcom,cpr-scaled-open-loop-voltage-as-ceiling; + + qcom,cpr-ro-scaling-factor = + <4040 4230 0000 2210 2560 2450 2230 + 2220 2410 2300 2560 2470 1600 3120 + 2620 2280>, + <4040 4230 0000 2210 2560 2450 2230 + 2220 2410 2300 2560 2470 1600 3120 + 2620 2280>, + <4040 4230 0000 2210 2560 2450 2230 + 2220 2410 2300 2560 2470 1600 3120 + 2620 2280>, + <4040 4230 0000 2210 2560 2450 2230 + 2220 2410 2300 2560 2470 1600 3120 + 2620 2280>, + <4040 4230 0000 2210 2560 2450 2230 + 2220 2410 2300 2560 2470 1600 3120 + 2620 2280>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + <15000 5000 5000 0 0>; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + <(-30000) (-30000) (-30000) + (-30000) (-30000)>; + + qcom,cpr-floor-to-ceiling-max-range = + /* Speed bin 0 */ + <40000 40000 40000 40000 + 40000 40000 40000 66000 + 66000 40000>, + + /* Speed bin 1 */ + <40000 40000 40000 40000 + 40000 40000 40000 66000 + 66000 40000>, + + /* Speed bin 2 */ + <40000 40000 40000 40000 + 40000 40000 40000 66000 + 66000 40000 40000>; }; }; }; diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi index 0011e1d7532154dd8c9a28ad19ad69994a8527af..9897900d3fd5c94bba9680a21a0734747ca633b8 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -1323,7 +1323,7 @@ < 1670400000 0x04040057 0x08450045 0x2 6 >, < 1881600000 0x04040062 0x094e004e 0x2 7 >, < 2016000000 0x04040069 0x0a540054 0x2 8 >, - < 2150400000 0x04040070 0x0b590059 0x2 8 >, + < 2150400000 0x04040070 0x0b590059 0x2 9 >, < 2208000000 0x04040073 0x0b5c005c 0x3 10 >; qcom,perfcl-speedbin2-v0 = @@ -1988,6 +1988,7 @@ interrupts = ; qcom,ee = <0>; qcom,channel = <0>; + qcom,reserved-chan = <511>; #address-cells = <2>; #size-cells = <0>; interrupt-controller; diff --git a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi index 191beaa4d53b906657a698bdbaa2b26654f12ae5..3d37d169a97caef8dd5cdbb9bb96612d6cc1690b 100644 --- a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi @@ -29,6 +29,36 @@ qcom,switch-source = <&pm660l_switch1>; status = "ok"; }; + + cam_avdd_gpio_regulator: cam_avdd_fixed_regulator { + compatible = "regulator-fixed"; + regulator-name = "cam_avdd_gpio_regulator"; + regulator-min-microvolt = <3600000>; + regulator-max-microvolt = <3600000>; + enable-active-high; + gpio = <&tlmm 51 0>; + vin-supply = <&pm660l_bob>; + }; + + cam_dvdd_gpio_regulator: cam_dvdd_fixed_regulator { + compatible = "regulator-fixed"; + regulator-name = "cam_dvdd_gpio_regulator"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + enable-active-high; + gpio = <&pm660l_gpios 3 0>; + vin-supply = <&pm660_s5>; + }; + + cam_rear_dvdd_gpio_regulator: cam_rear_dvdd_fixed_regulator { + compatible = "regulator-fixed"; + regulator-name = "cam_rear_dvdd_gpio_regulator"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + enable-active-high; + gpio = <&pm660l_gpios 4 0>; + vin-supply = <&pm660_s5>; + }; }; &cci { @@ -98,12 +128,12 @@ reg = <0>; compatible = "qcom,eeprom"; cam_vio-supply = <&pm660_l11>; - cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_rear_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_active @@ -114,19 +144,13 @@ &cam_actuator_vaf_suspend>; gpios = <&tlmm 32 0>, <&tlmm 46 0>, - <&pm660l_gpios 4 0>, - <&tlmm 51 0>, <&tlmm 50 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-vaf = <4>; - qcom,gpio-req-tbl-num = <0 1 2 3 4>; - qcom,gpio-req-tbl-flags = <1 0 0 0 0>; + qcom,gpio-vaf = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", - "CAM_VDIG", - "CAM_VANA", "CAM_VAF"; qcom,sensor-position = <0>; qcom,sensor-mode = <0>; @@ -143,12 +167,12 @@ reg = <0x1>; compatible = "qcom,eeprom"; cam_vio-supply = <&pm660_l11>; - cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk2_active @@ -156,18 +180,12 @@ pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_rear2_suspend>; gpios = <&tlmm 34 0>, - <&tlmm 48 0>, - <&pm660l_gpios 3 0>, - <&tlmm 51 0>; + <&tlmm 48 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-req-tbl-num = <0 1 2 3>; - qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK", - "CAM_RESET", - "CAM_VDIG", - "CAM_VANA"; + "CAM_RESET"; qcom,sensor-position = <0>; qcom,sensor-mode = <0>; qcom,cci-master = <1>; @@ -184,11 +202,11 @@ compatible = "qcom,eeprom"; cam_vio-supply = <&pm660_l11>; cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vdig-supply = <&cam_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 3300000 0>; + qcom,cam-vreg-max-voltage = <1950000 3600000 0>; + qcom,cam-vreg-op-mode = <105000 80000 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_active @@ -199,18 +217,15 @@ &cam_actuator_vaf_suspend>; gpios = <&tlmm 33 0>, <&tlmm 47 0>, - <&pm660_gpios 3 0>, <&tlmm 44 0>, <&tlmm 50 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-vaf = <4>; - qcom,gpio-req-tbl-num = <0 1 2 3 4>; - qcom,gpio-req-tbl-flags = <1 0 0 0 0>; + qcom,gpio-vana = <2>; + qcom,gpio-vaf = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2", - "CAM_VDIG", "CAM_VANA", "CAM_VAF"; qcom,sensor-position = <1>; @@ -235,12 +250,12 @@ qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; cam_vio-supply = <&pm660_l11>; - cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_rear_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_active @@ -248,18 +263,12 @@ pinctrl-1 = <&cam_sensor_mclk0_suspend &cam_sensor_rear_suspend>; gpios = <&tlmm 32 0>, - <&tlmm 46 0>, - <&pm660l_gpios 4 0>, - <&tlmm 51 0>; + <&tlmm 46 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-req-tbl-num = <0 1 2 3>; - qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK0", - "CAM_RESET0", - "CAM_VDIG", - "CAM_VANA"; + "CAM_RESET0"; qcom,sensor-position = <0>; qcom,sensor-mode = <0>; qcom,cci-master = <0>; @@ -280,12 +289,12 @@ qcom,actuator-src = <&actuator1>; qcom,eeprom-src = <&eeprom1>; cam_vio-supply = <&pm660_l11>; - cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk2_active @@ -293,18 +302,12 @@ pinctrl-1 = <&cam_sensor_mclk2_suspend &cam_sensor_rear2_suspend>; gpios = <&tlmm 34 0>, - <&tlmm 48 0>, - <&pm660l_gpios 3 0>, - <&tlmm 51 0>; + <&tlmm 48 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-req-tbl-num = <0 1 2 3>; - qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK", - "CAM_RESET", - "CAM_VDIG", - "CAM_VANA"; + "CAM_RESET"; qcom,sensor-position = <0>; qcom,sensor-mode = <0>; qcom,cci-master = <1>; @@ -325,12 +328,12 @@ qcom,actuator-src = <&actuator2>; qcom,eeprom-src = <&eeprom2>; cam_vio-supply = <&pm660_l11>; - cam_vana-supply = <&pm660l_bob>; - cam_vdig-supply = <&pm660_s5>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_dvdd_gpio_regulator>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; - qcom,cam-vreg-min-voltage = <1780000 3300000 1350000>; - qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>; - qcom,cam-vreg-op-mode = <105000 80000 105000>; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_active @@ -338,18 +341,12 @@ pinctrl-1 = <&cam_sensor_mclk1_suspend &cam_sensor_front_suspend>; gpios = <&tlmm 33 0>, - <&tlmm 47 0>, - <&pm660l_gpios 3 0>, - <&tlmm 51 0>; + <&tlmm 47 0>; qcom,gpio-reset = <1>; - qcom,gpio-vdig = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-req-tbl-num = <0 1 2 3>; - qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_VDIG", - "CAM_VANA"; + "CAM_RESET2"; qcom,sensor-position = <1>; qcom,sensor-mode = <0>; qcom,cci-master = <1>; @@ -359,6 +356,45 @@ clock-names = "cam_src_clk", "cam_clk"; qcom,clock-rates = <24000000 0>; }; + + qcom,camera@3 { + cell-index = <3>; + compatible = "qcom,camera"; + reg = <0x03>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + qcom,led-flash-src = <&led_flash1>; + qcom,actuator-src = <&actuator2>; + qcom,eeprom-src = <&eeprom2>; + cam_vio-supply = <&pm660_l11>; + cam_vana-supply = <&cam_avdd_gpio_regulator>; + cam_vdig-supply = <&cam_dvdd_gpio_regulator>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <1780000 0 0>; + qcom,cam-vreg-max-voltage = <1950000 0 0>; + qcom,cam-vreg-op-mode = <105000 0 0>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk3_active + &cam_sensor_front_iris_active>; + pinctrl-1 = <&cam_sensor_mclk3_suspend + &cam_sensor_front_iris_suspend>; + gpios = <&tlmm 35 0>, + <&tlmm 52 0>; + qcom,gpio-reset = <1>; + qcom,gpio-req-tbl-num = <0 1>; + qcom,gpio-req-tbl-flags = <1 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK3", + "CAM_RESET3"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + clocks = <&clock_mmss MCLK3_CLK_SRC>, + <&clock_mmss MMSS_CAMSS_MCLK3_CLK>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; }; &pm660l_gpios { diff --git a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi index f3b81b5df1de0770a0d6e0d4fde94a4dc8748d70..8ad33a5cb68ac03a93083ceda604d352d7530124 100644 --- a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi @@ -514,7 +514,8 @@ camss-vdd-supply = <&gdsc_camss_top>; smmu-vdd-supply = <&gdsc_bimc_smmu>; qcom,vdd-names = "vdd", "camss-vdd", "smmu-vdd"; - clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + clocks = <&clock_mmss MMSS_THROTTLE_CAMSS_AXI_CLK>, + <&clock_rpmcc MMSSNOC_AXI_CLK>, <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, @@ -527,16 +528,17 @@ <&clock_mmss MMSS_CAMSS_VFE_VBIF_AHB_CLK>, <&clock_mmss MMSS_CAMSS_VFE_VBIF_AXI_CLK>, <&clock_mmss MMSS_CAMSS_CSI_VFE0_CLK>; - clock-names = "mmssnoc_axi", "mnoc_ahb_clk", - "bimc_smmu_ahb_clk", "bimc_smmu_axi_clk", - "camss_ahb_clk", "camss_top_ahb_clk", "vfe_clk_src", + clock-names = "mmss_throttle_camss_axi_clk", "mmssnoc_axi", + "mnoc_ahb_clk", "bimc_smmu_ahb_clk", + "bimc_smmu_axi_clk", "camss_ahb_clk", + "camss_top_ahb_clk", "vfe_clk_src", "camss_vfe_clk", "camss_vfe_stream_clk", "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 404000000 0 0 0 0 0 0 - 0 0 0 0 0 0 480000000 0 0 0 0 0 0 - 0 0 0 0 0 0 576000000 0 0 0 0 0 0>; + qcom,clock-rates = <0 0 0 0 0 0 0 404000000 0 0 0 0 0 0 + 0 0 0 0 0 0 0 480000000 0 0 0 0 0 0 + 0 0 0 0 0 0 0 576000000 0 0 0 0 0 0>; status = "ok"; qos-entries = <8>; qos-regs = <0x404 0x408 0x40c 0x410 0x414 0x418 @@ -595,7 +597,8 @@ camss-vdd-supply = <&gdsc_camss_top>; smmu-vdd-supply = <&gdsc_bimc_smmu>; qcom,vdd-names = "vdd", "camss-vdd", "smmu-vdd"; - clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + clocks = <&clock_mmss MMSS_THROTTLE_CAMSS_AXI_CLK>, + <&clock_rpmcc MMSSNOC_AXI_CLK>, <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, @@ -608,16 +611,17 @@ <&clock_mmss MMSS_CAMSS_VFE_VBIF_AHB_CLK>, <&clock_mmss MMSS_CAMSS_VFE_VBIF_AXI_CLK>, <&clock_mmss MMSS_CAMSS_CSI_VFE1_CLK>; - clock-names = "mmssnoc_axi", "mnoc_ahb_clk", - "bimc_smmu_ahb_clk", "bimc_smmu_axi_clk", - "camss_ahb_clk", "camss_top_ahb_clk", "vfe_clk_src", + clock-names = "mmss_throttle_camss_axi_clk", "mmssnoc_axi", + "mnoc_ahb_clk", "bimc_smmu_ahb_clk", + "bimc_smmu_axi_clk", "camss_ahb_clk", + "camss_top_ahb_clk", "vfe_clk_src", "camss_vfe_clk", "camss_vfe_stream_clk", "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 404000000 0 0 0 0 0 0 - 0 0 0 0 0 0 480000000 0 0 0 0 0 0 - 0 0 0 0 0 0 576000000 0 0 0 0 0 0>; + qcom,clock-rates = <0 0 0 0 0 0 0 404000000 0 0 0 0 0 0 + 0 0 0 0 0 0 0 480000000 0 0 0 0 0 0 + 0 0 0 0 0 0 0 576000000 0 0 0 0 0 0>; status = "ok"; qos-entries = <8>; qos-regs = <0x404 0x408 0x40c 0x410 0x414 0x418 diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi index 33303f1e2a74f3c353c90a3883e7b16b163d99aa..4d05ea75b5764e503a40b0421220b1471d86b106 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi @@ -180,6 +180,10 @@ qcom,panel-roi-alignment = <2 2 4 2 1080 2>; }; +&dsi_rm67195_amoled_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; + &mdss_dp_ctrl { pinctrl-names = "mdss_dp_active", "mdss_dp_sleep"; pinctrl-0 = <&mdss_dp_aux_active &mdss_dp_usbplug_cc_active>; diff --git a/arch/arm/boot/dts/qcom/sdm660-common.dtsi b/arch/arm/boot/dts/qcom/sdm660-common.dtsi index 33edebec2f72e389155613a37898e012b9529c27..f933586183ecf31c71250eb91ccb7e00389d104e 100644 --- a/arch/arm/boot/dts/qcom/sdm660-common.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-common.dtsi @@ -181,6 +181,7 @@ "cfg_ahb_clk", "xo"; qcom,core-clk-rate = <133330000>; + qcom,core-clk-rate-hs = <66666667>; resets = <&clock_gcc GCC_USB_30_BCR>; reset-names = "core_reset"; @@ -192,6 +193,7 @@ interrupts = <0 131 0>; usb-phy = <&qusb_phy0>, <&ssphy>; tx-fifo-resize; + snps,usb3-u1u2-disable; snps,nominal-elastic-buffer; snps,disable-clk-gating; snps,has-lpm-erratum; @@ -375,6 +377,8 @@ 0x8f8 0x77 0x00 0x4fc 0x80 0x00 0x8fc 0x80 0x00 + 0x564 0x00 0x00 + 0x964 0x00 0x00 0x4c0 0x0a 0x00 0x8c0 0x0a 0x00 0x504 0x03 0x00 diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi index 7d293f8d821c5ae0b4b6157766256f4e41290e94..19862f02aa848273632357b12d55d61ef7a8de7a 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi @@ -147,7 +147,13 @@ 23 1e 07 08 05 03 04 a0 23 18 07 08 04 03 04 a0]; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; }; &dsi_dual_nt36850_truly_cmd { @@ -195,7 +201,13 @@ 20 12 05 06 03 13 04 a0]; qcom,config-select = <&dsi_nt35597_truly_dsc_cmd_config2>; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; }; &dsi_dual_nt35597_video { @@ -229,7 +241,13 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; }; &dsi_nt35695b_truly_fhd_cmd { @@ -239,7 +257,13 @@ 24 1e 08 09 05 03 04 a0 24 1a 08 09 05 03 04 a0]; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-on-check-value = <0x9c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; }; &dsi_truly_1080_vid { @@ -253,7 +277,14 @@ qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x1c>; + qcom,mdss-dsi-panel-on-check-value = <0x1c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_truly_1080_cmd { @@ -263,7 +294,14 @@ 23 1e 08 09 05 03 04 a0 23 1a 08 09 05 03 04 a0]; qcom,esd-check-enabled; - qcom,mdss-dsi-panel-status-check-mode = "bta_check"; + qcom,mdss-dsi-panel-status-check-mode = "reg_read"; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a]; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-panel-status-value = <0x1c>; + qcom,mdss-dsi-panel-on-check-value = <0x1c>; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-max-error-count = <3>; + }; &dsi_rm67195_amoled_fhd_cmd { diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi index b263d2a68792ead2c73049d06b60a1139bc6da9e..ab4e71e3cd6579c8c66733e9d19899d16e5e981a 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi @@ -117,13 +117,14 @@ clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_MDSS_AHB_CLK>, <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MMSS_THROTTLE_MDSS_AXI_CLK>, <&clock_mmss MDP_CLK_SRC>, <&clock_mmss MMSS_MDSS_MDP_CLK>, <&clock_mmss MMSS_MDSS_VSYNC_CLK>, <&clock_mmss MDP_CLK_SRC>; clock-names = "mnoc_clk", "iface_clk", "bus_clk", - "core_clk_src", "core_clk", "vsync_clk", - "lut_clk"; + "throttle_bus_clk", "core_clk_src", + "core_clk", "vsync_clk", "lut_clk"; qcom,mdp-settings = <0x01190 0x00000000>, <0x012ac 0xc0000ccc>, @@ -505,7 +506,16 @@ qcom,msm_ext_disp = <&msm_ext_disp>; - qcom,aux-cfg-settings = [00 13 00 00 0a 28 0a 03 b7 03]; + qcom,aux-cfg0-settings = [20 00]; + qcom,aux-cfg1-settings = [24 13 23 1d]; + qcom,aux-cfg2-settings = [28 00]; + qcom,aux-cfg3-settings = [2c 00]; + qcom,aux-cfg4-settings = [30 0a]; + qcom,aux-cfg5-settings = [34 28]; + qcom,aux-cfg6-settings = [38 0a]; + qcom,aux-cfg7-settings = [3c 03]; + qcom,aux-cfg8-settings = [40 b7]; + qcom,aux-cfg9-settings = [44 03]; qcom,logical2physical-lane-map = [00 01 02 03]; qcom,phy-register-offset = <0x4>; qcom,max-pclk-frequency-khz = <300000>; diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi index ed3b3d89d3925e8c59ec4fbb245c6e39b01138c5..cb554a639d71aec0b336ab2062c856b8cab89d91 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi @@ -170,6 +170,10 @@ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; +&dsi_rm67195_amoled_fhd_cmd { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>; +}; + &sdhc_1 { /* device core power supply */ vdd-supply = <&pm660l_l4>; diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi index efe58563a1f3a94a9cf89ccaedbc858f1a9c7295..d902078b104858d3e7b8ba19d45c90da2741406b 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi @@ -1104,7 +1104,7 @@ cam_sensor_mclk0_active: cam_sensor_mclk0_active { /* MCLK0 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio32"; function = "cam_mclk"; }; @@ -1119,7 +1119,7 @@ cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend { /* MCLK0 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio32"; function = "cam_mclk"; }; @@ -1162,7 +1162,7 @@ cam_sensor_mclk1_active: cam_sensor_mclk1_active { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio33"; function = "cam_mclk"; }; @@ -1177,7 +1177,7 @@ cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio33"; function = "cam_mclk"; }; @@ -1219,7 +1219,7 @@ cam_sensor_mclk2_active: cam_sensor_mclk2_active { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio34"; function = "cam_mclk"; }; @@ -1234,7 +1234,7 @@ cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend { /* MCLK1 */ mux { - /* CLK, DATA */ + /* CLK */ pins = "gpio34"; function = "cam_mclk"; }; @@ -1274,6 +1274,64 @@ }; }; + cam_sensor_mclk3_active: cam_sensor_mclk3_active { + /* MCLK3 */ + mux { + /* CLK */ + pins = "gpio35"; + function = "cam_mclk"; + }; + + config { + pins = "gpio35"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend { + /* MCLK3 */ + mux { + /* CLK */ + pins = "gpio35"; + function = "cam_mclk"; + }; + + config { + pins = "gpio35"; + bias-pull-down; /* PULL DOWN */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front_iris_active: cam_sensor_front_iris_active { + /* RESET */ + mux { + pins = "gpio52"; + function = "gpio"; + }; + + config { + pins = "gpio52"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front_iris_suspend: cam_sensor_front_iris_suspend { + /* RESET */ + mux { + pins = "gpio52"; + function = "gpio"; + }; + + config { + pins = "gpio52"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + /* HS UART CONFIGURATION */ blsp1_uart1_active: blsp1_uart1_active { mux { diff --git a/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts index 7ca31fcc41a2fbd8c80ffa8cb472c9429bc7873d..c27f76d3027b389a9467d0e626724640fd1fb970 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts @@ -25,13 +25,19 @@ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; +&mdss_dsi { + hw-config = "single_dsi"; +}; + &mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; oledb-supply = <&pm660a_oledb>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; }; &mdss_dsi1 { + status = "disabled"; oledb-supply = <&pm660a_oledb>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; diff --git a/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts index d6e1f6a32def7e351d47ccd3f71166c0e884d69a..eb5e4999fb67a747b0e4ef55b1ce43907bbf0ba4 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts @@ -25,13 +25,19 @@ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; +&mdss_dsi { + hw-config = "single_dsi"; +}; + &mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_rm67195_amoled_fhd_cmd>; oledb-supply = <&pm660a_oledb>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; }; &mdss_dsi1 { + status = "disabled"; oledb-supply = <&pm660a_oledb>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; diff --git a/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi index 3d2cfedc1009ffcc70619d7d132c194d22c60a45..e78c2474df4d3ec05406aede67b54b4480b785f2 100644 --- a/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi @@ -119,6 +119,19 @@ }; }; +&qusb_phy0 { + qcom,qusb-phy-init-seq = <0xf8 0x80 + 0x80 0x84 + 0x83 0x88 + 0xc7 0x8c + 0x30 0x08 + 0x79 0x0c + 0x21 0x10 + 0x14 0x9c + 0x9f 0x1c + 0x00 0x18>; +}; + &pm660_gpios { /* GPIO 4 (NFC_CLK_REQ) */ gpio@c300 { @@ -230,11 +243,12 @@ &pm660_fg { qcom,battery-data = <&qrd_batterydata>; qcom,fg-jeita-thresholds = <0 5 55 55>; + qcom,battery-thermal-coefficients = [9d 50 ff]; }; &i2c_2 { status = "ok"; - smb1351-charger@1d { + smb1351_charger: smb1351-charger@1d { compatible = "qcom,smb1351-charger"; reg = <0x1d>; qcom,parallel-charger; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index be200f8dd531293f641d7b5e66f7a01ea8a8a252..2e576a51677fdc01207abdf88ff034a08be8724b 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -466,6 +466,7 @@ interrupts = ; qcom,ee = <0>; qcom,channel = <0>; + qcom,reserved-chan = <511>; #address-cells = <2>; #size-cells = <0>; interrupt-controller; diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 4dfca8fc49b3db0777e5d262c2d8eb0a3f02f6f0..1bc61ece2589376166e600eb5c7240d672f146f8 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -856,6 +856,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf801c000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(35))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(36))>; + dma-names = "tx", "rx"; clocks = <&uart0_clk>; clock-names = "usart"; status = "disabled"; @@ -865,6 +872,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf8020000 0x100>; interrupts = <25 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(37))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(38))>; + dma-names = "tx", "rx"; clocks = <&uart1_clk>; clock-names = "usart"; status = "disabled"; @@ -874,6 +888,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf8024000 0x100>; interrupts = <26 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(39))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(40))>; + dma-names = "tx", "rx"; clocks = <&uart2_clk>; clock-names = "usart"; status = "disabled"; @@ -985,6 +1006,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfc008000 0x100>; interrupts = <27 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(41))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(42))>; + dma-names = "tx", "rx"; clocks = <&uart3_clk>; clock-names = "usart"; status = "disabled"; @@ -993,6 +1021,13 @@ uart4: serial@fc00c000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfc00c000 0x100>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(43))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(44))>; + dma-names = "tx", "rx"; interrupts = <28 IRQ_TYPE_LEVEL_HIGH 7>; clocks = <&uart4_clk>; clock-names = "usart"; diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 1658cc992ee69a27011e6fa5d7ce574c701e3f8f..45aa719252d4c1d2c716fe0af9e1a888db30f8b6 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -224,7 +224,6 @@ CONFIG_ZRAM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_UID_CPUTIME=y CONFIG_MSM_ULTRASOUND=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -294,7 +293,6 @@ CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y CONFIG_POWER_SUPPLY=y -CONFIG_QPNP_SMBCHARGER=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig index 32cf48661c9bba27e7f7b5cc4c8e49cc3e1a98dd..fe6988ebbb53364037b13feaef5cc0657c2a46c7 100644 --- a/arch/arm/configs/sdm660-perf_defconfig +++ b/arch/arm/configs/sdm660-perf_defconfig @@ -3,6 +3,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y @@ -242,7 +245,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -359,6 +362,7 @@ CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_QPNP_LCDB=y CONFIG_REGULATOR_QPNP_OLEDB=y CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y @@ -526,7 +530,6 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y -CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig index c4b0eabe2fbf8a313b52a678781f256846d7ae86..3942da1a768ded02dcb1de7ec2dc800e2a2ae1e0 100644 --- a/arch/arm/configs/sdm660_defconfig +++ b/arch/arm/configs/sdm660_defconfig @@ -3,6 +3,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -241,7 +244,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -526,8 +529,6 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y -CONFIG_IOMMU_IO_PGTABLE_FAST=y -CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y @@ -635,13 +636,13 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_FREE=y CONFIG_DEBUG_OBJECTS_TIMERS=y CONFIG_DEBUG_OBJECTS_WORK=y CONFIG_DEBUG_OBJECTS_RCU_HEAD=y CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y -CONFIG_SLUB_DEBUG_ON=y CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index 679c589c48285b0f0cefbc2db1fbdea34493162e..1f7b98e1a00de2a57f40ceeac00112130a06dedf 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c @@ -369,7 +369,7 @@ static struct crypto_alg aes_algs[] = { { .cra_blkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = ce_aes_setkey, .encrypt = ecb_encrypt, .decrypt = ecb_decrypt, @@ -446,7 +446,7 @@ static struct crypto_alg aes_algs[] = { { .cra_ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = ablk_set_key, .encrypt = ablk_encrypt, .decrypt = ablk_decrypt, diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h index 4f8e9e5514b14486c8b9a6fdcc652af966bceeda..d54f8feec78f303d9a1b6641521073e34e2d9906 100644 --- a/arch/arm/include/asm/dma-contiguous.h +++ b/arch/arm/include/asm/dma-contiguous.h @@ -1,14 +1,25 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #ifndef ASMARM_DMA_CONTIGUOUS_H #define ASMARM_DMA_CONTIGUOUS_H #ifdef __KERNEL__ -#ifdef CONFIG_DMA_CMA #include void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); -#endif #endif #endif diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index 54a5aeab988d3526657b8e3089942ca8cfe4fe5e..bbbffe9461221248d051e11bd618be9f8d83d3b5 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -17,6 +17,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -39,7 +40,7 @@ static struct page **vdso_text_pagelist; /* Total number of pages needed for the data and text portions of the VDSO. */ -unsigned int vdso_total_pages __read_mostly; +unsigned int vdso_total_pages __ro_after_init; /* * The VDSO data page. @@ -47,13 +48,13 @@ unsigned int vdso_total_pages __read_mostly; static union vdso_data_store vdso_data_store __page_aligned_data; static struct vdso_data *vdso_data = &vdso_data_store.data; -static struct page *vdso_data_page; -static struct vm_special_mapping vdso_data_mapping = { +static struct page *vdso_data_page __ro_after_init; +static const struct vm_special_mapping vdso_data_mapping = { .name = "[vvar]", .pages = &vdso_data_page, }; -static struct vm_special_mapping vdso_text_mapping = { +static struct vm_special_mapping vdso_text_mapping __ro_after_init = { .name = "[vdso]", }; @@ -67,7 +68,7 @@ struct elfinfo { /* Cached result of boot-time check for whether the arch timer exists, * and if so, whether the virtual counter is useable. */ -static bool cntvct_ok __read_mostly; +static bool cntvct_ok __ro_after_init; static bool __init cntvct_functional(void) { @@ -224,7 +225,7 @@ static int install_vvar(struct mm_struct *mm, unsigned long addr) VM_READ | VM_MAYREAD, &vdso_data_mapping); - return IS_ERR(vma) ? PTR_ERR(vma) : 0; + return PTR_ERR_OR_ZERO(vma); } /* assumes mmap_sem is write-locked */ diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 767872411d97bbafddd9d4ee7c255db61a36c5c6..33ee522bb76fda7ca7a3bc839d0a28e0007ea96c 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -301,6 +301,14 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, next = kvm_pgd_addr_end(addr, end); if (!pgd_none(*pgd)) unmap_puds(kvm, pgd, addr, next); + /* + * If we are dealing with a large range in + * stage2 table, release the kvm->mmu_lock + * to prevent starvation and lockup detector + * warnings. + */ + if (kvm && (next != end)) + cond_resched_lock(&kvm->mmu_lock); } while (pgd++, addr = next, addr != end); } @@ -745,6 +753,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) */ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) { + assert_spin_locked(&kvm->mmu_lock); unmap_range(kvm, kvm->arch.pgd, start, size); } @@ -803,6 +812,7 @@ void stage2_unmap_vm(struct kvm *kvm) int idx; idx = srcu_read_lock(&kvm->srcu); + down_read(¤t->mm->mmap_sem); spin_lock(&kvm->mmu_lock); slots = kvm_memslots(kvm); @@ -810,6 +820,7 @@ void stage2_unmap_vm(struct kvm *kvm) stage2_unmap_memslot(kvm, memslot); spin_unlock(&kvm->mmu_lock); + up_read(¤t->mm->mmap_sem); srcu_read_unlock(&kvm->srcu, idx); } @@ -829,7 +840,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) if (kvm->arch.pgd == NULL) return; + spin_lock(&kvm->mmu_lock); unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); + spin_unlock(&kvm->mmu_lock); + kvm_free_hwpgd(kvm_get_hwpgd(kvm)); if (KVM_PREALLOC_LEVEL > 0) kfree(kvm->arch.pgd); @@ -1771,6 +1785,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, (KVM_PHYS_SIZE >> PAGE_SHIFT)) return -EFAULT; + down_read(¤t->mm->mmap_sem); /* * A memory region could potentially cover multiple VMAs, and any holes * between them, so iterate over all of them to find out if we can map @@ -1814,8 +1829,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, pa += vm_start - vma->vm_start; /* IO region dirty page logging not allowed */ - if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) - return -EINVAL; + if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { + ret = -EINVAL; + goto out; + } ret = kvm_phys_addr_ioremap(kvm, gpa, pa, vm_end - vm_start, @@ -1827,7 +1844,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, } while (hva < reg_end); if (change == KVM_MR_FLAGS_ONLY) - return ret; + goto out; spin_lock(&kvm->mmu_lock); if (ret) @@ -1835,6 +1852,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, else stage2_flush_memslot(kvm, memslot); spin_unlock(&kvm->mmu_lock); +out: + up_read(¤t->mm->mmap_sem); return ret; } diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 23726fb31741ea1479733ef91e88ac5585f7fe52..d687f860a2da24073837d5f916fb302d79909b6d 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -286,6 +286,22 @@ static void at91_ddr_standby(void) at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } +static void sama5d3_ddr_standby(void) +{ + u32 lpr0; + u32 saved_lpr0; + + saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); + lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; + lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN; + + at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); + + cpu_do_idle(); + + at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); +} + /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ @@ -320,7 +336,7 @@ static const struct of_device_id const ramc_ids[] __initconst = { { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, - { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, + { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby }, { /*sentinel*/ } }; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index f86692dbcfd56efce7250b3a659891ad57a45725..83fc403aec3c9aaeaafd8f7744438f631ca1a76d 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -496,8 +496,7 @@ void __init omap_init_time(void) __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon", 2, "timer_sys_ck", NULL, false); - if (of_have_populated_dt()) - clocksource_probe(); + clocksource_probe(); } #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX) @@ -505,6 +504,8 @@ void __init omap3_secure_sync32k_timer_init(void) { __omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure", 2, "timer_sys_ck", NULL, false); + + clocksource_probe(); } #endif /* CONFIG_ARCH_OMAP3 */ @@ -513,6 +514,8 @@ void __init omap3_gptimer_timer_init(void) { __omap_sync32k_timer_init(2, "timer_sys_ck", NULL, 1, "timer_sys_ck", "ti,timer-alwon", true); + + clocksource_probe(); } #endif diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 8bda55f00b7bce87030be2dae2f7cb092f3f91b6..7708d83f16acb83029affcc5dff72d0c6f8a10ba 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -672,7 +672,7 @@ static void __free_from_contiguous(struct device *dev, struct page *page, if (PageHighMem(page)) __dma_free_remap(cpu_addr, size, true); else - __dma_remap(page, size, PAGE_KERNEL, false); + __dma_remap(page, size, PAGE_KERNEL, true); dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT); } @@ -2169,6 +2169,9 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size) if (!bitmap_size) return ERR_PTR(-EINVAL); + WARN(!IS_ALIGNED(size, SZ_128M), + "size is not aligned to 128M, alignment enforced"); + if (bitmap_size > PAGE_SIZE) { extensions = bitmap_size / PAGE_SIZE; bitmap_size = PAGE_SIZE; @@ -2191,7 +2194,7 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size) mapping->nr_bitmaps = 1; mapping->extensions = extensions; mapping->base = base; - mapping->bits = bits; + mapping->bits = BITS_PER_BYTE * bitmap_size; spin_lock_init(&mapping->lock); diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 1160434eece0509c3797733b49e8fcb1262e42e7..59a8fa7b8a3bd5541e58a7a1c6e811852aad30df 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -74,5 +74,5 @@ $(MODLIB)/vdso: FORCE @mkdir -p $(MODLIB)/vdso PHONY += vdso_install -vdso_install: $(obj)/vdso.so.dbg $(MODLIB)/vdso FORCE +vdso_install: $(obj)/vdso.so.dbg $(MODLIB)/vdso $(call cmd,vdso_install) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3c89828b9af23fa4034a5d68f3d1f8b561927a9b..0c369a5d59f939dc8a7d47cbf4320411e02b1e89 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -540,6 +540,37 @@ config ARM64_64K_PAGES endchoice +config MSM_APP_API + bool "API support to enable / disable app settings for MSM8996" + depends on ARCH_MSM8996 && (ENABLE_FP_SIMD_SETTINGS || MSM_APP_SETTINGS) + help + Add API support to enable / disable the app settings to be used + at runtime. These APIs are used to enable / disable app setting + when specific aarch32 or aarch64 processes are running. + + If you are not sure what to do, select 'N' here. + +config ENABLE_FP_SIMD_SETTINGS + bool "Enable FP(Floating Point) Settings for Qualcomm MSM8996" + depends on ARCH_MSM8996 + select MSM_APP_API + help + Enable FP(Floating Point) and SIMD settings for the MSM8996 during + the execution of the aarch32 processes and disable these settings + when you switch to the aarch64 processes. + + If you are not sure what to do, select 'N' here. + +config MSM_APP_SETTINGS + bool "Support to enable / disable app settings for MSM8996" + depends on ARCH_MSM8996 + select MSM_APP_API + help + Expose an interface used by the userspace at runtime to + enable / disable the app specific settings. + + If you are not sure what to do, select 'N' here. + choice prompt "Virtual address space size" default ARM64_VA_BITS_39 if ARM64_4K_PAGES @@ -1023,6 +1054,26 @@ config BUILD_ARM64_APPENDED_DTB_IMAGE DTBs to be built by default (instead of a standalone Image.gz.) The image will built in arch/arm64/boot/Image.gz-dtb +choice + prompt "Appended DTB Kernel Image name" + depends on BUILD_ARM64_APPENDED_DTB_IMAGE + help + Enabling this option will cause a specific kernel image Image or + Image.gz to be used for final image creation. + The image will built in arch/arm64/boot/IMAGE-NAME-dtb + + config IMG_GZ_DTB + bool "Image.gz-dtb" + config IMG_DTB + bool "Image-dtb" +endchoice + +config BUILD_ARM64_APPENDED_KERNEL_IMAGE_NAME + string + depends on BUILD_ARM64_APPENDED_DTB_IMAGE + default "Image.gz-dtb" if IMG_GZ_DTB + default "Image-dtb" if IMG_DTB + config BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES string "Default dtb names" depends on BUILD_ARM64_APPENDED_DTB_IMAGE diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 2b9a966791d8a5659d14bc34a12ec765c7c16d53..441005f88761b0f9b0ec54c819d8b413306608bf 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -87,7 +87,6 @@ config DEBUG_ALIGN_RODATA config FORCE_PAGES bool "Force lowmem to be mapped with 4K pages" - depends on !DEBUG_RODATA help There are some advanced debug features that can only be done when memory is mapped with pages instead of sections. Enable this option @@ -112,6 +111,7 @@ config FREE_PAGES_RDONLY config KERNEL_TEXT_RDONLY bool "Set kernel text section pages as read only" depends on FREE_PAGES_RDONLY + depends on !DEBUG_RODATA help The kernel text pages are always mapped in the kernel. This means that anyone can write to the page if they have diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index fcfa3c7dedc178baa49aa66e92ce4cbbe9ef3710..f656c52d7e10c8622a72a97d441678652cec2a0e 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -85,7 +85,7 @@ core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a # Default target when executing plain make ifeq ($(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),y) -KBUILD_IMAGE := Image.gz-dtb +KBUILD_IMAGE := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_KERNEL_IMAGE_NAME)) else KBUILD_IMAGE := Image.gz endif @@ -132,6 +132,16 @@ archclean: $(Q)$(MAKE) $(clean)=$(boot) $(Q)$(MAKE) $(clean)=$(boot)/dts +# We need to generate vdso-offsets.h before compiling certain files in kernel/. +# In order to do that, we should use the archprepare target, but we can't since +# asm-offsets.h is included in some files used to generate vdso-offsets.h, and +# asm-offsets.h is built in prepare0, for which archprepare is a dependency. +# Therefore we need to generate the header after prepare0 has been made, hence +# this hack. +prepare: vdso_prepare +vdso_prepare: prepare0 + $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h + define archhelp echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts index 93bc3d7d51c0f32f6894e9210ef9f41df3913e0a..29315af22147b3300be711e35f39961fe5b7bb77 100644 --- a/arch/arm64/boot/dts/arm/juno-r1.dts +++ b/arch/arm64/boot/dts/arm/juno-r1.dts @@ -60,6 +60,28 @@ }; }; + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + A57_0: cpu@0 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x0 0x0>; @@ -67,6 +89,7 @@ enable-method = "psci"; next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A57_1: cpu@1 { @@ -76,6 +99,7 @@ enable-method = "psci"; next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A53_0: cpu@100 { @@ -85,6 +109,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A53_1: cpu@101 { @@ -94,6 +119,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A53_2: cpu@102 { @@ -103,6 +129,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A53_3: cpu@103 { @@ -112,6 +139,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; }; A57_L2: l2-cache0 { diff --git a/arch/arm64/boot/dts/arm/juno-sched-energy.dtsi b/arch/arm64/boot/dts/arm/juno-sched-energy.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..38207e4391ab3e24fe1d134d624b16089bfdf40d --- /dev/null +++ b/arch/arm64/boot/dts/arm/juno-sched-energy.dtsi @@ -0,0 +1,147 @@ +/* + * ARM JUNO specific energy cost model data. There are no unit requirements for + * the data. Data can be normalized to any reference point, but the + * normalization must be consistent. That is, one bogo-joule/watt must be the + * same quantity for all data, but we don't care what it is. + */ + +/* static struct idle_state idle_states_cluster_a53[] = { */ +/* { .power = 56 }, /\* arch_cpu_idle() (active idle) = WFI *\/ */ +/* { .power = 56 }, /\* WFI *\/ */ +/* { .power = 56 }, /\* cpu-sleep-0 *\/ */ +/* { .power = 17 }, /\* cluster-sleep-0 *\/ */ +/* }; */ + +/* static struct idle_state idle_states_cluster_a57[] = { */ +/* { .power = 65 }, /\* arch_cpu_idle() (active idle) = WFI *\/ */ +/* { .power = 65 }, /\* WFI *\/ */ +/* { .power = 65 }, /\* cpu-sleep-0 *\/ */ +/* { .power = 24 }, /\* cluster-sleep-0 *\/ */ +/* }; */ + +/* static struct capacity_state cap_states_cluster_a53[] = { */ +/* /\* Power per cluster *\/ */ +/* { .cap = 235, .power = 26, }, /\* 450 MHz *\/ */ +/* { .cap = 303, .power = 30, }, /\* 575 MHz *\/ */ +/* { .cap = 368, .power = 39, }, /\* 700 MHz *\/ */ +/* { .cap = 406, .power = 47, }, /\* 775 MHz *\/ */ +/* { .cap = 447, .power = 57, }, /\* 850 Mhz *\/ */ +/* }; */ + +/* static struct capacity_state cap_states_cluster_a57[] = { */ +/* /\* Power per cluster *\/ */ +/* { .cap = 417, .power = 24, }, /\* 450 MHz *\/ */ +/* { .cap = 579, .power = 32, }, /\* 625 MHz *\/ */ +/* { .cap = 744, .power = 43, }, /\* 800 MHz *\/ */ +/* { .cap = 883, .power = 49, }, /\* 950 MHz *\/ */ +/* { .cap = 1024, .power = 64, }, /\* 1100 MHz *\/ */ +/* }; */ + +/* static struct sched_group_energy energy_cluster_a53 = { */ +/* .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a53), */ +/* .idle_states = idle_states_cluster_a53, */ +/* .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a53), */ +/* .cap_states = cap_states_cluster_a53, */ +/* }; */ + +/* static struct sched_group_energy energy_cluster_a57 = { */ +/* .nr_idle_states = ARRAY_SIZE(idle_states_cluster_a57), */ +/* .idle_states = idle_states_cluster_a57, */ +/* .nr_cap_states = ARRAY_SIZE(cap_states_cluster_a57), */ +/* .cap_states = cap_states_cluster_a57, */ +/* }; */ + +/* static struct idle_state idle_states_core_a53[] = { */ +/* { .power = 6 }, /\* arch_cpu_idle() (active idle) = WFI *\/ */ +/* { .power = 6 }, /\* WFI *\/ */ +/* { .power = 0 }, /\* cpu-sleep-0 *\/ */ +/* { .power = 0 }, /\* cluster-sleep-0 *\/ */ +/* }; */ + +/* static struct idle_state idle_states_core_a57[] = { */ +/* { .power = 15 }, /\* arch_cpu_idle() (active idle) = WFI *\/ */ +/* { .power = 15 }, /\* WFI *\/ */ +/* { .power = 0 }, /\* cpu-sleep-0 *\/ */ +/* { .power = 0 }, /\* cluster-sleep-0 *\/ */ +/* }; */ + +/* static struct capacity_state cap_states_core_a53[] = { */ +/* /\* Power per cpu *\/ */ +/* { .cap = 235, .power = 33, }, /\* 450 MHz *\/ */ +/* { .cap = 302, .power = 46, }, /\* 575 MHz *\/ */ +/* { .cap = 368, .power = 61, }, /\* 700 MHz *\/ */ +/* { .cap = 406, .power = 76, }, /\* 775 MHz *\/ */ +/* { .cap = 447, .power = 93, }, /\* 850 Mhz *\/ */ +/* }; */ + +/* static struct capacity_state cap_states_core_a57[] = { */ +/* /\* Power per cpu *\/ */ +/* { .cap = 417, .power = 168, }, /\* 450 MHz *\/ */ +/* { .cap = 579, .power = 251, }, /\* 625 MHz *\/ */ +/* { .cap = 744, .power = 359, }, /\* 800 MHz *\/ */ +/* { .cap = 883, .power = 479, }, /\* 950 MHz *\/ */ +/* { .cap = 1024, .power = 616, }, /\* 1100 MHz *\/ */ +/* }; */ + +energy-costs { + CPU_COST_A57: core-cost0 { + busy-cost-data = < + 417 168 + 579 251 + 744 359 + 883 479 + 1023 616 + >; + idle-cost-data = < + 15 + 15 + 0 + 0 + >; + }; + CPU_COST_A53: core-cost1 { + busy-cost-data = < + 235 33 + 302 46 + 368 61 + 406 76 + 447 93 + >; + idle-cost-data = < + 6 + 6 + 0 + 0 + >; + }; + CLUSTER_COST_A57: cluster-cost0 { + busy-cost-data = < + 417 24 + 579 32 + 744 43 + 883 49 + 1024 64 + >; + idle-cost-data = < + 65 + 65 + 65 + 24 + >; + }; + CLUSTER_COST_A53: cluster-cost1 { + busy-cost-data = < + 235 26 + 303 30 + 368 39 + 406 47 + 447 57 + >; + idle-cost-data = < + 56 + 56 + 56 + 17 + >; + }; +}; diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index 3e1a84b01b500807fea638858ebb2c879a5dae94..68816f71fa5124755c656b68e17b7f304a34d2c2 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -60,6 +60,28 @@ }; }; + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <400>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + A57_0: cpu@0 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x0 0x0>; @@ -67,6 +89,8 @@ enable-method = "psci"; next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A57 &CLUSTER_COST_A57>; }; A57_1: cpu@1 { @@ -76,6 +100,8 @@ enable-method = "psci"; next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A57 &CLUSTER_COST_A57>; }; A53_0: cpu@100 { @@ -85,6 +111,8 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A53 &CLUSTER_COST_A53>; }; A53_1: cpu@101 { @@ -94,6 +122,8 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A53 &CLUSTER_COST_A53>; }; A53_2: cpu@102 { @@ -103,6 +133,8 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A53 &CLUSTER_COST_A53>; }; A53_3: cpu@103 { @@ -112,6 +144,8 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + sched-energy-costs = <&CPU_COST_A53 &CLUSTER_COST_A53>; }; A57_L2: l2-cache0 { @@ -121,6 +155,8 @@ A53_L2: l2-cache1 { compatible = "cache"; }; + + /include/ "juno-sched-energy.dtsi" }; pmu_a57 { diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..eb1ebee6c2a047b26ed5c9e120f974e5a34880cf --- /dev/null +++ b/arch/arm64/configs/msm-auto-perf_defconfig @@ -0,0 +1,634 @@ +CONFIG_LOCALVERSION="-perf" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_CPU_MAX_BUF_SHIFT=15 +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_HMP=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_MEMBARRIER is not set +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_MSM8996=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_ENABLE_FP_SIMD_SETTINGS=y +CONFIG_MSM_APP_SETTINGS=y +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT=y +CONFIG_HZ_100=y +CONFIG_CMA=y +CONFIG_ZSMALLOC=y +CONFIG_BALANCE_ANON_FILE_RECLAIM=y +CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y +CONFIG_SECCOMP=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +# CONFIG_EFI is not set +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_BOOST=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_L2TP=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_MULTIQ=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_ACT_MIRRED=y +CONFIG_NET_ACT_SKBEDIT=y +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_SOCKEV_NLMCAST=y +CONFIG_CAN=y +CONFIG_CAN_RH850=y +CONFIG_BT=y +CONFIG_MSM_BT_POWER=y +CONFIG_BTFM_SLIM=y +CONFIG_BTFM_SLIM_WCN3990=y +CONFIG_CFG80211=y +CONFIG_RFKILL=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_DMA_CMA=y +# CONFIG_PNP_DEBUG_MESSAGES is not set +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_HDCP_QSEECOM=y +CONFIG_PROFILER=y +CONFIG_UID_SYS_STATS=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_BONDING=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_E1000E=y +CONFIG_MSM_RMNET_MHI=y +CONFIG_RNDIS_IPA=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_MPPE=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_USB_USBNET=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CNSS_CRYPTO=y +CONFIG_ATH_CARDS=y +CONFIG_WIL6210=m +CONFIG_CNSS=y +CONFIG_CNSS_ASYNC=y +CONFIG_CLD_LL_CORE=y +CONFIG_BUS_AUTO_SUSPEND=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS=y +CONFIG_SECURE_TOUCH=y +CONFIG_TOUCHSCREEN_GEN_VKEYS=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_SMD=y +CONFIG_DIAG_CHAR=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_MSM_ADSPRPC=y +CONFIG_MSM_RDBG=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_QUP=y +CONFIG_I2C_MSM_V2=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_SOUNDWIRE=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_PINCTRL_MSM8996=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_SMB135X_CHARGER=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y +CONFIG_SENSORS_EPM_ADC=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_TSENS8974=y +CONFIG_THERMAL_QPNP_ADC_TM=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_WCD9335_CODEC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_ONSEMI_NCP6335D=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR3_HMSS=y +CONFIG_REGULATOR_CPR3_MMSS=y +CONFIG_REGULATOR_KRYO=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_PROXY_CONSUMER=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_MSM_CAMERA=y +CONFIG_MSM_CAMERA_DEBUG=y +CONFIG_MSMB_CAMERA=y +CONFIG_MSMB_CAMERA_DEBUG=y +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI20_HEADER=y +CONFIG_MSM_CSI22_HEADER=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSI31_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +CONFIG_IMX134=y +CONFIG_IMX132=y +CONFIG_OV9724=y +CONFIG_OV5648=y +CONFIG_GC0339=y +CONFIG_OV8825=y +CONFIG_OV8865=y +CONFIG_s5k4e1=y +CONFIG_OV12830=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_JPEGDMA=y +CONFIG_MSM_VIDC_V4L2=y +CONFIG_MSM_VIDC_VMEM=y +CONFIG_MSM_VIDC_GOVERNORS=y +CONFIG_MSM_SDE_ROTATOR=y +CONFIG_QCOM_KGSL=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=m +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_MSM8996=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_ISP1760=y +CONFIG_USB_QTI_KS_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_QCRNDIS=y +CONFIG_USB_CONFIGFS_RMNET_BAM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_USB_CONFIGFS_F_CDEV=y +CONFIG_USB_CONFIGFS_F_QDSS=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_CQ_HCI=y +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH_V2=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_SWITCH=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_ESOC=y +CONFIG_ESOC_DEV=y +CONFIG_ESOC_CLIENT=y +CONFIG_ESOC_MDM_4x=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_BAM_DMA=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_UIO_MSM_SHAREDMEM=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_SW_SYNC_USER=y +CONFIG_ION=y +CONFIG_ION_MSM=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +CONFIG_GSI=y +CONFIG_IPA3=y +CONFIG_RMNET_IPA3=y +CONFIG_IPA_UT=y +CONFIG_GPIO_USB_DETECT=y +CONFIG_MSM_MHI=y +CONFIG_MSM_MHI_UCI=y +CONFIG_SEEMP_CORE=y +CONFIG_USB_BAM=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_IOMMU_IO_PGTABLE_FAST=y +CONFIG_ARM_SMMU=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_TESTS=y +CONFIG_MSM_SMEM=y +CONFIG_QPNP_HAPTIC=y +CONFIG_MSM_SMD=y +CONFIG_MSM_GLINK=y +CONFIG_MSM_GLINK_LOOPBACK_SERVER=y +CONFIG_MSM_GLINK_SMD_XPRT=y +CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_SYSMON_GLINK_COMM=y +CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y +CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y +CONFIG_MSM_GLINK_PKT=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_SCM_XPU=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_BOOT_TIME_MARKER=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_TRACER_PKT=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_MSM_MPM_OF=y +CONFIG_MSM_EVENT_TIMER=y +CONFIG_MSM_AVTIMER=y +CONFIG_QCOM_REMOTEQDSS=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_CACHE_M4M_ERP64=y +CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_CE=y +CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_UE=y +CONFIG_MEM_SHARE_QMI_SERVICE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_QCOM_M4M_HWMON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_DEVFREQ_SIMPLE_DEV=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON=y +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +CONFIG_ARM_GIC_V3_ACL=y +CONFIG_PHY_XGENE=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_SENSORS_SSC=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y +CONFIG_EXT4_FS_ICE_ENCRYPTION=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_IPC_LOGGING=y +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_QCOM_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_QPDI=y +CONFIG_CORESIGHT_SOURCE_DUMMY=y +CONFIG_PFK=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SMACK=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_OTA_CRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_CRC32_ARM64=y +CONFIG_QMI_ENCDEC=y diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..1981b97309a25c30bf1f1e4ce2cab7ecaba99e82 --- /dev/null +++ b/arch/arm64/configs/msm-auto_defconfig @@ -0,0 +1,678 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_CPU_MAX_BUF_SHIFT=15 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_HMP=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_MEMBARRIER is not set +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_MSM8996=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_ENABLE_FP_SIMD_SETTINGS=y +CONFIG_MSM_APP_SETTINGS=y +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT=y +CONFIG_HZ_100=y +CONFIG_CMA=y +CONFIG_CMA_DEBUGFS=y +CONFIG_ZSMALLOC=y +CONFIG_BALANCE_ANON_FILE_RECLAIM=y +CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y +CONFIG_SECCOMP=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CMDLINE="console=ttyAMA0" +# CONFIG_EFI is not set +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_DEBUG=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_BOOST=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_MULTIQ=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_ACT_MIRRED=y +CONFIG_NET_ACT_SKBEDIT=y +CONFIG_DNS_RESOLVER=y +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_SOCKEV_NLMCAST=y +CONFIG_CAN=y +CONFIG_CAN_RH850=y +CONFIG_BT=y +CONFIG_MSM_BT_POWER=y +CONFIG_BTFM_SLIM=y +CONFIG_BTFM_SLIM_WCN3990=y +CONFIG_CFG80211=y +CONFIG_RFKILL=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_DMA_CMA=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_HDCP_QSEECOM=y +CONFIG_PROFILER=y +CONFIG_UID_SYS_STATS=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_BONDING=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_E1000E=y +CONFIG_MSM_RMNET_MHI=y +CONFIG_RNDIS_IPA=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_MPPE=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_USB_USBNET=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_CNSS_CRYPTO=y +CONFIG_ATH_CARDS=y +CONFIG_WIL6210=m +CONFIG_CNSS=y +CONFIG_CNSS_ASYNC=y +CONFIG_CLD_LL_CORE=y +CONFIG_BUS_AUTO_SUSPEND=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS=y +CONFIG_SECURE_TOUCH=y +CONFIG_TOUCHSCREEN_GEN_VKEYS=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_SMD=y +CONFIG_DIAG_CHAR=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_MSM_ADSPRPC=y +CONFIG_MSM_RDBG=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_QUP=y +CONFIG_I2C_MSM_V2=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_SOUNDWIRE=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_PINCTRL_MSM8996=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_SMB135X_CHARGER=y +CONFIG_SMB1351_USB_CHARGER=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y +CONFIG_SENSORS_EPM_ADC=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_TSENS8974=y +CONFIG_THERMAL_QPNP_ADC_TM=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_WCD9335_CODEC=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_ONSEMI_NCP6335D=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR3_HMSS=y +CONFIG_REGULATOR_CPR3_MMSS=y +CONFIG_REGULATOR_KRYO=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_PROXY_CONSUMER=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_MSM_CAMERA=y +CONFIG_MSM_CAMERA_DEBUG=y +CONFIG_MSMB_CAMERA=y +CONFIG_MSMB_CAMERA_DEBUG=y +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI20_HEADER=y +CONFIG_MSM_CSI22_HEADER=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSI31_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +CONFIG_IMX134=y +CONFIG_IMX132=y +CONFIG_OV9724=y +CONFIG_OV5648=y +CONFIG_GC0339=y +CONFIG_OV8825=y +CONFIG_OV8865=y +CONFIG_s5k4e1=y +CONFIG_OV12830=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_JPEGDMA=y +CONFIG_MSM_VIDC_V4L2=y +CONFIG_MSM_VIDC_VMEM=y +CONFIG_MSM_VIDC_GOVERNORS=y +CONFIG_MSM_SDE_ROTATOR=y +CONFIG_QCOM_KGSL=y +CONFIG_FB=y +CONFIG_FB_MSM=y +CONFIG_FB_MSM_MDSS=y +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=m +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_MSM8996=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_ISP1760=y +CONFIG_USB_QTI_KS_BRIDGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_QCRNDIS=y +CONFIG_USB_CONFIGFS_RMNET_BAM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_USB_CONFIGFS_F_CDEV=y +CONFIG_USB_CONFIGFS_F_QDSS=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_PARANOID_SD_INIT=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_CQ_HCI=y +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH_V2=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_SWITCH=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_ESOC=y +CONFIG_ESOC_DEV=y +CONFIG_ESOC_CLIENT=y +CONFIG_ESOC_DEBUG=y +CONFIG_ESOC_MDM_4x=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_BAM_DMA=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_UIO_MSM_SHAREDMEM=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_SW_SYNC_USER=y +CONFIG_ION=y +CONFIG_ION_MSM=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +CONFIG_GSI=y +CONFIG_IPA3=y +CONFIG_RMNET_IPA3=y +CONFIG_IPA_UT=y +CONFIG_GPIO_USB_DETECT=y +CONFIG_MSM_MHI=y +CONFIG_MSM_MHI_UCI=y +CONFIG_MSM_MHI_DEBUG=y +CONFIG_SEEMP_CORE=y +CONFIG_USB_BAM=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_IOMMU_IO_PGTABLE_FAST=y +CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y +CONFIG_ARM_SMMU=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_IOMMU_TESTS=y +CONFIG_MSM_SMEM=y +CONFIG_QPNP_HAPTIC=y +CONFIG_MSM_SMD=y +CONFIG_MSM_SMD_DEBUG=y +CONFIG_MSM_GLINK=y +CONFIG_MSM_GLINK_LOOPBACK_SERVER=y +CONFIG_MSM_GLINK_SMD_XPRT=y +CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_SYSMON_GLINK_COMM=y +CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y +CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y +CONFIG_MSM_GLINK_PKT=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_QCOM_SCM=y +CONFIG_QCOM_SCM_XPU=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_BOOT_TIME_MARKER=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_TRACER_PKT=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_MSM_MPM_OF=y +CONFIG_MSM_EVENT_TIMER=y +CONFIG_MSM_AVTIMER=y +CONFIG_QCOM_REMOTEQDSS=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_MSM_CACHE_M4M_ERP64=y +CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_CE=y +CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_UE=y +CONFIG_MEM_SHARE_QMI_SERVICE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_QCOM_M4M_HWMON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_QCOM_CACHE_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_DEVFREQ_SIMPLE_DEV=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_EXTCON=y +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +CONFIG_ARM_GIC_V3_ACL=y +CONFIG_PHY_XGENE=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_MSM_TZ_LOG=y +CONFIG_SENSORS_SSC=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y +CONFIG_EXT4_FS_ICE_ENCRYPTION=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_PAGE_OWNER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_PANIC_TIMEOUT=5 +CONFIG_PANIC_ON_SCHED_BUG=y +CONFIG_PANIC_ON_RT_THROTTLING=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_LIST=y +CONFIG_FAULT_INJECTION=y +CONFIG_FAIL_PAGE_ALLOC=y +CONFIG_UFS_FAULT_INJECTION=y +CONFIG_FAULT_INJECTION_DEBUG_FS=y +CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y +CONFIG_IPC_LOGGING=y +CONFIG_QCOM_RTB=y +CONFIG_QCOM_RTB_SEPARATE_CPUS=y +CONFIG_IRQSOFF_TRACER=y +CONFIG_PREEMPT_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +CONFIG_PANIC_ON_DATA_CORRUPTION=y +CONFIG_ARM64_PTDUMP=y +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_FREE_PAGES_RDONLY=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_SOURCE_ETM4X=y +CONFIG_CORESIGHT_REMOTE_ETM=y +CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 +CONFIG_CORESIGHT_QCOM_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_QPDI=y +CONFIG_CORESIGHT_SOURCE_DUMMY=y +CONFIG_PFK=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SMACK=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_OTA_CRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_CRC32_ARM64=y +CONFIG_XZ_DEC=y +CONFIG_QMI_ENCDEC=y diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 0031c55360c78f6db6882f58dfd8db35f23b9ec8..3cd68ecf863431dd906c212e923c1148cde06ae9 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -5,6 +5,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y @@ -236,7 +239,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y @@ -516,6 +519,7 @@ CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y CONFIG_MSM_GLINK_PKT=y CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_SCM_XPU=y CONFIG_QCOM_WATCHDOG_V2=y @@ -530,7 +534,9 @@ CONFIG_MSM_PIL_SSR_GENERIC=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_MSM_MPM_OF=y +CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_AVTIMER=y +CONFIG_MSM_QBT1000=y CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y CONFIG_MSM_RPM_LOG=y CONFIG_MSM_RPM_STATS_LOG=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 261a49d7944a82d366748ae96bd43933f92198d1..5c4b307b1887abb20436f2ffbbf3034b37bcc1d0 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -4,6 +4,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -228,7 +231,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y @@ -517,6 +520,7 @@ CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y CONFIG_MSM_GLINK_PKT=y CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y CONFIG_QCOM_SCM=y CONFIG_QCOM_SCM_XPU=y CONFIG_QCOM_WATCHDOG_V2=y @@ -532,9 +536,11 @@ CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y CONFIG_MSM_MPM_OF=y +CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_AVTIMER=y CONFIG_QCOM_REMOTEQDSS=y CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_QBT1000=y CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y CONFIG_MSM_RPM_LOG=y CONFIG_MSM_RPM_STATS_LOG=y @@ -616,7 +622,6 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_ARM64_PTDUMP=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_FREE_PAGES_RDONLY=y -CONFIG_KERNEL_TEXT_RDONLY=y CONFIG_PFK=y CONFIG_SECURITY=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 4b0918e2136da0ab61e05a5ca6e768fd1981f458..778dcfecaf1c992b4d029af512fd68014b012f0d 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -5,8 +5,13 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_ALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_CPU_MAX_BUF_SHIFT=17 @@ -60,12 +65,12 @@ CONFIG_CMA=y CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_BALANCE_ANON_FILE_RECLAIM=y -CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y CONFIG_SECCOMP=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_RANDOMIZE_BASE=y # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set # CONFIG_EFI is not set @@ -186,6 +191,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_IPTABLES_128=y CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y @@ -240,7 +246,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -268,6 +274,7 @@ CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y CONFIG_SKY2=y +CONFIG_MSM_RMNET_MHI=y CONFIG_RNDIS_IPA=y CONFIG_SMSC911X=y CONFIG_PPP=y @@ -513,6 +520,8 @@ CONFIG_GSI=y CONFIG_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_GPIO_USB_DETECT=y +CONFIG_MSM_MHI=y +CONFIG_MSM_MHI_UCI=y CONFIG_SEEMP_CORE=y CONFIG_USB_BAM=y CONFIG_MSM_MDSS_PLL=y @@ -565,6 +574,7 @@ CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_AVTIMER=y CONFIG_QCOM_REMOTEQDSS=y CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_QBT1000=y CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y CONFIG_MSM_RPM_LOG=y CONFIG_MSM_RPM_STATS_LOG=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 031923e1db0b8faf11fa40b5f02e8aa7e5fecede..743f76c8ac3fdaf47ca19a085aef3aef4e757799 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -4,8 +4,13 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_ALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_CPU_MAX_BUF_SHIFT=17 @@ -66,6 +71,7 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y CONFIG_RANDOMIZE_BASE=y CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set @@ -186,6 +192,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_IPTABLES_128=y CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y @@ -243,7 +250,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -256,6 +263,7 @@ CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_QCOM=y CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_SCSI_UFSHCD_CMD_LOGGING=y CONFIG_MD=y CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=y @@ -270,6 +278,7 @@ CONFIG_NETDEVICES=y CONFIG_BONDING=y CONFIG_DUMMY=y CONFIG_TUN=y +CONFIG_MSM_RMNET_MHI=y CONFIG_RNDIS_IPA=y CONFIG_PPP=y CONFIG_PPP_BSDCOMP=y @@ -525,6 +534,9 @@ CONFIG_GSI=y CONFIG_IPA3=y CONFIG_RMNET_IPA3=y CONFIG_GPIO_USB_DETECT=y +CONFIG_MSM_MHI=y +CONFIG_MSM_MHI_UCI=y +CONFIG_MSM_MHI_DEBUG=y CONFIG_SEEMP_CORE=y CONFIG_USB_BAM=y CONFIG_MSM_MDSS_PLL=y @@ -586,6 +598,7 @@ CONFIG_MSM_EVENT_TIMER=y CONFIG_MSM_AVTIMER=y CONFIG_QCOM_REMOTEQDSS=y CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_QBT1000=y CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y CONFIG_MSM_RPM_LOG=y CONFIG_MSM_RPM_STATS_LOG=y @@ -638,6 +651,8 @@ CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_FREE=y CONFIG_DEBUG_OBJECTS_TIMERS=y diff --git a/arch/arm64/configs/msmcortex_mediabox-perf_defconfig b/arch/arm64/configs/msmcortex_mediabox-perf_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..cb0a5977c167e5f28164a9c16d141cf755b56e67 --- /dev/null +++ b/arch/arm64/configs/msmcortex_mediabox-perf_defconfig @@ -0,0 +1,642 @@ +CONFIG_LOCALVERSION="-perf" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_RCU_EXPERT=y +CONFIG_RCU_FAST_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_CPU_MAX_BUF_SHIFT=17 +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_SCHEDTUNE=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_HMP=y +CONFIG_SCHED_HMP_CSTATE_AWARE=y +CONFIG_SCHED_CORE_CTL=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_SCHED_AUTOGROUP=y +CONFIG_SCHED_TUNE=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_AIO is not set +# CONFIG_MEMBARRIER is not set +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_SHA512=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_MSM8998=y +CONFIG_ARCH_MSMHAMSTER=y +CONFIG_PCI=y +CONFIG_PCI_MSM=y +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=8 +CONFIG_QCOM_TLB_EL2_HANDLER=y +CONFIG_PREEMPT=y +CONFIG_HZ_100=y +CONFIG_ARM64_REG_REBALANCE_ON_CTX_SW=y +CONFIG_CMA=y +CONFIG_CMA_DEBUGFS=y +CONFIG_ZSMALLOC=y +CONFIG_BALANCE_ANON_FILE_RECLAIM=y +CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y +CONFIG_SECCOMP=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +CONFIG_RANDOMIZE_BASE=y +# CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set +# CONFIG_EFI is not set +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COMPAT=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_BOOST=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_DIAG_DESTROY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_RPFILTER=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +CONFIG_L2TP=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NET_SCH_PRIO=y +CONFIG_NET_SCH_MULTIQ=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_FLOW=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_ACT_MIRRED=y +CONFIG_NET_ACT_SKBEDIT=y +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_SOCKEV_NLMCAST=y +CONFIG_BT=y +CONFIG_MSM_BT_POWER=y +CONFIG_BTFM_SLIM=y +CONFIG_BTFM_SLIM_WCN3990=y +CONFIG_CFG80211=y +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_RFKILL=y +CONFIG_NFC_NQ=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_DMA_CMA=y +# CONFIG_PNP_DEBUG_MESSAGES is not set +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_QSEECOM=y +CONFIG_HDCP_QSEECOM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_FEC=y +CONFIG_DM_ANDROID_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_BONDING=y +CONFIG_DUMMY=y +CONFIG_TUN=y +CONFIG_SKY2=y +CONFIG_RNDIS_IPA=y +CONFIG_SMSC911X=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_MPPE=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_USB_USBNET=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +CONFIG_ATH_CARDS=y +CONFIG_WIL6210=m +CONFIG_ATH10K=m +CONFIG_ATH10K_TARGET_SNOC=m +CONFIG_ATH10K_SNOC=y +CONFIG_CLD_LL_CORE=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_KEYRESET=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y +CONFIG_SECURE_TOUCH=y +CONFIG_TOUCHSCREEN_ST=y +CONFIG_TOUCHSCREEN_ST_I2C=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_HBTP_INPUT=y +CONFIG_INPUT_QPNP_POWER_ON=y +CONFIG_INPUT_UINPUT=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_MSM_HS=y +CONFIG_SERIAL_MSM_SMD=y +CONFIG_DIAG_CHAR=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM_LEGACY=y +CONFIG_MSM_ADSPRPC=y +CONFIG_MSM_RDBG=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MSM_V2=y +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_SOUNDWIRE=y +CONFIG_SPI=y +CONFIG_SPI_QUP=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y +CONFIG_PINCTRL_MSM8998=y +CONFIG_PINCTRL_SDM660=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_RESET_QCOM=y +CONFIG_QCOM_DLOAD_MODE=y +CONFIG_POWER_RESET_XGENE=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_QPNP_FG_GEN3=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_BATTERY_BCL=y +CONFIG_QPNP_SMB2=y +CONFIG_SMB138X_CHARGER=y +CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_CPU_THERMAL=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_TSENS8974=y +CONFIG_THERMAL_QPNP=y +CONFIG_THERMAL_QPNP_ADC_TM=y +CONFIG_QCOM_THERMAL_LIMITS_DCVS=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_MFD_I2C_PMIC=y +CONFIG_WCD9335_CODEC=y +CONFIG_WCD934X_CODEC=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_QPNP_LCDB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR3_HMSS=y +CONFIG_REGULATOR_CPR3_MMSS=y +CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_MEM_ACC=y +CONFIG_REGULATOR_PROXY_CONSUMER=y +CONFIG_REGULATOR_STUB=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_ADV_DEBUG=y +CONFIG_VIDEO_FIXED_MINOR_RANGES=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_MSM_CAMERA=y +CONFIG_MSM_CAMERA_DEBUG=y +CONFIG_MSMB_CAMERA=y +CONFIG_MSMB_CAMERA_DEBUG=y +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI20_HEADER=y +CONFIG_MSM_CSI22_HEADER=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSI31_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +CONFIG_IMX134=y +CONFIG_IMX132=y +CONFIG_OV9724=y +CONFIG_OV5648=y +CONFIG_GC0339=y +CONFIG_OV8825=y +CONFIG_OV8865=y +CONFIG_s5k4e1=y +CONFIG_OV12830=y +CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +CONFIG_MSM_JPEGDMA=y +CONFIG_MSM_VIDC_V4L2=y +CONFIG_MSM_VIDC_VMEM=y +CONFIG_MSM_VIDC_GOVERNORS=y +CONFIG_MSM_SDE_ROTATOR=y +CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y +CONFIG_DVB_MPQ=m +CONFIG_DVB_MPQ_DEMUX=m +CONFIG_DVB_MPQ_MEDIA_BOX_DEMUX=y +CONFIG_TSPP=m +CONFIG_DRM=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_AUDIO_QMI=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_MSM8998=y +CONFIG_UHID=y +CONFIG_HID_APPLE=y +CONFIG_HID_ELECOM=y +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_PLANTRONICS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_ISP1760=y +CONFIG_USB_ISP1760_HOST_ROLE=y +CONFIG_USB_PD_POLICY=y +CONFIG_QPNP_USB_PDPHY=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_USB_OTG_WAKELOCK=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_DIAG=y +CONFIG_USB_CONFIGFS_F_GSI=y +CONFIG_USB_CONFIGFS_F_CDEV=y +CONFIG_USB_CONFIGFS_F_QDSS=y +CONFIG_USB_CONFIGFS_F_CCID=y +CONFIG_MMC=y +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH_V2=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_SYSCON=y +CONFIG_SWITCH=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_QPNP=y +CONFIG_ESOC=y +CONFIG_ESOC_DEV=y +CONFIG_ESOC_CLIENT=y +CONFIG_ESOC_MDM_4x=y +CONFIG_ESOC_MDM_DRV=y +CONFIG_DMADEVICES=y +CONFIG_QCOM_SPS_DMA=y +CONFIG_UIO=y +CONFIG_UIO_MSM_SHAREDMEM=y +CONFIG_STAGING=y +CONFIG_ASHMEM=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ION=y +CONFIG_ION_MSM=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_SPS=y +CONFIG_SPS_SUPPORT_NDP_BAM=y +CONFIG_IPA=y +CONFIG_RMNET_IPA=y +CONFIG_GSI=y +CONFIG_IPA3=y +CONFIG_RMNET_IPA3=y +CONFIG_GPIO_USB_DETECT=y +CONFIG_SEEMP_CORE=y +CONFIG_USB_BAM=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y +CONFIG_IOMMU_IO_PGTABLE_FAST=y +CONFIG_ARM_SMMU=y +CONFIG_IOMMU_DEBUG=y +CONFIG_IOMMU_DEBUG_TRACKING=y +CONFIG_IOMMU_TESTS=y +CONFIG_MSM_SMEM=y +CONFIG_QPNP_HAPTIC=y +CONFIG_MSM_SMD=y +CONFIG_MSM_GLINK=y +CONFIG_MSM_GLINK_LOOPBACK_SERVER=y +CONFIG_MSM_GLINK_SMD_XPRT=y +CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_GLINK_SPI_XPRT=y +CONFIG_MSM_SPCOM=y +CONFIG_MSM_SPSS_UTILS=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_QMI_INTERFACE=y +CONFIG_MSM_RPM_SMD=y +CONFIG_QCOM_BUS_SCALING=y +CONFIG_MSM_SERVICE_LOCATOR=y +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_SYSMON_GLINK_COMM=y +CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y +CONFIG_MSM_GLINK_PKT=y +CONFIG_MSM_SPM=y +CONFIG_QCOM_WATCHDOG_V2=y +CONFIG_QCOM_IRQ_HELPER=y +CONFIG_QCOM_MEMORY_DUMP_V2=y +CONFIG_ICNSS=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_BOOT_STATS=y +CONFIG_MSM_ADSP_LOADER=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +CONFIG_TRACER_PKT=y +CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y +CONFIG_MSM_MPM_OF=y +CONFIG_MSM_EVENT_TIMER=y +CONFIG_MSM_AVTIMER=y +CONFIG_QCOM_REMOTEQDSS=y +CONFIG_MSM_SERVICE_NOTIFIER=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_QSEE_IPC_IRQ_BRIDGE=y +CONFIG_QCOM_SMCINVOKE=y +CONFIG_QCOM_EARLY_RANDOM=y +CONFIG_MEM_SHARE_QMI_SERVICE=y +CONFIG_QCOM_BIMC_BWMON=y +CONFIG_ARM_MEMLAT_MON=y +CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MEMLAT=y +CONFIG_QCOM_DEVFREQ_DEVBW=y +CONFIG_SPDM_SCM=y +CONFIG_DEVFREQ_SPDM=y +CONFIG_EXTCON=y +CONFIG_IIO=y +CONFIG_QCOM_RRADC=y +CONFIG_QCOM_TADC=y +CONFIG_PWM=y +CONFIG_PWM_QPNP=y +CONFIG_ARM_GIC_V3_ACL=y +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder" +CONFIG_MSM_TZ_LOG=y +CONFIG_SENSORS_SSC=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_EXT4_FS_ENCRYPTION=y +CONFIG_EXT4_FS_ICE_ENCRYPTION=y +CONFIG_FUSE_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_IPC_LOGGING=y +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +CONFIG_CORESIGHT_QCOM_REPLICATOR=y +CONFIG_CORESIGHT_STM=y +CONFIG_CORESIGHT_HWEVENT=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_TPDA=y +CONFIG_CORESIGHT_TPDM=y +CONFIG_CORESIGHT_QPDI=y +CONFIG_CORESIGHT_SOURCE_DUMMY=y +CONFIG_PFK=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SMACK=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_OTA_CRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +CONFIG_SYSTEM_TRUSTED_KEYS="verity.x509.pem" +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_CRC32_ARM64=y +CONFIG_QMI_ENCDEC=y diff --git a/arch/arm64/configs/msmcortex_mediabox_defconfig b/arch/arm64/configs/msmcortex_mediabox_defconfig index ccd653eaec7d09d13df024b6674af2af31625d21..28d900cf5b1899a3906f9a5cf341010c70d5fecf 100644 --- a/arch/arm64/configs/msmcortex_mediabox_defconfig +++ b/arch/arm64/configs/msmcortex_mediabox_defconfig @@ -4,6 +4,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -194,6 +197,7 @@ CONFIG_L2TP_V3=y CONFIG_L2TP_IP=y CONFIG_L2TP_ETH=y CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y CONFIG_NET_SCHED=y CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_PRIO=y @@ -241,7 +245,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -543,7 +547,6 @@ CONFIG_QCOM_WATCHDOG_V2=y CONFIG_QCOM_IRQ_HELPER=y CONFIG_QCOM_MEMORY_DUMP_V2=y CONFIG_ICNSS=y -CONFIG_ICNSS_DEBUG=y CONFIG_MSM_GLADIATOR_ERP_V2=y CONFIG_PANIC_ON_GLADIATOR_ERROR_V2=y CONFIG_MSM_GLADIATOR_HANG_DETECT=y diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index ffb983587c31c6f8e1109c7d0766a53729fafd1e..daadeff7ea348cac20f4242fecd90576b822e4fb 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -526,6 +526,7 @@ CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y CONFIG_IOMMU_DEBUG_TRACKING=y CONFIG_IOMMU_TESTS=y +CONFIG_QCOM_COMMON_LOG=y CONFIG_MSM_SMEM=y CONFIG_QPNP_HAPTIC=y CONFIG_QPNP_PBS=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index bba52749284a0bad0d25805e4b067945c3d293a7..3fe9e2bda6d2b36941d651a0ca08ff7c88bec11c 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -4,6 +4,9 @@ CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_TASKSTATS=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y CONFIG_RCU_EXPERT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -242,7 +245,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_QSEECOM=y CONFIG_HDCP_QSEECOM=y -CONFIG_UID_CPUTIME=y +CONFIG_UID_SYS_STATS=y CONFIG_QPNP_MISC=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -645,13 +648,14 @@ CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_SLUB_DEBUG_PANIC_ON=y +CONFIG_PAGE_POISONING=y +CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_FREE=y CONFIG_DEBUG_OBJECTS_TIMERS=y CONFIG_DEBUG_OBJECTS_WORK=y CONFIG_DEBUG_OBJECTS_RCU_HEAD=y CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y -CONFIG_SLUB_DEBUG_ON=y CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index 2cf32e9887e1b292a0ec9102761ce3a200b8fa0d..de1aab4b5da8e03d9b6e00c9e83ca5a401637b45 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -23,6 +23,11 @@ config CRYPTO_GHASH_ARM64_CE depends on ARM64 && KERNEL_MODE_NEON select CRYPTO_HASH +config CRYPTO_POLY_HASH_ARM64_CE + tristate "poly_hash (for HEH encryption mode) using ARMv8 Crypto Extensions" + depends on ARM64 && KERNEL_MODE_NEON + select CRYPTO_HASH + config CRYPTO_AES_ARM64_CE tristate "AES core cipher using ARMv8 Crypto Extensions" depends on ARM64 && KERNEL_MODE_NEON diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile index abb79b3cfcfea158cdcaa8ac1ffcbd32699da9b0..f0a8f2475ea3466ea9c9e370f13f418c5bcd79e0 100644 --- a/arch/arm64/crypto/Makefile +++ b/arch/arm64/crypto/Makefile @@ -17,6 +17,9 @@ sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o +obj-$(CONFIG_CRYPTO_POLY_HASH_ARM64_CE) += poly-hash-ce.o +poly-hash-ce-y := poly-hash-ce-glue.o poly-hash-ce-core.o + obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index 6a51dfccfe71a1846c66e8b2b53580b489a3d90c..448b874a482674c0fe1d686125ee5cbd778f418b 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -294,7 +294,7 @@ static struct crypto_alg aes_algs[] = { { .cra_blkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = aes_setkey, .encrypt = ecb_encrypt, .decrypt = ecb_decrypt, @@ -371,7 +371,7 @@ static struct crypto_alg aes_algs[] = { { .cra_ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, + .ivsize = 0, .setkey = ablk_set_key, .encrypt = ablk_encrypt, .decrypt = ablk_decrypt, diff --git a/arch/arm64/crypto/poly-hash-ce-core.S b/arch/arm64/crypto/poly-hash-ce-core.S new file mode 100644 index 0000000000000000000000000000000000000000..8ccb544c5526ab507eb6a04a506eac02a03aa17a --- /dev/null +++ b/arch/arm64/crypto/poly-hash-ce-core.S @@ -0,0 +1,163 @@ +/* + * Accelerated poly_hash implementation with ARMv8 PMULL instructions. + * + * Based on ghash-ce-core.S. + * + * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2017 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include + + KEY .req v0 + KEY2 .req v1 + T1 .req v2 + T2 .req v3 + GSTAR .req v4 + XL .req v5 + XM .req v6 + XH .req v7 + + .text + .arch armv8-a+crypto + + /* 16-byte aligned (2**4 = 16); not required, but might as well */ + .align 4 +.Lgstar: + .quad 0x87, 0x87 + +/* + * void pmull_poly_hash_update(le128 *digest, const le128 *key, + * const u8 *src, unsigned int blocks, + * unsigned int partial); + */ +ENTRY(pmull_poly_hash_update) + + /* Load digest into XL */ + ld1 {XL.16b}, [x0] + + /* Load key into KEY */ + ld1 {KEY.16b}, [x1] + + /* Load g*(x) = g(x) + x^128 = x^7 + x^2 + x + 1 into both halves of + * GSTAR */ + adr x1, .Lgstar + ld1 {GSTAR.2d}, [x1] + + /* Set KEY2 to (KEY[1]+KEY[0]):(KEY[1]+KEY[0]). This is needed for + * Karatsuba multiplication. */ + ext KEY2.16b, KEY.16b, KEY.16b, #8 + eor KEY2.16b, KEY2.16b, KEY.16b + + /* If 'partial' is nonzero, then we're finishing a pending block and + * should go right to the multiplication. */ + cbnz w4, 1f + +0: + /* Add the next block from 'src' to the digest */ + ld1 {T1.16b}, [x2], #16 + eor XL.16b, XL.16b, T1.16b + sub w3, w3, #1 + +1: + /* + * Multiply the current 128-bit digest (a1:a0, in XL) by the 128-bit key + * (b1:b0, in KEY) using Karatsuba multiplication. + */ + + /* T1 = (a1+a0):(a1+a0) */ + ext T1.16b, XL.16b, XL.16b, #8 + eor T1.16b, T1.16b, XL.16b + + /* XH = a1 * b1 */ + pmull2 XH.1q, XL.2d, KEY.2d + + /* XL = a0 * b0 */ + pmull XL.1q, XL.1d, KEY.1d + + /* XM = (a1+a0) * (b1+b0) */ + pmull XM.1q, T1.1d, KEY2.1d + + /* XM += (XH[0]:XL[1]) + XL + XH */ + ext T1.16b, XL.16b, XH.16b, #8 + eor T2.16b, XL.16b, XH.16b + eor XM.16b, XM.16b, T1.16b + eor XM.16b, XM.16b, T2.16b + + /* + * Now the 256-bit product is in XH[1]:XM:XL[0]. It represents a + * polynomial over GF(2) with degree as large as 255. We need to + * compute its remainder modulo g(x) = x^128+x^7+x^2+x+1. For this it + * is sufficient to compute the remainder of the high half 'c(x)x^128' + * add it to the low half. To reduce the high half we use the Barrett + * reduction method. The basic idea is that we can express the + * remainder p(x) as g(x)q(x) mod x^128, where q(x) = (c(x)x^128)/g(x). + * As detailed in [1], to avoid having to divide by g(x) at runtime the + * following equivalent expression can be derived: + * + * p(x) = [ g*(x)((c(x)q+(x))/x^128) ] mod x^128 + * + * where g*(x) = x^128+g(x) = x^7+x^2+x+1, and q+(x) = x^256/g(x) = g(x) + * in this case. This is also equivalent to: + * + * p(x) = [ g*(x)((c(x)(x^128 + g*(x)))/x^128) ] mod x^128 + * = [ g*(x)(c(x) + (c(x)g*(x))/x^128) ] mod x^128 + * + * Since deg g*(x) < 64: + * + * p(x) = [ g*(x)(c(x) + ((c(x)/x^64)g*(x))/x^64) ] mod x^128 + * = [ g*(x)((c(x)/x^64)x^64 + (c(x) mod x^64) + + * ((c(x)/x^64)g*(x))/x^64) ] mod x^128 + * + * Letting t(x) = g*(x)(c(x)/x^64): + * + * p(x) = [ t(x)x^64 + g*(x)((c(x) mod x^64) + t(x)/x^64) ] mod x^128 + * + * Therefore, to do the reduction we only need to issue two 64-bit => + * 128-bit carryless multiplications: g*(x) times c(x)/x^64, and g*(x) + * times ((c(x) mod x^64) + t(x)/x^64). (Multiplication by x^64 doesn't + * count since it is simply a shift or move.) + * + * An alternate reduction method, also based on Barrett reduction and + * described in [1], uses only shifts and XORs --- no multiplications. + * However, the method with multiplications requires fewer instructions + * and is faster on processors with fast carryless multiplication. + * + * [1] "Intel Carry-Less Multiplication Instruction and its Usage for + * Computing the GCM Mode", + * https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf + */ + + /* 256-bit product is XH[1]:XM:XL[0], so c(x) is XH[1]:XM[1] */ + + /* T1 = t(x) = g*(x)(c(x)/x^64) */ + pmull2 T1.1q, GSTAR.2d, XH.2d + + /* T2 = g*(x)((c(x) mod x^64) + t(x)/x^64) */ + eor T2.16b, XM.16b, T1.16b + pmull2 T2.1q, GSTAR.2d, T2.2d + + /* Make XL[0] be the low half of the 128-bit result by adding the low 64 + * bits of the T2 term to what was already there. The 't(x)x^64' term + * makes no difference, so skip it. */ + eor XL.16b, XL.16b, T2.16b + + /* Make XL[1] be the high half of the 128-bit result by adding the high + * 64 bits of the 't(x)x^64' and T2 terms to what was already in XM[0], + * then moving XM[0] to XL[1]. */ + eor XM.16b, XM.16b, T1.16b + ext T2.16b, T2.16b, T2.16b, #8 + eor XM.16b, XM.16b, T2.16b + mov XL.d[1], XM.d[0] + + /* If more blocks remain, then loop back to process the next block; + * else, store the digest and return. */ + cbnz w3, 0b + st1 {XL.16b}, [x0] + ret +ENDPROC(pmull_poly_hash_update) diff --git a/arch/arm64/crypto/poly-hash-ce-glue.c b/arch/arm64/crypto/poly-hash-ce-glue.c new file mode 100644 index 0000000000000000000000000000000000000000..e195740c9ecf140dc0ab4ed1f58bd1274a058886 --- /dev/null +++ b/arch/arm64/crypto/poly-hash-ce-glue.c @@ -0,0 +1,166 @@ +/* + * Accelerated poly_hash implementation with ARMv8 PMULL instructions. + * + * Based on ghash-ce-glue.c. + * + * poly_hash is part of the HEH (Hash-Encrypt-Hash) encryption mode, proposed in + * Internet Draft https://tools.ietf.org/html/draft-cope-heh-01. + * + * poly_hash is very similar to GHASH: both algorithms are keyed hashes which + * interpret their input data as coefficients of a polynomial over GF(2^128), + * then calculate a hash value by evaluating that polynomial at the point given + * by the key, e.g. using Horner's rule. The difference is that poly_hash uses + * the more natural "ble" convention to represent GF(2^128) elements, whereas + * GHASH uses the less natural "lle" convention (see include/crypto/gf128mul.h). + * The ble convention makes it simpler to implement GF(2^128) multiplication. + * + * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2017 Google Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +/* + * Note: in this algorithm we currently use 'le128' to represent GF(2^128) + * elements, even though poly_hash-generic uses 'be128'. Both types are + * actually "wrong" because the elements are actually in 'ble' format, and there + * should be a ble type to represent this --- as well as lle, bbe, and lbe types + * for the other conventions for representing GF(2^128) elements. But + * practically it doesn't matter which type we choose here, so we just use le128 + * since it's arguably more accurate, while poly_hash-generic still has to use + * be128 because the generic GF(2^128) multiplication functions all take be128. + */ + +struct poly_hash_desc_ctx { + le128 digest; + unsigned int count; +}; + +asmlinkage void pmull_poly_hash_update(le128 *digest, const le128 *key, + const u8 *src, unsigned int blocks, + unsigned int partial); + +static int poly_hash_setkey(struct crypto_shash *tfm, + const u8 *key, unsigned int keylen) +{ + if (keylen != sizeof(le128)) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + memcpy(crypto_shash_ctx(tfm), key, sizeof(le128)); + return 0; +} + +static int poly_hash_init(struct shash_desc *desc) +{ + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + + ctx->digest = (le128) { 0 }; + ctx->count = 0; + return 0; +} + +static int poly_hash_update(struct shash_desc *desc, const u8 *src, + unsigned int len) +{ + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + unsigned int partial = ctx->count % sizeof(le128); + u8 *dst = (u8 *)&ctx->digest + partial; + + ctx->count += len; + + /* Finishing at least one block? */ + if (partial + len >= sizeof(le128)) { + const le128 *key = crypto_shash_ctx(desc->tfm); + + if (partial) { + /* Finish the pending block. */ + unsigned int n = sizeof(le128) - partial; + + len -= n; + do { + *dst++ ^= *src++; + } while (--n); + } + + /* + * Do the real work. If 'partial' is nonzero, this starts by + * multiplying 'digest' by 'key'. Then for each additional full + * block it adds the block to 'digest' and multiplies by 'key'. + */ + kernel_neon_begin_partial(8); + pmull_poly_hash_update(&ctx->digest, key, src, + len / sizeof(le128), partial); + kernel_neon_end(); + + src += len - (len % sizeof(le128)); + len %= sizeof(le128); + dst = (u8 *)&ctx->digest; + } + + /* Continue adding the next block to 'digest'. */ + while (len--) + *dst++ ^= *src++; + return 0; +} + +static int poly_hash_final(struct shash_desc *desc, u8 *out) +{ + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + unsigned int partial = ctx->count % sizeof(le128); + + /* Finish the last block if needed. */ + if (partial) { + const le128 *key = crypto_shash_ctx(desc->tfm); + + kernel_neon_begin_partial(8); + pmull_poly_hash_update(&ctx->digest, key, NULL, 0, partial); + kernel_neon_end(); + } + + memcpy(out, &ctx->digest, sizeof(le128)); + return 0; +} + +static struct shash_alg poly_hash_alg = { + .digestsize = sizeof(le128), + .init = poly_hash_init, + .update = poly_hash_update, + .final = poly_hash_final, + .setkey = poly_hash_setkey, + .descsize = sizeof(struct poly_hash_desc_ctx), + .base = { + .cra_name = "poly_hash", + .cra_driver_name = "poly_hash-ce", + .cra_priority = 300, + .cra_ctxsize = sizeof(le128), + .cra_module = THIS_MODULE, + }, +}; + +static int __init poly_hash_ce_mod_init(void) +{ + return crypto_register_shash(&poly_hash_alg); +} + +static void __exit poly_hash_ce_mod_exit(void) +{ + crypto_unregister_shash(&poly_hash_alg); +} + +MODULE_DESCRIPTION("Polynomial evaluation hash using ARMv8 Crypto Extensions"); +MODULE_AUTHOR("Eric Biggers "); +MODULE_LICENSE("GPL v2"); + +module_cpu_feature_match(PMULL, poly_hash_ce_mod_init); +module_exit(poly_hash_ce_mod_exit); diff --git a/arch/arm64/include/asm/app_api.h b/arch/arm64/include/asm/app_api.h new file mode 100644 index 0000000000000000000000000000000000000000..0e6a469cd68367b1d57424e874ead56e60cb0926 --- /dev/null +++ b/arch/arm64/include/asm/app_api.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_APP_API_H +#define __ASM_APP_API_H + +#include +#include +#include + +#define APP_SETTING_BIT 30 +#define MAX_ENTRIES 10 + +/* + * APIs to set / clear the app setting bits + * in the register. + */ +#ifdef CONFIG_MSM_APP_API +extern void set_app_setting_bit(uint32_t bit); +extern void clear_app_setting_bit(uint32_t bit); +extern void set_app_setting_bit_for_32bit_apps(void); +extern void clear_app_setting_bit_for_32bit_apps(void); +#else +static inline void set_app_setting_bit(uint32_t bit) {} +static inline void clear_app_setting_bit(uint32_t bit) {} +static inline void set_app_setting_bit_for_32bit_apps(void) {} +static inline void clear_app_setting_bit_for_32bit_apps(void) {} +#endif + +#ifdef CONFIG_MSM_APP_SETTINGS +extern void switch_app_setting_bit(struct task_struct *prev, + struct task_struct *next); +extern void switch_32bit_app_setting_bit(struct task_struct *prev, + struct task_struct *next); +extern void apply_app_setting_bit(struct file *file); +extern bool use_app_setting; +extern bool use_32bit_app_setting; +extern bool use_32bit_app_setting_pro; +#endif + +#endif diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h index 5082b30bc2c05fbf7b970141dd1d69800e7ed3b3..f9359d32fae5274a4104ac8a8cac4f0571c84292 100644 --- a/arch/arm64/include/asm/cache.h +++ b/arch/arm64/include/asm/cache.h @@ -18,17 +18,17 @@ #include -#define L1_CACHE_SHIFT 7 +#define L1_CACHE_SHIFT 6 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) /* * Memory returned by kmalloc() may be used for DMA, so we must make - * sure that all such allocations are cache aligned. Otherwise, - * unrelated code may cause parts of the buffer to be read into the - * cache before the transfer is done, causing old data to be seen by - * the CPU. + * sure that all such allocations are aligned to the maximum *known* + * cache line size on ARMv8 systems. Otherwise, unrelated code may + * cause parts of the buffer to be read into the cache before the + * transfer is done, causing old data to be seen by the CPU. */ -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN (128) #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/dma-contiguous.h b/arch/arm64/include/asm/dma-contiguous.h index 61507394a99b30e00f432891982c7c9552eb8f77..e77da2002bc9d157115c95657dc580a68f49f0e6 100644 --- a/arch/arm64/include/asm/dma-contiguous.h +++ b/arch/arm64/include/asm/dma-contiguous.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2013,2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,7 +15,6 @@ #define _ASM_DMA_CONTIGUOUS_H #ifdef __KERNEL__ -#ifdef CONFIG_DMA_CMA #include @@ -23,5 +22,3 @@ void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); #endif #endif - -#endif diff --git a/arch/arm64/include/asm/dma-iommu.h b/arch/arm64/include/asm/dma-iommu.h index ba8f19a13a315a540cd1bdb9d6de119c6ad7efeb..c16cf151f6896c41d7aa3249730fb5d5b02ec59c 100644 --- a/arch/arm64/include/asm/dma-iommu.h +++ b/arch/arm64/include/asm/dma-iommu.h @@ -9,7 +9,6 @@ #include #include #include -#include struct dma_iommu_mapping { /* iommu specific data */ @@ -21,8 +20,9 @@ struct dma_iommu_mapping { spinlock_t lock; struct kref kref; - +#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST struct dma_fast_smmu_mapping *fast; +#endif }; #ifdef CONFIG_ARM64_DMA_USE_IOMMU diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 7875c886ad24226bea0617649b6e50a7944361bf..a383c288ef490a0d2bbb3199e53496ab2b9b6ce5 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -23,6 +23,7 @@ */ #include #include +#include /* * AArch64 static relocation types. @@ -182,7 +183,11 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; ((x)->e_flags & EF_ARM_EABI_MASK)) #define compat_start_thread compat_start_thread -#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT); +#define COMPAT_SET_PERSONALITY(ex) \ +do { \ + set_thread_flag(TIF_32BIT); \ +} while (0) + #define COMPAT_ARCH_DLINFO extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp); diff --git a/arch/arm64/include/asm/exec.h b/arch/arm64/include/asm/exec.h index db0563c23482d52175bf6c22f733410797122e36..f7865dd9d86854760e69ea71d30452625d6713ec 100644 --- a/arch/arm64/include/asm/exec.h +++ b/arch/arm64/include/asm/exec.h @@ -18,6 +18,9 @@ #ifndef __ASM_EXEC_H #define __ASM_EXEC_H +#include + extern unsigned long arch_align_stack(unsigned long sp); +void uao_thread_switch(struct task_struct *next); #endif /* __ASM_EXEC_H */ diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 50f559f574fe53b4d25995bd465c7b90f0a4b8be..3efaa5cebc03e7b79cce223f338e9e7902901c4a 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -81,6 +81,14 @@ extern void fpsimd_save_partial_state(struct fpsimd_partial_state *state, u32 num_regs); extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state); +#ifdef CONFIG_ENABLE_FP_SIMD_SETTINGS +extern void fpsimd_disable_trap(void); +extern void fpsimd_enable_trap(void); +#else +static inline void fpsimd_disable_trap(void) {} +static inline void fpsimd_enable_trap(void) {} +#endif + #endif #endif diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h index 9732908bfc8a54b546c4cab40802f70a56b36fce..c72b8e201ab4f2b028b7cdc0ff701b6f18f782e4 100644 --- a/arch/arm64/include/asm/hw_breakpoint.h +++ b/arch/arm64/include/asm/hw_breakpoint.h @@ -68,7 +68,11 @@ static inline void decode_ctrl_reg(u32 reg, /* Lengths */ #define ARM_BREAKPOINT_LEN_1 0x1 #define ARM_BREAKPOINT_LEN_2 0x3 +#define ARM_BREAKPOINT_LEN_3 0x7 #define ARM_BREAKPOINT_LEN_4 0xf +#define ARM_BREAKPOINT_LEN_5 0x1f +#define ARM_BREAKPOINT_LEN_6 0x3f +#define ARM_BREAKPOINT_LEN_7 0x7f #define ARM_BREAKPOINT_LEN_8 0xff /* Kernel stepping */ @@ -110,7 +114,7 @@ struct perf_event; struct pmu; extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, - int *gen_len, int *gen_type); + int *gen_len, int *gen_type, int *offset); extern int arch_check_bp_in_kernelspace(struct perf_event *bp); extern int arch_validate_hwbkpt_settings(struct perf_event *bp); extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h index de66199673d7ae23678c72bd898953af869a4b87..2b9a63771eda8c81b12ec4279a9e279543739ecc 100644 --- a/arch/arm64/include/asm/vdso_datapage.h +++ b/arch/arm64/include/asm/vdso_datapage.h @@ -22,6 +22,8 @@ struct vdso_data { __u64 cs_cycle_last; /* Timebase at clocksource init */ + __u64 raw_time_sec; /* Raw time */ + __u64 raw_time_nsec; __u64 xtime_clock_sec; /* Kernel time */ __u64 xtime_clock_nsec; __u64 xtime_coarse_sec; /* Coarse time */ @@ -29,8 +31,10 @@ struct vdso_data { __u64 wtm_clock_sec; /* Wall to monotonic time */ __u64 wtm_clock_nsec; __u32 tb_seq_count; /* Timebase sequence counter */ - __u32 cs_mult; /* Clocksource multiplier */ - __u32 cs_shift; /* Clocksource shift */ + /* cs_* members must be adjacent and in this order (ldp accesses) */ + __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */ + __u32 cs_shift; /* Clocksource shift (mono = raw) */ + __u32 cs_raw_mult; /* Raw clocksource multiplier */ __u32 tz_minuteswest; /* Whacky timezone stuff */ __u32 tz_dsttime; __u32 use_syscall; diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index d3cfa681654f146ced345599cbd9ed40b8dc09aa..99f4410833b46958de02e0a83f066295e4ec6c3d 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -44,6 +44,8 @@ arm64-obj-$(CONFIG_PCI) += pci.o arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o arm64-obj-$(CONFIG_ACPI) += acpi.o arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o +arm64-obj-$(CONFIG_MSM_APP_API) += app_api.o +arm64-obj-$(CONFIG_MSM_APP_SETTINGS) += app_setting.o arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o @@ -52,7 +54,3 @@ obj-y += $(arm64-obj-y) vdso/ probes/ obj-m += $(arm64-obj-m) head-y := head.o extra-y += $(head-y) vmlinux.lds - -# vDSO - this must be built first to generate the symbol offsets -$(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h -$(obj)/vdso/vdso-offsets.h: $(obj)/vdso diff --git a/arch/arm64/kernel/app_api.c b/arch/arm64/kernel/app_api.c new file mode 100644 index 0000000000000000000000000000000000000000..e995bbf3c7b4b4f76247515020f5eb04679388c7 --- /dev/null +++ b/arch/arm64/kernel/app_api.c @@ -0,0 +1,135 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include + +static spinlock_t spinlock; +static spinlock_t spinlock_32bit_app; +static DEFINE_PER_CPU(int, app_config_applied); +static unsigned long app_config_set[NR_CPUS]; +static unsigned long app_config_clear[NR_CPUS]; + +void set_app_setting_bit(uint32_t bit) +{ + unsigned long flags; + uint64_t reg; + int cpu; + + spin_lock_irqsave(&spinlock, flags); + asm volatile("mrs %0, S3_1_C15_C15_0" : "=r" (reg)); + reg = reg | BIT(bit); + isb(); + asm volatile("msr S3_1_C15_C15_0, %0" : : "r" (reg)); + isb(); + if (bit == APP_SETTING_BIT) { + cpu = raw_smp_processor_id(); + app_config_set[cpu]++; + + this_cpu_write(app_config_applied, 1); + } + spin_unlock_irqrestore(&spinlock, flags); + +} +EXPORT_SYMBOL(set_app_setting_bit); + +void clear_app_setting_bit(uint32_t bit) +{ + unsigned long flags; + uint64_t reg; + int cpu; + + spin_lock_irqsave(&spinlock, flags); + asm volatile("mrs %0, S3_1_C15_C15_0" : "=r" (reg)); + reg = reg & ~BIT(bit); + isb(); + asm volatile("msr S3_1_C15_C15_0, %0" : : "r" (reg)); + isb(); + if (bit == APP_SETTING_BIT) { + cpu = raw_smp_processor_id(); + app_config_clear[cpu]++; + + this_cpu_write(app_config_applied, 0); + } + spin_unlock_irqrestore(&spinlock, flags); +} +EXPORT_SYMBOL(clear_app_setting_bit); + +void set_app_setting_bit_for_32bit_apps(void) +{ + unsigned long flags; + uint64_t reg; + + spin_lock_irqsave(&spinlock_32bit_app, flags); + if (use_32bit_app_setting) { + asm volatile("mrs %0, S3_0_c15_c15_0 " : "=r" (reg)); + reg = reg | BIT(24); + isb(); + asm volatile("msr S3_0_c15_c15_0, %0" : : "r" (reg)); + isb(); + asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg)); + reg = reg | BIT(18) | BIT(2) | BIT(0); + isb(); + asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg)); + isb(); + } else if (use_32bit_app_setting_pro) { + asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg)); + reg = reg | BIT(18); + isb(); + asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg)); + isb(); + } + spin_unlock_irqrestore(&spinlock_32bit_app, flags); +} +EXPORT_SYMBOL(set_app_setting_bit_for_32bit_apps); + +void clear_app_setting_bit_for_32bit_apps(void) +{ + unsigned long flags; + uint64_t reg; + + spin_lock_irqsave(&spinlock_32bit_app, flags); + if (use_32bit_app_setting) { + asm volatile("mrs %0, S3_0_c15_c15_0 " : "=r" (reg)); + reg = reg & ~BIT(24); + isb(); + asm volatile("msr S3_0_c15_c15_0, %0" : : "r" (reg)); + isb(); + asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg)); + reg = reg & ~BIT(18); + reg = reg & ~BIT(2); + reg = reg & ~BIT(0); + isb(); + asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg)); + isb(); + } else if (use_32bit_app_setting_pro) { + asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg)); + reg = reg & ~BIT(18); + isb(); + asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg)); + isb(); + } + spin_unlock_irqrestore(&spinlock_32bit_app, flags); +} +EXPORT_SYMBOL(clear_app_setting_bit_for_32bit_apps); + +static int __init init_app_api(void) +{ + spin_lock_init(&spinlock); + spin_lock_init(&spinlock_32bit_app); + return 0; +} +early_initcall(init_app_api); diff --git a/arch/arm64/kernel/app_setting.c b/arch/arm64/kernel/app_setting.c new file mode 100644 index 0000000000000000000000000000000000000000..0c6b0031764596bdf19e9519df30851020847902 --- /dev/null +++ b/arch/arm64/kernel/app_setting.c @@ -0,0 +1,139 @@ +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include + +#define MAX_LEN 100 + +static char *lib_names[MAX_ENTRIES]; +static unsigned int count; +static struct mutex mutex; + +static char lib_str[MAX_LEN] = ""; +static struct kparam_string kps = { + .string = lib_str, + .maxlen = MAX_LEN, +}; +static int set_name(const char *str, struct kernel_param *kp); +module_param_call(lib_name, set_name, param_get_string, &kps, S_IWUSR); + +bool use_app_setting = true; +module_param(use_app_setting, bool, 0644); +MODULE_PARM_DESC(use_app_setting, "control use of app specific settings"); + +bool use_32bit_app_setting = true; +module_param(use_32bit_app_setting, bool, 0644); +MODULE_PARM_DESC(use_32bit_app_setting, "control use of 32 bit app specific settings"); + +bool use_32bit_app_setting_pro; +module_param(use_32bit_app_setting_pro, bool, 0644); +MODULE_PARM_DESC(use_32bit_app_setting_pro, "control use of 32 bit app specific settings"); + +static int set_name(const char *str, struct kernel_param *kp) +{ + int len = strlen(str); + char *name; + + if (len >= MAX_LEN) { + pr_err("app_setting: name string too long\n"); + return -ENOSPC; + } + + /* + * echo adds '\n' which we need to chop off later + */ + name = kzalloc(len + 1, GFP_KERNEL); + if (!name) + return -ENOMEM; + + strlcpy(name, str, len + 1); + + if (name[len - 1] == '\n') + name[len - 1] = '\0'; + + mutex_lock(&mutex); + if (count < MAX_ENTRIES) { + lib_names[count] = name; + /* + * mb to ensure that the new lib_names entry is present + * before updating the view presented by get_lib_names + */ + mb(); + count++; + } else { + pr_err("app_setting: set name failed. Max entries reached\n"); + kfree(name); + mutex_unlock(&mutex); + return -EPERM; + } + mutex_unlock(&mutex); + + return 0; +} + +void switch_app_setting_bit(struct task_struct *prev, struct task_struct *next) +{ + if (prev->mm && unlikely(prev->mm->app_setting)) + clear_app_setting_bit(APP_SETTING_BIT); + + if (next->mm && unlikely(next->mm->app_setting)) + set_app_setting_bit(APP_SETTING_BIT); +} +EXPORT_SYMBOL(switch_app_setting_bit); + +void switch_32bit_app_setting_bit(struct task_struct *prev, + struct task_struct *next) +{ + if (prev->mm && unlikely(is_compat_thread(task_thread_info(prev)))) + clear_app_setting_bit_for_32bit_apps(); + + if (next->mm && unlikely(is_compat_thread(task_thread_info(next)))) + set_app_setting_bit_for_32bit_apps(); +} +EXPORT_SYMBOL(switch_32bit_app_setting_bit); + +void apply_app_setting_bit(struct file *file) +{ + bool found = false; + int i; + + if (file && file->f_path.dentry) { + const char *name = file->f_path.dentry->d_name.name; + + for (i = 0; i < count; i++) { + if (unlikely(!strcmp(name, lib_names[i]))) { + found = true; + break; + } + } + if (found) { + preempt_disable(); + set_app_setting_bit(APP_SETTING_BIT); + /* This will take care of child processes as well */ + current->mm->app_setting = 1; + preempt_enable(); + } + } +} +EXPORT_SYMBOL(apply_app_setting_bit); + +static int __init app_setting_init(void) +{ + mutex_init(&mutex); + return 0; +} +module_init(app_setting_init); diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index c9ea87198789771cc5d3662d43a54fa0aedc3514..350c0e99fc6bcb1a6706efd46d1cdb022e9f0339 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -92,6 +92,7 @@ int main(void) BLANK(); DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); + DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW); DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE); @@ -99,6 +100,8 @@ int main(void) DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); BLANK(); DEFINE(VDSO_CS_CYCLE_LAST, offsetof(struct vdso_data, cs_cycle_last)); + DEFINE(VDSO_RAW_TIME_SEC, offsetof(struct vdso_data, raw_time_sec)); + DEFINE(VDSO_RAW_TIME_NSEC, offsetof(struct vdso_data, raw_time_nsec)); DEFINE(VDSO_XTIME_CLK_SEC, offsetof(struct vdso_data, xtime_clock_sec)); DEFINE(VDSO_XTIME_CLK_NSEC, offsetof(struct vdso_data, xtime_clock_nsec)); DEFINE(VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec)); @@ -106,7 +109,8 @@ int main(void) DEFINE(VDSO_WTM_CLK_SEC, offsetof(struct vdso_data, wtm_clock_sec)); DEFINE(VDSO_WTM_CLK_NSEC, offsetof(struct vdso_data, wtm_clock_nsec)); DEFINE(VDSO_TB_SEQ_COUNT, offsetof(struct vdso_data, tb_seq_count)); - DEFINE(VDSO_CS_MULT, offsetof(struct vdso_data, cs_mult)); + DEFINE(VDSO_CS_MONO_MULT, offsetof(struct vdso_data, cs_mono_mult)); + DEFINE(VDSO_CS_RAW_MULT, offsetof(struct vdso_data, cs_raw_mult)); DEFINE(VDSO_CS_SHIFT, offsetof(struct vdso_data, cs_shift)); DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index cdf1dca6413385f7ac2bbaa1faeff8198b8d4d92..f75000996e4c5b7acb2e9066784fc33a3990b69c 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -992,9 +992,9 @@ void __init setup_cpu_features(void) if (!cwg) pr_warn("No Cache Writeback Granule information, assuming cache line size %d\n", cls); - if (L1_CACHE_BYTES < cls) - pr_warn("L1_CACHE_BYTES smaller than the Cache Writeback Granule (%d < %d)\n", - L1_CACHE_BYTES, cls); + if (ARCH_DMA_MINALIGN < cls) + pr_warn("ARCH_DMA_MINALIGN smaller than the Cache Writeback Granule (%d < %d)\n", + ARCH_DMA_MINALIGN, cls); } static bool __maybe_unused diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index c44a82f146b16664850ddadbfdc4699784c4e468..1ffe15459c925f77c3894c9e035e1a2310d53430 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S @@ -64,4 +64,20 @@ ENTRY(fpsimd_load_partial_state) ret ENDPROC(fpsimd_load_partial_state) +#ifdef CONFIG_ENABLE_FP_SIMD_SETTINGS +ENTRY(fpsimd_enable_trap) + mrs x0, cpacr_el1 + bic x0, x0, #(3 << 20) + orr x0, x0, #(1 << 20) + msr cpacr_el1, x0 + ret +ENDPROC(fpsimd_enable_trap) +ENTRY(fpsimd_disable_trap) + mrs x0, cpacr_el1 + orr x0, x0, #(3 << 20) + msr cpacr_el1, x0 + ret +ENDPROC(fpsimd_disable_trap) +#endif + #endif diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 191e3136fa6ead0bf2ba32c633c94a2c498041f2..0ea65307f866425dff858b814a98683b5de40810 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -561,7 +561,7 @@ el0_sync_compat: cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0 b.eq el0_ia cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access - b.eq el0_fpsimd_acc + b.eq el0_fpsimd_acc_compat cmp x24, #ESR_ELx_EC_FP_EXC32 // FP/ASIMD exception b.eq el0_fpsimd_exc cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception @@ -632,6 +632,17 @@ el0_fpsimd_acc: mov x1, sp bl do_fpsimd_acc b ret_to_user +el0_fpsimd_acc_compat: + /* + * Floating Point or Advanced SIMD access + */ + enable_dbg + ct_user_exit + mov x0, x25 + mov x1, sp + bl do_fpsimd_acc_compat + b ret_to_user + el0_fpsimd_exc: /* * Floating Point or Advanced SIMD exception diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index acc1afd5c749a62b7c0bae5a14d2fd7dbc33adf2..790d27e3b99735204f788f65a9985682a502eca3 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include +#include #define FPEXC_IOF (1 << 0) #define FPEXC_DZF (1 << 1) @@ -35,6 +37,8 @@ #define FPEXC_IXF (1 << 4) #define FPEXC_IDF (1 << 7) +#define FP_SIMD_BIT 31 + /* * In order to reduce the number of times the FPSIMD state is needlessly saved * and restored, we need to keep track of two things: @@ -88,14 +92,42 @@ * whatever is in the FPSIMD registers is not saved to memory, but discarded. */ static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); +static DEFINE_PER_CPU(int, fpsimd_stg_enable); + +static int fpsimd_settings = 0x1; /* default = 0x1 */ +module_param(fpsimd_settings, int, 0644); + +void fpsimd_settings_enable(void) +{ + set_app_setting_bit(FP_SIMD_BIT); +} + +void fpsimd_settings_disable(void) +{ + clear_app_setting_bit(FP_SIMD_BIT); +} /* * Trapped FP/ASIMD access. */ void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) { - /* TODO: implement lazy context saving/restoring */ - WARN_ON(1); + if (!fpsimd_settings) + return; + + fpsimd_disable_trap(); + fpsimd_settings_disable(); + this_cpu_write(fpsimd_stg_enable, 0); +} + +void do_fpsimd_acc_compat(unsigned int esr, struct pt_regs *regs) +{ + if (!fpsimd_settings) + return; + + fpsimd_disable_trap(); + fpsimd_settings_enable(); + this_cpu_write(fpsimd_stg_enable, 1); } /* @@ -135,6 +167,11 @@ void fpsimd_thread_switch(struct task_struct *next) if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_save_state(¤t->thread.fpsimd_state); + if (fpsimd_settings && __this_cpu_read(fpsimd_stg_enable)) { + fpsimd_settings_disable(); + this_cpu_write(fpsimd_stg_enable, 0); + } + if (next->mm) { /* * If we are switching to a task whose most recent userland @@ -152,6 +189,14 @@ void fpsimd_thread_switch(struct task_struct *next) else set_ti_thread_flag(task_thread_info(next), TIF_FOREIGN_FPSTATE); + + if (!fpsimd_settings) + return; + + if (test_ti_thread_flag(task_thread_info(next), TIF_32BIT)) + fpsimd_enable_trap(); + else + fpsimd_disable_trap(); } } diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index 367a954f9937979c574a805bab2e3cbad706d202..f4dfd8c41e061fbc94c14d3deb5e1088d01fd4f5 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -317,9 +317,21 @@ static int get_hbp_len(u8 hbp_len) case ARM_BREAKPOINT_LEN_2: len_in_bytes = 2; break; + case ARM_BREAKPOINT_LEN_3: + len_in_bytes = 3; + break; case ARM_BREAKPOINT_LEN_4: len_in_bytes = 4; break; + case ARM_BREAKPOINT_LEN_5: + len_in_bytes = 5; + break; + case ARM_BREAKPOINT_LEN_6: + len_in_bytes = 6; + break; + case ARM_BREAKPOINT_LEN_7: + len_in_bytes = 7; + break; case ARM_BREAKPOINT_LEN_8: len_in_bytes = 8; break; @@ -349,7 +361,7 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) * to generic breakpoint descriptions. */ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, - int *gen_len, int *gen_type) + int *gen_len, int *gen_type, int *offset) { /* Type */ switch (ctrl.type) { @@ -369,17 +381,33 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, return -EINVAL; } + if (!ctrl.len) + return -EINVAL; + *offset = __ffs(ctrl.len); + /* Len */ - switch (ctrl.len) { + switch (ctrl.len >> *offset) { case ARM_BREAKPOINT_LEN_1: *gen_len = HW_BREAKPOINT_LEN_1; break; case ARM_BREAKPOINT_LEN_2: *gen_len = HW_BREAKPOINT_LEN_2; break; + case ARM_BREAKPOINT_LEN_3: + *gen_len = HW_BREAKPOINT_LEN_3; + break; case ARM_BREAKPOINT_LEN_4: *gen_len = HW_BREAKPOINT_LEN_4; break; + case ARM_BREAKPOINT_LEN_5: + *gen_len = HW_BREAKPOINT_LEN_5; + break; + case ARM_BREAKPOINT_LEN_6: + *gen_len = HW_BREAKPOINT_LEN_6; + break; + case ARM_BREAKPOINT_LEN_7: + *gen_len = HW_BREAKPOINT_LEN_7; + break; case ARM_BREAKPOINT_LEN_8: *gen_len = HW_BREAKPOINT_LEN_8; break; @@ -423,9 +451,21 @@ static int arch_build_bp_info(struct perf_event *bp) case HW_BREAKPOINT_LEN_2: info->ctrl.len = ARM_BREAKPOINT_LEN_2; break; + case HW_BREAKPOINT_LEN_3: + info->ctrl.len = ARM_BREAKPOINT_LEN_3; + break; case HW_BREAKPOINT_LEN_4: info->ctrl.len = ARM_BREAKPOINT_LEN_4; break; + case HW_BREAKPOINT_LEN_5: + info->ctrl.len = ARM_BREAKPOINT_LEN_5; + break; + case HW_BREAKPOINT_LEN_6: + info->ctrl.len = ARM_BREAKPOINT_LEN_6; + break; + case HW_BREAKPOINT_LEN_7: + info->ctrl.len = ARM_BREAKPOINT_LEN_7; + break; case HW_BREAKPOINT_LEN_8: info->ctrl.len = ARM_BREAKPOINT_LEN_8; break; @@ -517,18 +557,17 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) default: return -EINVAL; } - - info->address &= ~alignment_mask; - info->ctrl.len <<= offset; } else { if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) alignment_mask = 0x3; else alignment_mask = 0x7; - if (info->address & alignment_mask) - return -EINVAL; + offset = info->address & alignment_mask; } + info->address &= ~alignment_mask; + info->ctrl.len <<= offset; + /* * Disallow per-task kernel breakpoints since these would * complicate the stepping code. @@ -661,12 +700,47 @@ unlock: } NOKPROBE_SYMBOL(breakpoint_handler); +/* + * Arm64 hardware does not always report a watchpoint hit address that matches + * one of the watchpoints set. It can also report an address "near" the + * watchpoint if a single instruction access both watched and unwatched + * addresses. There is no straight-forward way, short of disassembling the + * offending instruction, to map that address back to the watchpoint. This + * function computes the distance of the memory access from the watchpoint as a + * heuristic for the likelyhood that a given access triggered the watchpoint. + * + * See Section D2.10.5 "Determining the memory location that caused a Watchpoint + * exception" of ARMv8 Architecture Reference Manual for details. + * + * The function returns the distance of the address from the bytes watched by + * the watchpoint. In case of an exact match, it returns 0. + */ +static u64 get_distance_from_watchpoint(unsigned long addr, u64 val, + struct arch_hw_breakpoint_ctrl *ctrl) +{ + u64 wp_low, wp_high; + u32 lens, lene; + + lens = __ffs(ctrl->len); + lene = __fls(ctrl->len); + + wp_low = val + lens; + wp_high = val + lene; + if (addr < wp_low) + return wp_low - addr; + else if (addr > wp_high) + return addr - wp_high; + else + return 0; +} + static int watchpoint_handler(unsigned long addr, unsigned int esr, struct pt_regs *regs) { - int i, step = 0, *kernel_step, access; + int i, step = 0, *kernel_step, access, closest_match = 0; + u64 min_dist = -1, dist; u32 ctrl_reg; - u64 val, alignment_mask; + u64 val; struct perf_event *wp, **slots; struct debug_info *debug_info; struct arch_hw_breakpoint *info; @@ -675,35 +749,15 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, slots = this_cpu_ptr(wp_on_reg); debug_info = ¤t->thread.debug; + /* + * Find all watchpoints that match the reported address. If no exact + * match is found. Attribute the hit to the closest watchpoint. + */ + rcu_read_lock(); for (i = 0; i < core_num_wrps; ++i) { - rcu_read_lock(); - wp = slots[i]; - if (wp == NULL) - goto unlock; - - info = counter_arch_bp(wp); - /* AArch32 watchpoints are either 4 or 8 bytes aligned. */ - if (is_compat_task()) { - if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) - alignment_mask = 0x7; - else - alignment_mask = 0x3; - } else { - alignment_mask = 0x7; - } - - /* Check if the watchpoint value matches. */ - val = read_wb_reg(AARCH64_DBG_REG_WVR, i); - if (val != (addr & ~alignment_mask)) - goto unlock; - - /* Possible match, check the byte address select to confirm. */ - ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i); - decode_ctrl_reg(ctrl_reg, &ctrl); - if (!((1 << (addr & alignment_mask)) & ctrl.len)) - goto unlock; + continue; /* * Check that the access type matches. @@ -712,18 +766,41 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W : HW_BREAKPOINT_R; if (!(access & hw_breakpoint_type(wp))) - goto unlock; + continue; + /* Check if the watchpoint value and byte select match. */ + val = read_wb_reg(AARCH64_DBG_REG_WVR, i); + ctrl_reg = read_wb_reg(AARCH64_DBG_REG_WCR, i); + decode_ctrl_reg(ctrl_reg, &ctrl); + dist = get_distance_from_watchpoint(addr, val, &ctrl); + if (dist < min_dist) { + min_dist = dist; + closest_match = i; + } + /* Is this an exact match? */ + if (dist != 0) + continue; + + info = counter_arch_bp(wp); info->trigger = addr; perf_bp_event(wp, regs); /* Do we need to handle the stepping? */ if (!wp->overflow_handler) step = 1; + } + if (min_dist > 0 && min_dist != -1) { + /* No exact match found. */ + wp = slots[closest_match]; + info = counter_arch_bp(wp); + info->trigger = addr; + perf_bp_event(wp, regs); -unlock: - rcu_read_unlock(); + /* Do we need to handle the stepping? */ + if (!wp->overflow_handler) + step = 1; } + rcu_read_unlock(); if (!step) return 0; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 5a09efa7572282fc6f62cb5daacdf2d6dfc78848..fc0a7aa2ca82452d8d3440c69a31529947668ba8 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -383,7 +384,7 @@ static void tls_thread_switch(struct task_struct *next) } /* Restore the UAO state depending on next's addr_limit */ -static void uao_thread_switch(struct task_struct *next) +void uao_thread_switch(struct task_struct *next) { if (IS_ENABLED(CONFIG_ARM64_UAO)) { if (task_thread_info(next)->addr_limit == KERNEL_DS) diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index c5ef059598135eee7ee8894330e269d1d2b1bec2..6204b7600d1b0a2ab7b8764d0534ac51e18a33ef 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -327,13 +327,13 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, struct arch_hw_breakpoint_ctrl ctrl, struct perf_event_attr *attr) { - int err, len, type, disabled = !ctrl.enabled; + int err, len, type, offset, disabled = !ctrl.enabled; attr->disabled = disabled; if (disabled) return 0; - err = arch_bp_generic_fields(ctrl, &len, &type); + err = arch_bp_generic_fields(ctrl, &len, &type, &offset); if (err) return err; @@ -352,6 +352,7 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, attr->bp_len = len; attr->bp_type = type; + attr->bp_addr += offset; return 0; } @@ -404,7 +405,7 @@ static int ptrace_hbp_get_addr(unsigned int note_type, if (IS_ERR(bp)) return PTR_ERR(bp); - *addr = bp ? bp->attr.bp_addr : 0; + *addr = bp ? counter_arch_bp(bp)->address : 0; return 0; } diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index c2bf5a58039f1b7f749912bc18f58bf5007e80fb..9a3aec97ac091bd8503e539544b3a62bec0bd143 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -132,6 +132,11 @@ ENTRY(_cpu_resume) */ bl cpu_do_resume +#ifdef CONFIG_KASAN + mov x0, sp + bl kasan_unpoison_remaining_stack +#endif + ldp x19, x20, [x29, #16] ldp x21, x22, [x29, #32] ldp x23, x24, [x29, #48] diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 5a0b1088c17c0fa0d9998ee03a67791d111b2e75..0acdb63d19b6a48dd71f3b0d263f2b72fda87e8e 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) */ asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)); + uao_thread_switch(current); /* * Restore HW breakpoint registers to sane values diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 97bc68f4c689f28eac7188f5e0b792b5293c37da..3b8acfae7797bf54877805cde809d7a061564562 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -55,7 +55,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; */ static struct page *vectors_page[1]; -static int alloc_vectors_page(void) +static int __init alloc_vectors_page(void) { extern char __kuser_helper_start[], __kuser_helper_end[]; extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[]; @@ -88,7 +88,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) { struct mm_struct *mm = current->mm; unsigned long addr = AARCH32_VECTORS_BASE; - static struct vm_special_mapping spec = { + static const struct vm_special_mapping spec = { .name = "[vectors]", .pages = vectors_page, @@ -212,10 +212,16 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; if (!use_syscall) { + /* tkr_mono.cycle_last == tkr_raw.cycle_last */ vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; + vdso_data->raw_time_sec = tk->raw_time.tv_sec; + vdso_data->raw_time_nsec = tk->raw_time.tv_nsec; vdso_data->xtime_clock_sec = tk->xtime_sec; vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; - vdso_data->cs_mult = tk->tkr_mono.mult; + /* tkr_raw.xtime_nsec == 0 */ + vdso_data->cs_mono_mult = tk->tkr_mono.mult; + vdso_data->cs_raw_mult = tk->tkr_raw.mult; + /* tkr_mono.shift == tkr_raw.shift */ vdso_data->cs_shift = tk->tkr_mono.shift; } diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index b467fd0a384b36b87fe76ef7e50b4a28bda8bd01..62c84f7cb01b99e0105abef1d3bd3252249fc74c 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -23,7 +23,7 @@ GCOV_PROFILE := n ccflags-y += -Wl,-shared obj-y += vdso.o -extra-y += vdso.lds vdso-offsets.h +extra-y += vdso.lds CPPFLAGS_vdso.lds += -P -C -U$(ARCH) # Force dependency (incbin is bad) @@ -42,11 +42,10 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh quiet_cmd_vdsosym = VDSOSYM $@ define cmd_vdsosym - $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \ - cp $@ include/generated/ + $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ endef -$(obj)/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE +include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE $(call if_changed,vdsosym) # Assembly rules for the .S files diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S index 9f8eeccae67ced2dfc10ddacb1fa5ee6696903dc..e00b4671bd7c4af5516b95da00409c7296df1963 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.S +++ b/arch/arm64/kernel/vdso/gettimeofday.S @@ -26,24 +26,109 @@ #define NSEC_PER_SEC_HI16 0x3b9a vdso_data .req x6 -use_syscall .req w7 -seqcnt .req w8 +seqcnt .req w7 +w_tmp .req w8 +x_tmp .req x8 + +/* + * Conventions for macro arguments: + * - An argument is write-only if its name starts with "res". + * - All other arguments are read-only, unless otherwise specified. + */ .macro seqcnt_acquire 9999: ldr seqcnt, [vdso_data, #VDSO_TB_SEQ_COUNT] tbnz seqcnt, #0, 9999b dmb ishld - ldr use_syscall, [vdso_data, #VDSO_USE_SYSCALL] .endm - .macro seqcnt_read, cnt + .macro seqcnt_check fail dmb ishld - ldr \cnt, [vdso_data, #VDSO_TB_SEQ_COUNT] + ldr w_tmp, [vdso_data, #VDSO_TB_SEQ_COUNT] + cmp w_tmp, seqcnt + b.ne \fail .endm - .macro seqcnt_check, cnt, fail - cmp \cnt, seqcnt - b.ne \fail + .macro syscall_check fail + ldr w_tmp, [vdso_data, #VDSO_USE_SYSCALL] + cbnz w_tmp, \fail + .endm + + .macro get_nsec_per_sec res + mov \res, #NSEC_PER_SEC_LO16 + movk \res, #NSEC_PER_SEC_HI16, lsl #16 + .endm + + /* + * Returns the clock delta, in nanoseconds left-shifted by the clock + * shift. + */ + .macro get_clock_shifted_nsec res, cycle_last, mult + /* Read the virtual counter. */ + isb + mrs x_tmp, cntvct_el0 + /* Calculate cycle delta and convert to ns. */ + sub \res, x_tmp, \cycle_last + /* We can only guarantee 56 bits of precision. */ + movn x_tmp, #0xff00, lsl #48 + and \res, x_tmp, \res + mul \res, \res, \mult + .endm + + /* + * Returns in res_{sec,nsec} the REALTIME timespec, based on the + * "wall time" (xtime) and the clock_mono delta. + */ + .macro get_ts_realtime res_sec, res_nsec, \ + clock_nsec, xtime_sec, xtime_nsec, nsec_to_sec + add \res_nsec, \clock_nsec, \xtime_nsec + udiv x_tmp, \res_nsec, \nsec_to_sec + add \res_sec, \xtime_sec, x_tmp + msub \res_nsec, x_tmp, \nsec_to_sec, \res_nsec + .endm + + /* + * Returns in res_{sec,nsec} the timespec based on the clock_raw delta, + * used for CLOCK_MONOTONIC_RAW. + */ + .macro get_ts_clock_raw res_sec, res_nsec, clock_nsec, nsec_to_sec + udiv \res_sec, \clock_nsec, \nsec_to_sec + msub \res_nsec, \res_sec, \nsec_to_sec, \clock_nsec + .endm + + /* sec and nsec are modified in place. */ + .macro add_ts sec, nsec, ts_sec, ts_nsec, nsec_to_sec + /* Add timespec. */ + add \sec, \sec, \ts_sec + add \nsec, \nsec, \ts_nsec + + /* Normalise the new timespec. */ + cmp \nsec, \nsec_to_sec + b.lt 9999f + sub \nsec, \nsec, \nsec_to_sec + add \sec, \sec, #1 +9999: + cmp \nsec, #0 + b.ge 9998f + add \nsec, \nsec, \nsec_to_sec + sub \sec, \sec, #1 +9998: + .endm + + .macro clock_gettime_return, shift=0 + .if \shift == 1 + lsr x11, x11, x12 + .endif + stp x10, x11, [x1, #TSPEC_TV_SEC] + mov x0, xzr + ret + .endm + + .macro jump_slot jumptable, index, label + .if (. - \jumptable) != 4 * (\index) + .error "Jump slot index mismatch" + .endif + b \label .endm .text @@ -51,18 +136,25 @@ seqcnt .req w8 /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */ ENTRY(__kernel_gettimeofday) .cfi_startproc - mov x2, x30 - .cfi_register x30, x2 - - /* Acquire the sequence counter and get the timespec. */ adr vdso_data, _vdso_data -1: seqcnt_acquire - cbnz use_syscall, 4f - /* If tv is NULL, skip to the timezone code. */ cbz x0, 2f - bl __do_get_tspec - seqcnt_check w9, 1b + + /* Compute the time of day. */ +1: seqcnt_acquire + syscall_check fail=4f + ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] + /* w11 = cs_mono_mult, w12 = cs_shift */ + ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] + ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] + seqcnt_check fail=1b + + get_nsec_per_sec res=x9 + lsl x9, x9, x12 + + get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 + get_ts_realtime res_sec=x10, res_nsec=x11, \ + clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 /* Convert ns to us. */ mov x13, #1000 @@ -76,95 +168,126 @@ ENTRY(__kernel_gettimeofday) stp w4, w5, [x1, #TZ_MINWEST] 3: mov x0, xzr - ret x2 + ret 4: /* Syscall fallback. */ mov x8, #__NR_gettimeofday svc #0 - ret x2 + ret .cfi_endproc ENDPROC(__kernel_gettimeofday) +#define JUMPSLOT_MAX CLOCK_MONOTONIC_COARSE + /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */ ENTRY(__kernel_clock_gettime) .cfi_startproc - cmp w0, #CLOCK_REALTIME - ccmp w0, #CLOCK_MONOTONIC, #0x4, ne - b.ne 2f + cmp w0, #JUMPSLOT_MAX + b.hi syscall + adr vdso_data, _vdso_data + adr x_tmp, jumptable + add x_tmp, x_tmp, w0, uxtw #2 + br x_tmp + + ALIGN +jumptable: + jump_slot jumptable, CLOCK_REALTIME, realtime + jump_slot jumptable, CLOCK_MONOTONIC, monotonic + b syscall + b syscall + jump_slot jumptable, CLOCK_MONOTONIC_RAW, monotonic_raw + jump_slot jumptable, CLOCK_REALTIME_COARSE, realtime_coarse + jump_slot jumptable, CLOCK_MONOTONIC_COARSE, monotonic_coarse + + .if (. - jumptable) != 4 * (JUMPSLOT_MAX + 1) + .error "Wrong jumptable size" + .endif + + ALIGN +realtime: + seqcnt_acquire + syscall_check fail=syscall + ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] + /* w11 = cs_mono_mult, w12 = cs_shift */ + ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] + ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] + seqcnt_check fail=realtime - mov x2, x30 - .cfi_register x30, x2 + /* All computations are done with left-shifted nsecs. */ + get_nsec_per_sec res=x9 + lsl x9, x9, x12 - /* Get kernel timespec. */ - adr vdso_data, _vdso_data -1: seqcnt_acquire - cbnz use_syscall, 7f + get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 + get_ts_realtime res_sec=x10, res_nsec=x11, \ + clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 + clock_gettime_return, shift=1 - bl __do_get_tspec - seqcnt_check w9, 1b + ALIGN +monotonic: + seqcnt_acquire + syscall_check fail=syscall + ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] + /* w11 = cs_mono_mult, w12 = cs_shift */ + ldp w11, w12, [vdso_data, #VDSO_CS_MONO_MULT] + ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] + ldp x3, x4, [vdso_data, #VDSO_WTM_CLK_SEC] + seqcnt_check fail=monotonic - mov x30, x2 + /* All computations are done with left-shifted nsecs. */ + lsl x4, x4, x12 + get_nsec_per_sec res=x9 + lsl x9, x9, x12 - cmp w0, #CLOCK_MONOTONIC - b.ne 6f + get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 + get_ts_realtime res_sec=x10, res_nsec=x11, \ + clock_nsec=x15, xtime_sec=x13, xtime_nsec=x14, nsec_to_sec=x9 - /* Get wtm timespec. */ - ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] + add_ts sec=x10, nsec=x11, ts_sec=x3, ts_nsec=x4, nsec_to_sec=x9 + clock_gettime_return, shift=1 - /* Check the sequence counter. */ - seqcnt_read w9 - seqcnt_check w9, 1b - b 4f -2: - cmp w0, #CLOCK_REALTIME_COARSE - ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne - b.ne 8f + ALIGN +monotonic_raw: + seqcnt_acquire + syscall_check fail=syscall + ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] + /* w11 = cs_raw_mult, w12 = cs_shift */ + ldp w12, w11, [vdso_data, #VDSO_CS_SHIFT] + ldp x13, x14, [vdso_data, #VDSO_RAW_TIME_SEC] + seqcnt_check fail=monotonic_raw - /* xtime_coarse_nsec is already right-shifted */ - mov x12, #0 + /* All computations are done with left-shifted nsecs. */ + lsl x14, x14, x12 + get_nsec_per_sec res=x9 + lsl x9, x9, x12 - /* Get coarse timespec. */ - adr vdso_data, _vdso_data -3: seqcnt_acquire - ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] + get_clock_shifted_nsec res=x15, cycle_last=x10, mult=x11 + get_ts_clock_raw res_sec=x10, res_nsec=x11, \ + clock_nsec=x15, nsec_to_sec=x9 - /* Get wtm timespec. */ - ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] + add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9 + clock_gettime_return, shift=1 - /* Check the sequence counter. */ - seqcnt_read w9 - seqcnt_check w9, 3b + ALIGN +realtime_coarse: + seqcnt_acquire + ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] + seqcnt_check fail=realtime_coarse + clock_gettime_return - cmp w0, #CLOCK_MONOTONIC_COARSE - b.ne 6f -4: - /* Add on wtm timespec. */ - add x10, x10, x13 - lsl x14, x14, x12 - add x11, x11, x14 + ALIGN +monotonic_coarse: + seqcnt_acquire + ldp x10, x11, [vdso_data, #VDSO_XTIME_CRS_SEC] + ldp x13, x14, [vdso_data, #VDSO_WTM_CLK_SEC] + seqcnt_check fail=monotonic_coarse - /* Normalise the new timespec. */ - mov x15, #NSEC_PER_SEC_LO16 - movk x15, #NSEC_PER_SEC_HI16, lsl #16 - lsl x15, x15, x12 - cmp x11, x15 - b.lt 5f - sub x11, x11, x15 - add x10, x10, #1 -5: - cmp x11, #0 - b.ge 6f - add x11, x11, x15 - sub x10, x10, #1 + /* Computations are done in (non-shifted) nsecs. */ + get_nsec_per_sec res=x9 + add_ts sec=x10, nsec=x11, ts_sec=x13, ts_nsec=x14, nsec_to_sec=x9 + clock_gettime_return -6: /* Store to the user timespec. */ - lsr x11, x11, x12 - stp x10, x11, [x1, #TSPEC_TV_SEC] - mov x0, xzr - ret -7: - mov x30, x2 -8: /* Syscall fallback. */ + ALIGN +syscall: /* Syscall fallback. */ mov x8, #__NR_clock_gettime svc #0 ret @@ -176,6 +299,7 @@ ENTRY(__kernel_clock_getres) .cfi_startproc cmp w0, #CLOCK_REALTIME ccmp w0, #CLOCK_MONOTONIC, #0x4, ne + ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne b.ne 1f ldr x2, 5f @@ -203,55 +327,3 @@ ENTRY(__kernel_clock_getres) .quad CLOCK_COARSE_RES .cfi_endproc ENDPROC(__kernel_clock_getres) - -/* - * Read the current time from the architected counter. - * Expects vdso_data to be initialised. - * Clobbers the temporary registers (x9 - x15). - * Returns: - * - w9 = vDSO sequence counter - * - (x10, x11) = (ts->tv_sec, shifted ts->tv_nsec) - * - w12 = cs_shift - */ -ENTRY(__do_get_tspec) - .cfi_startproc - - /* Read the virtual counter. */ - isb -#if IS_ENABLED(CONFIG_MSM_TIMER_LEAP) -#define LEAST_32BITS 0x00000000FFFFFFFF -reread: - mrs x15, cntvct_el0 - and x13, x15, #LEAST_32BITS - eor x13, x13, #LEAST_32BITS - cbz x13, reread -#else - mrs x15, cntvct_el0 -#endif - - /* Read from the vDSO data page. */ - ldr x10, [vdso_data, #VDSO_CS_CYCLE_LAST] - ldp x13, x14, [vdso_data, #VDSO_XTIME_CLK_SEC] - ldp w11, w12, [vdso_data, #VDSO_CS_MULT] - seqcnt_read w9 - - /* Calculate cycle delta and convert to ns. */ - sub x10, x15, x10 - /* We can only guarantee 56 bits of precision. */ - movn x15, #0xff00, lsl #48 - and x10, x15, x10 - mul x10, x10, x11 - - /* Use the kernel time to calculate the new timespec. */ - mov x11, #NSEC_PER_SEC_LO16 - movk x11, #NSEC_PER_SEC_HI16, lsl #16 - lsl x11, x11, x12 - add x15, x10, x14 - udiv x14, x15, x11 - add x10, x13, x14 - mul x13, x14, x11 - sub x11, x15, x13 - - ret - .cfi_endproc -ENDPROC(__do_get_tspec) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index a13b9a65322fd576d0d12d215abc7b336d014d79..1804aea44faa4cc8f26214e6e5a9680a29c8a241 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -708,5 +708,6 @@ int cpu_enable_pan(void *__unused) int cpu_enable_uao(void *__unused) { asm(SET_PSTATE_UAO(1)); + return 0; } #endif /* CONFIG_ARM64_UAO */ diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c index 3c494e84444d1e2347d91bb67531e314166c3109..a511ac16a8e37c20e9774d87887d516b5c64c5f6 100644 --- a/arch/c6x/kernel/ptrace.c +++ b/arch/c6x/kernel/ptrace.c @@ -69,46 +69,6 @@ static int gpr_get(struct task_struct *target, 0, sizeof(*regs)); } -static int gpr_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int ret; - struct pt_regs *regs = task_pt_regs(target); - - /* Don't copyin TSR or CSR */ - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - ®s, - 0, PT_TSR * sizeof(long)); - if (ret) - return ret; - - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - PT_TSR * sizeof(long), - (PT_TSR + 1) * sizeof(long)); - if (ret) - return ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - ®s, - (PT_TSR + 1) * sizeof(long), - PT_CSR * sizeof(long)); - if (ret) - return ret; - - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - PT_CSR * sizeof(long), - (PT_CSR + 1) * sizeof(long)); - if (ret) - return ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - ®s, - (PT_CSR + 1) * sizeof(long), -1); - return ret; -} - enum c6x_regset { REGSET_GPR, }; @@ -120,7 +80,6 @@ static const struct user_regset c6x_regsets[] = { .size = sizeof(u32), .align = sizeof(u32), .get = gpr_get, - .set = gpr_set }, }; diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c index 92075544a19ac03fae02b3efc28a986b0748ec1c..0dc1c8f622bc3fda818d5703896e99be485762ea 100644 --- a/arch/h8300/kernel/ptrace.c +++ b/arch/h8300/kernel/ptrace.c @@ -95,7 +95,8 @@ static int regs_get(struct task_struct *target, long *reg = (long *)®s; /* build user regs in buffer */ - for (r = 0; r < ARRAY_SIZE(register_offset); r++) + BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); + for (r = 0; r < sizeof(regs) / sizeof(long); r++) *reg++ = h8300_get_reg(target, r); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, @@ -113,7 +114,8 @@ static int regs_set(struct task_struct *target, long *reg; /* build user regs in buffer */ - for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) + BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); + for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) *reg++ = h8300_get_reg(target, r); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, @@ -122,7 +124,7 @@ static int regs_set(struct task_struct *target, return ret; /* write back to pt_regs */ - for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) + for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) h8300_put_reg(target, r, *reg++); return 0; } diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 970d0bd99621b32eef163debccd8c2d41a970250..648f1cef33fa8aa684ac57ffdaa2247392024c1a 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -95,8 +95,8 @@ define archhelp echo '* unwcheck - Check vmlinux for invalid unwind info' endef -archprepare: make_nr_irqs_h FORCE +archprepare: make_nr_irqs_h PHONY += make_nr_irqs_h FORCE -make_nr_irqs_h: FORCE +make_nr_irqs_h: $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 273e61225c277ae67ba28dfae4ef9123e3ef34a9..07238b39638cd2c933219bb957bff1d80212d8bc 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h @@ -197,20 +197,21 @@ extern long __must_check strnlen_user(const char __user *src, long count); #define strlen_user(str) strnlen_user(str, 32767) -extern unsigned long __must_check __copy_user_zeroing(void *to, - const void __user *from, - unsigned long n); +extern unsigned long raw_copy_from_user(void *to, const void __user *from, + unsigned long n); static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { + unsigned long res = n; if (likely(access_ok(VERIFY_READ, from, n))) - return __copy_user_zeroing(to, from, n); - memset(to, 0, n); - return n; + res = raw_copy_from_user(to, from, n); + if (unlikely(res)) + memset(to + (n - res), 0, res); + return res; } -#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) +#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) #define __copy_from_user_inatomic __copy_from_user extern unsigned long __must_check __copy_user(void __user *to, diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c index 7563628822bdf638a708816bf4abe8ccb1b2a4db..5e2dc7defd2cea8f8895b028ab6adaa2c11f10d4 100644 --- a/arch/metag/kernel/ptrace.c +++ b/arch/metag/kernel/ptrace.c @@ -24,6 +24,16 @@ * user_regset definitions. */ +static unsigned long user_txstatus(const struct pt_regs *regs) +{ + unsigned long data = (unsigned long)regs->ctx.Flags; + + if (regs->ctx.SaveMask & TBICTX_CBUF_BIT) + data |= USER_GP_REGS_STATUS_CATCH_BIT; + + return data; +} + int metag_gp_regs_copyout(const struct pt_regs *regs, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) @@ -62,9 +72,7 @@ int metag_gp_regs_copyout(const struct pt_regs *regs, if (ret) goto out; /* TXSTATUS */ - data = (unsigned long)regs->ctx.Flags; - if (regs->ctx.SaveMask & TBICTX_CBUF_BIT) - data |= USER_GP_REGS_STATUS_CATCH_BIT; + data = user_txstatus(regs); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &data, 4*25, 4*26); if (ret) @@ -119,6 +127,7 @@ int metag_gp_regs_copyin(struct pt_regs *regs, if (ret) goto out; /* TXSTATUS */ + data = user_txstatus(regs); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &data, 4*25, 4*26); if (ret) @@ -244,6 +253,8 @@ int metag_rp_state_copyin(struct pt_regs *regs, unsigned long long *ptr; int ret, i; + if (count < 4*13) + return -EINVAL; /* Read the entire pipeline before making any changes */ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &rp, 0, 4*13); @@ -303,7 +314,7 @@ static int metag_tls_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { int ret; - void __user *tls; + void __user *tls = target->thread.tls_ptr; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); if (ret) diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c index b3ebfe9c8e886a5c0f8f309b1a390ac286208a86..2792fc621088bcd1c3d7bfe58b8560ec32e6f880 100644 --- a/arch/metag/lib/usercopy.c +++ b/arch/metag/lib/usercopy.c @@ -29,7 +29,6 @@ COPY \ "1:\n" \ " .section .fixup,\"ax\"\n" \ - " MOV D1Ar1,#0\n" \ FIXUP \ " MOVT D1Ar1,#HI(1b)\n" \ " JUMP D1Ar1,#LO(1b)\n" \ @@ -260,27 +259,31 @@ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "22:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ - "SUB %3, %3, #32\n" \ "23:\n" \ - "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "SUB %3, %3, #32\n" \ "24:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "25:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "26:\n" \ "SUB %3, %3, #32\n" \ "DCACHE [%1+#-64], D0Ar6\n" \ "BR $Lloop"id"\n" \ \ "MOV RAPF, %1\n" \ - "25:\n" \ + "27:\n" \ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "26:\n" \ + "28:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "29:\n" \ "SUB %3, %3, #32\n" \ - "27:\n" \ + "30:\n" \ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "28:\n" \ + "31:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "32:\n" \ "SUB %0, %0, #8\n" \ - "29:\n" \ + "33:\n" \ "SETL [%0++], D0.7, D1.7\n" \ "SUB %3, %3, #32\n" \ "1:" \ @@ -312,11 +315,15 @@ " .long 26b,3b\n" \ " .long 27b,3b\n" \ " .long 28b,3b\n" \ - " .long 29b,4b\n" \ + " .long 29b,3b\n" \ + " .long 30b,3b\n" \ + " .long 31b,3b\n" \ + " .long 32b,3b\n" \ + " .long 33b,4b\n" \ " .previous\n" \ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ : "0" (to), "1" (from), "2" (ret), "3" (n) \ - : "D1Ar1", "D0Ar2", "memory") + : "D1Ar1", "D0Ar2", "cc", "memory") /* rewind 'to' and 'from' pointers when a fault occurs * @@ -342,7 +349,7 @@ #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ "LSR D0Ar2, D0Ar2, #8\n" \ - "AND D0Ar2, D0Ar2, #0x7\n" \ + "ANDS D0Ar2, D0Ar2, #0x7\n" \ "ADDZ D0Ar2, D0Ar2, #4\n" \ "SUB D0Ar2, D0Ar2, #1\n" \ "MOV D1Ar1, #4\n" \ @@ -403,47 +410,55 @@ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "22:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ - "SUB %3, %3, #16\n" \ "23:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "24:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ "SUB %3, %3, #16\n" \ - "25:\n" \ + "24:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "26:\n" \ + "25:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "26:\n" \ "SUB %3, %3, #16\n" \ "27:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "28:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "29:\n" \ + "SUB %3, %3, #16\n" \ + "30:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "31:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "32:\n" \ "SUB %3, %3, #16\n" \ "DCACHE [%1+#-64], D0Ar6\n" \ "BR $Lloop"id"\n" \ \ "MOV RAPF, %1\n" \ - "29:\n" \ + "33:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "30:\n" \ + "34:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "35:\n" \ "SUB %3, %3, #16\n" \ - "31:\n" \ + "36:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "32:\n" \ + "37:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "38:\n" \ "SUB %3, %3, #16\n" \ - "33:\n" \ + "39:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "34:\n" \ + "40:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "41:\n" \ "SUB %3, %3, #16\n" \ - "35:\n" \ + "42:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "36:\n" \ + "43:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "44:\n" \ "SUB %0, %0, #4\n" \ - "37:\n" \ + "45:\n" \ "SETD [%0++], D0.7\n" \ "SUB %3, %3, #16\n" \ "1:" \ @@ -483,11 +498,19 @@ " .long 34b,3b\n" \ " .long 35b,3b\n" \ " .long 36b,3b\n" \ - " .long 37b,4b\n" \ + " .long 37b,3b\n" \ + " .long 38b,3b\n" \ + " .long 39b,3b\n" \ + " .long 40b,3b\n" \ + " .long 41b,3b\n" \ + " .long 42b,3b\n" \ + " .long 43b,3b\n" \ + " .long 44b,3b\n" \ + " .long 45b,4b\n" \ " .previous\n" \ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ : "0" (to), "1" (from), "2" (ret), "3" (n) \ - : "D1Ar1", "D0Ar2", "memory") + : "D1Ar1", "D0Ar2", "cc", "memory") /* rewind 'to' and 'from' pointers when a fault occurs * @@ -513,7 +536,7 @@ #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ "LSR D0Ar2, D0Ar2, #8\n" \ - "AND D0Ar2, D0Ar2, #0x7\n" \ + "ANDS D0Ar2, D0Ar2, #0x7\n" \ "ADDZ D0Ar2, D0Ar2, #4\n" \ "SUB D0Ar2, D0Ar2, #1\n" \ "MOV D1Ar1, #4\n" \ @@ -538,23 +561,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, if ((unsigned long) src & 1) { __asm_copy_to_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } if ((unsigned long) dst & 1) { /* Worst case - byte copy */ while (n > 0) { __asm_copy_to_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_to_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } if ((unsigned long) dst & 2) { /* Second worst case - word copy */ while (n >= 2) { __asm_copy_to_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } } @@ -569,6 +600,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 8) { __asm_copy_to_user_8x64(dst, src, retn); n -= 8; + if (retn) + return retn + n; } } if (n >= RAPF_MIN_BUF_SIZE) { @@ -581,6 +614,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 8) { __asm_copy_to_user_8x64(dst, src, retn); n -= 8; + if (retn) + return retn + n; } } #endif @@ -588,11 +623,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 16) { __asm_copy_to_user_16(dst, src, retn); n -= 16; + if (retn) + return retn + n; } while (n >= 4) { __asm_copy_to_user_4(dst, src, retn); n -= 4; + if (retn) + return retn + n; } switch (n) { @@ -609,6 +648,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, break; } + /* + * If we get here, retn correctly reflects the number of failing + * bytes. + */ return retn; } EXPORT_SYMBOL(__copy_user); @@ -617,16 +660,14 @@ EXPORT_SYMBOL(__copy_user); __asm_copy_user_cont(to, from, ret, \ " GETB D1Ar1,[%1++]\n" \ "2: SETB [%0++],D1Ar1\n", \ - "3: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ + "3: ADD %2,%2,#1\n", \ " .long 2b,3b\n") #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " GETW D1Ar1,[%1++]\n" \ "2: SETW [%0++],D1Ar1\n" COPY, \ - "3: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ + "3: ADD %2,%2,#2\n" FIXUP, \ " .long 2b,3b\n" TENTRY) #define __asm_copy_from_user_2(to, from, ret) \ @@ -636,145 +677,26 @@ EXPORT_SYMBOL(__copy_user); __asm_copy_from_user_2x_cont(to, from, ret, \ " GETB D1Ar1,[%1++]\n" \ "4: SETB [%0++],D1Ar1\n", \ - "5: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ + "5: ADD %2,%2,#1\n", \ " .long 4b,5b\n") #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " GETD D1Ar1,[%1++]\n" \ "2: SETD [%0++],D1Ar1\n" COPY, \ - "3: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ + "3: ADD %2,%2,#4\n" FIXUP, \ " .long 2b,3b\n" TENTRY) #define __asm_copy_from_user_4(to, from, ret) \ __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") -#define __asm_copy_from_user_5(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "4: SETB [%0++],D1Ar1\n", \ - "5: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 4b,5b\n") - -#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "4: SETW [%0++],D1Ar1\n" COPY, \ - "5: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_6(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_7(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "6: SETB [%0++],D1Ar1\n", \ - "7: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 6b,7b\n") - -#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "4: SETD [%0++],D1Ar1\n" COPY, \ - "5: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_8(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_9(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "6: SETB [%0++],D1Ar1\n", \ - "7: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 6b,7b\n") - -#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "6: SETW [%0++],D1Ar1\n" COPY, \ - "7: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_10(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_11(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "8: SETB [%0++],D1Ar1\n", \ - "9: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 8b,9b\n") - -#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "6: SETD [%0++],D1Ar1\n" COPY, \ - "7: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_12(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_13(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "8: SETB [%0++],D1Ar1\n", \ - "9: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 8b,9b\n") - -#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "8: SETW [%0++],D1Ar1\n" COPY, \ - "9: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_14(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_15(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "10: SETB [%0++],D1Ar1\n", \ - "11: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 10b,11b\n") - -#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "8: SETD [%0++],D1Ar1\n" COPY, \ - "9: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_16(to, from, ret) \ - __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") - #define __asm_copy_from_user_8x64(to, from, ret) \ asm volatile ( \ " GETL D0Ar2,D1Ar1,[%1++]\n" \ "2: SETL [%0++],D0Ar2,D1Ar1\n" \ "1:\n" \ " .section .fixup,\"ax\"\n" \ - " MOV D1Ar1,#0\n" \ - " MOV D0Ar2,#0\n" \ "3: ADD %2,%2,#8\n" \ - " SETL [%0++],D0Ar2,D1Ar1\n" \ " MOVT D0Ar2,#HI(1b)\n" \ " JUMP D0Ar2,#LO(1b)\n" \ " .previous\n" \ @@ -789,36 +711,57 @@ EXPORT_SYMBOL(__copy_user); * * Rationale: * A fault occurs while reading from user buffer, which is the - * source. Since the fault is at a single address, we only - * need to rewind by 8 bytes. + * source. * Since we don't write to kernel buffer until we read first, * the kernel buffer is at the right state and needn't be - * corrected. + * corrected, but the source must be rewound to the beginning of + * the block, which is LSM_STEP*8 bytes. + * LSM_STEP is bits 10:8 in TXSTATUS which is already read + * and stored in D0Ar2 + * + * NOTE: If a fault occurs at the last operation in M{G,S}ETL + * LSM_STEP will be 0. ie: we do 4 writes in our case, if + * a fault happens at the 4th write, LSM_STEP will be 0 + * instead of 4. The code copes with that. */ #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ - "SUB %1, %1, #8\n") + "LSR D0Ar2, D0Ar2, #5\n" \ + "ANDS D0Ar2, D0Ar2, #0x38\n" \ + "ADDZ D0Ar2, D0Ar2, #32\n" \ + "SUB %1, %1, D0Ar2\n") /* rewind 'from' pointer when a fault occurs * * Rationale: * A fault occurs while reading from user buffer, which is the - * source. Since the fault is at a single address, we only - * need to rewind by 4 bytes. + * source. * Since we don't write to kernel buffer until we read first, * the kernel buffer is at the right state and needn't be - * corrected. + * corrected, but the source must be rewound to the beginning of + * the block, which is LSM_STEP*4 bytes. + * LSM_STEP is bits 10:8 in TXSTATUS which is already read + * and stored in D0Ar2 + * + * NOTE: If a fault occurs at the last operation in M{G,S}ETL + * LSM_STEP will be 0. ie: we do 4 writes in our case, if + * a fault happens at the 4th write, LSM_STEP will be 0 + * instead of 4. The code copes with that. */ #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ - "SUB %1, %1, #4\n") + "LSR D0Ar2, D0Ar2, #6\n" \ + "ANDS D0Ar2, D0Ar2, #0x1c\n" \ + "ADDZ D0Ar2, D0Ar2, #16\n" \ + "SUB %1, %1, D0Ar2\n") -/* Copy from user to kernel, zeroing the bytes that were inaccessible in - userland. The return-value is the number of bytes that were - inaccessible. */ -unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - unsigned long n) +/* + * Copy from user to kernel. The return-value is the number of bytes that were + * inaccessible. + */ +unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, + unsigned long n) { register char *dst asm ("A0.2") = pdst; register const char __user *src asm ("A1.2") = psrc; @@ -830,6 +773,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, if ((unsigned long) src & 1) { __asm_copy_from_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } if ((unsigned long) dst & 1) { /* Worst case - byte copy */ @@ -837,12 +782,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_1(dst, src, retn); n--; if (retn) - goto copy_exception_bytes; + return retn + n; } } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_from_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } if ((unsigned long) dst & 2) { /* Second worst case - word copy */ @@ -850,16 +797,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_2(dst, src, retn); n -= 2; if (retn) - goto copy_exception_bytes; + return retn + n; } } - /* We only need one check after the unalignment-adjustments, - because if both adjustments were done, either both or - neither reference had an exception. */ - if (retn != 0) - goto copy_exception_bytes; - #ifdef USE_RAPF /* 64 bit copy loop */ if (!(((unsigned long) src | (unsigned long) dst) & 7)) { @@ -872,7 +813,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_8x64(dst, src, retn); n -= 8; if (retn) - goto copy_exception_bytes; + return retn + n; } } @@ -888,7 +829,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_8x64(dst, src, retn); n -= 8; if (retn) - goto copy_exception_bytes; + return retn + n; } } #endif @@ -898,7 +839,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, n -= 4; if (retn) - goto copy_exception_bytes; + return retn + n; } /* If we get here, there were no memory read faults. */ @@ -924,21 +865,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, /* If we get here, retn correctly reflects the number of failing bytes. */ return retn; - - copy_exception_bytes: - /* We already have "retn" bytes cleared, and need to clear the - remaining "n" bytes. A non-optimized simple byte-for-byte in-line - memset is preferred here, since this isn't speed-critical code and - we'd rather have this a leaf-function than calling memset. */ - { - char *endp; - for (endp = dst + n; dst < endp; dst++) - *dst = 0; - } - - return retn + n; } -EXPORT_SYMBOL(__copy_user_zeroing); +EXPORT_SYMBOL(raw_copy_from_user); #define __asm_clear_8x64(to, ret) \ asm volatile ( \ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index db459612de44852509f967da96ecc3d5d48eb616..8b0424abc84c9be88df34bac03f43fd50c365da8 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -9,6 +9,7 @@ config MIPS select HAVE_CONTEXT_TRACKING select HAVE_GENERIC_DMA_COHERENT select HAVE_IDE + select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_OPROFILE select HAVE_PERF_EVENTS select PERF_USE_VMALLOC @@ -1463,7 +1464,7 @@ config CPU_MIPS64_R6 select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_MSA select GENERIC_CSUM - select MIPS_O32_FP64_SUPPORT if MIPS32_O32 + select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 help Choose this option to build a kernel for release 6 or later of the MIPS64 architecture. New MIPS processors, starting with the Warrior diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 15e0fecbc300fd9752023931984fe277a73da876..ebb9efb025029d6f5184f45f765688912a1ece48 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -17,6 +17,18 @@ #include +#define IRQ_STACK_SIZE THREAD_SIZE + +extern void *irq_stack[NR_CPUS]; + +static inline bool on_irq_stack(int cpu, unsigned long sp) +{ + unsigned long low = (unsigned long)irq_stack[cpu]; + unsigned long high = low + IRQ_STACK_SIZE; + + return (low <= sp && sp <= high); +} + #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) { diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 40196bebe849a0c825cc8a61e40b03440d14f31e..2365ce0ad8f23dfacf9ae4b944639d7a047932ef 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -112,7 +112,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) " andi %[ticket], %[ticket], 0xffff \n" " bne %[ticket], %[my_ticket], 4f \n" " subu %[ticket], %[my_ticket], %[ticket] \n" - "2: \n" + "2: .insn \n" " .subsection 2 \n" "4: andi %[ticket], %[ticket], 0xffff \n" " sll %[ticket], 5 \n" @@ -187,7 +187,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) " sc %[ticket], %[ticket_ptr] \n" " beqz %[ticket], 1b \n" " li %[ticket], 1 \n" - "2: \n" + "2: .insn \n" " .subsection 2 \n" "3: b 2b \n" " li %[ticket], 0 \n" @@ -367,7 +367,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) " .set reorder \n" __WEAK_LLSC_MB " li %2, 1 \n" - "2: \n" + "2: .insn \n" : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) : GCC_OFF_SMALL_ASM() (rw->lock) : "memory"); @@ -407,7 +407,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) " lui %1, 0x8000 \n" " sc %1, %0 \n" " li %2, 1 \n" - "2: \n" + "2: .insn \n" : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) : GCC_OFF_SMALL_ASM() (rw->lock) diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index a71da576883c8f4b1a3d60279ebfaefb95798031..5347f130f5367f9c32bb2240dc8c2208befae7c5 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -216,12 +216,19 @@ LONG_S $25, PT_R25(sp) LONG_S $28, PT_R28(sp) LONG_S $31, PT_R31(sp) + + /* Set thread_info if we're coming from user mode */ + mfc0 k0, CP0_STATUS + sll k0, 3 /* extract cu0 bit */ + bltz k0, 9f + ori $28, sp, _THREAD_MASK xori $28, _THREAD_MASK #ifdef CONFIG_CPU_CAVIUM_OCTEON .set mips64 pref 0, 0($28) /* Prefetch the current pointer */ #endif +9: .set pop .endm diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 154e2039ea5ef13fe9ba8935eb01475031283913..ec053ce7bb38f5a9abd2d426132de359ef01a312 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -101,6 +101,7 @@ void output_thread_info_defines(void) OFFSET(TI_REGS, thread_info, regs); DEFINE(_THREAD_SIZE, THREAD_SIZE); DEFINE(_THREAD_MASK, THREAD_MASK); + DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); BLANK(); } diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c index d434d5d5ae6e70b5241fe2fae2f3d1a0ec8bb1ed..610f0f3bdb3455cfa42629e98f8cc883524fe8ba 100644 --- a/arch/mips/kernel/crash.c +++ b/arch/mips/kernel/crash.c @@ -14,12 +14,22 @@ static int crashing_cpu = -1; static cpumask_t cpus_in_crash = CPU_MASK_NONE; #ifdef CONFIG_SMP -static void crash_shutdown_secondary(void *ignore) +static void crash_shutdown_secondary(void *passed_regs) { - struct pt_regs *regs; + struct pt_regs *regs = passed_regs; int cpu = smp_processor_id(); - regs = task_pt_regs(current); + /* + * If we are passed registers, use those. Otherwise get the + * regs from the last interrupt, which should be correct, as + * we are in an interrupt. But if the regs are not there, + * pull them from the top of the stack. They are probably + * wrong, but we need something to keep from crashing again. + */ + if (!regs) + regs = get_irq_regs(); + if (!regs) + regs = task_pt_regs(current); if (!cpu_online(cpu)) return; diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 4a4d9e067c89427fc34e990586f0e8237a9418ba..3afffc30ee1289fae4abb4d997f98403db2ccc06 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -206,7 +206,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, else if ((prog_req.fr1 && prog_req.frdefault) || (prog_req.single && !prog_req.frdefault)) /* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */ - state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) && + state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) && cpu_has_mips_r2_r6) ? FP_FR1 : FP_FR0; else if (prog_req.fr1) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index baa7b6fc0a60b1879976c2d4158f73d01e0ca53b..619e30e2c4f028df981383ae26380f652dab173e 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp) LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) - PTR_LA ra, ret_from_irq - PTR_LA v0, plat_irq_dispatch - jr v0 + + /* + * SAVE_ALL ensures we are using a valid kernel stack for the thread. + * Check if we are already using the IRQ stack. + */ + move s1, sp # Preserve the sp + + /* Get IRQ stack for this CPU */ + ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) + lui k1, %hi(irq_stack) +#else + lui k1, %highest(irq_stack) + daddiu k1, %higher(irq_stack) + dsll k1, 16 + daddiu k1, %hi(irq_stack) + dsll k1, 16 +#endif + LONG_SRL k0, SMP_CPUID_PTRSHIFT + LONG_ADDU k1, k0 + LONG_L t0, %lo(irq_stack)(k1) + + # Check if already on IRQ stack + PTR_LI t1, ~(_THREAD_SIZE-1) + and t1, t1, sp + beq t0, t1, 2f + + /* Switch to IRQ stack */ + li t1, _IRQ_STACK_SIZE + PTR_ADD sp, t0, t1 + +2: + jal plat_irq_dispatch + + /* Restore sp */ + move sp, s1 + + j ret_from_irq #ifdef CONFIG_CPU_MICROMIPS nop #endif @@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp) LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) - PTR_LA ra, ret_from_irq - jr v0 + + /* + * SAVE_ALL ensures we are using a valid kernel stack for the thread. + * Check if we are already using the IRQ stack. + */ + move s1, sp # Preserve the sp + + /* Get IRQ stack for this CPU */ + ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) + lui k1, %hi(irq_stack) +#else + lui k1, %highest(irq_stack) + daddiu k1, %higher(irq_stack) + dsll k1, 16 + daddiu k1, %hi(irq_stack) + dsll k1, 16 +#endif + LONG_SRL k0, SMP_CPUID_PTRSHIFT + LONG_ADDU k1, k0 + LONG_L t0, %lo(irq_stack)(k1) + + # Check if already on IRQ stack + PTR_LI t1, ~(_THREAD_SIZE-1) + and t1, t1, sp + beq t0, t1, 2f + + /* Switch to IRQ stack */ + li t1, _IRQ_STACK_SIZE + PTR_ADD sp, t0, t1 + +2: + jalr v0 + + /* Restore sp */ + move sp, s1 + + j ret_from_irq END(except_vec_vi_handler) /* diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 8eb5af8059641311bfeb63b25454778a0f7bddde..dc1180a8bfa163a7c3fe3b2bc8b8b95d34ea17a7 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -25,6 +25,8 @@ #include #include +void *irq_stack[NR_CPUS]; + /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -55,6 +57,15 @@ void __init init_IRQ(void) irq_set_noprobe(i); arch_init_irq(); + + for_each_possible_cpu(i) { + int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; + void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); + + irq_stack[i] = s; + pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, + irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); + } } #ifdef CONFIG_DEBUG_STACKOVERFLOW diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index de63d36af895aaa3aa5e1c0469f9a70a00064bf0..732d6171ac6aeb40e835a45b050d0a3a973116b9 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -244,9 +244,6 @@ static int compute_signal(int tt) void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) { int reg; - struct thread_info *ti = task_thread_info(p); - unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32; - struct pt_regs *regs = (struct pt_regs *)ksp - 1; #if (KGDB_GDB_REG_SIZE == 32) u32 *ptr = (u32 *)gdb_regs; #else @@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) #endif for (reg = 0; reg < 16; reg++) - *(ptr++) = regs->regs[reg]; + *(ptr++) = 0; /* S0 - S7 */ - for (reg = 16; reg < 24; reg++) - *(ptr++) = regs->regs[reg]; + *(ptr++) = p->thread.reg16; + *(ptr++) = p->thread.reg17; + *(ptr++) = p->thread.reg18; + *(ptr++) = p->thread.reg19; + *(ptr++) = p->thread.reg20; + *(ptr++) = p->thread.reg21; + *(ptr++) = p->thread.reg22; + *(ptr++) = p->thread.reg23; for (reg = 24; reg < 28; reg++) *(ptr++) = 0; /* GP, SP, FP, RA */ - for (reg = 28; reg < 32; reg++) - *(ptr++) = regs->regs[reg]; - - *(ptr++) = regs->cp0_status; - *(ptr++) = regs->lo; - *(ptr++) = regs->hi; - *(ptr++) = regs->cp0_badvaddr; - *(ptr++) = regs->cp0_cause; - *(ptr++) = regs->cp0_epc; + *(ptr++) = (long)p; + *(ptr++) = p->thread.reg29; + *(ptr++) = p->thread.reg30; + *(ptr++) = p->thread.reg31; + + *(ptr++) = p->thread.cp0_status; + + /* lo, hi */ + *(ptr++) = 0; + *(ptr++) = 0; + + /* + * BadVAddr, Cause + * Ideally these would come from the last exception frame up the stack + * but that requires unwinding, otherwise we can't know much for sure. + */ + *(ptr++) = 0; + *(ptr++) = 0; + + /* + * PC + * use return address (RA), i.e. the moment after return from resume() + */ + *(ptr++) = p->thread.reg31; } void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index fc537d1b649d516a1b7d879dd75239f74a39ff24..8c26ecac930dd33860fd9fc6356c8f04542aafae 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -552,7 +553,19 @@ EXPORT_SYMBOL(unwind_stack_by_address); unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, unsigned long pc, unsigned long *ra) { - unsigned long stack_page = (unsigned long)task_stack_page(task); + unsigned long stack_page = 0; + int cpu; + + for_each_possible_cpu(cpu) { + if (on_irq_stack(cpu, *sp)) { + stack_page = (unsigned long)irq_stack[cpu]; + break; + } + } + + if (!stack_page) + stack_page = (unsigned long)task_stack_page(task); + return unwind_stack_by_address(stack_page, sp, pc, ra); } #endif diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 74d581569778f5c4a43a4b7062075584049808d6..c95bf18260f89cfb5f5c0e8c2ae17a9babc1051e 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -485,7 +485,8 @@ static int fpr_set(struct task_struct *target, &target->thread.fpu, 0, sizeof(elf_fpregset_t)); - for (i = 0; i < NUM_FPU_REGS; i++) { + BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); + for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) { err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpr_val, i * sizeof(elf_fpreg_t), (i + 1) * sizeof(elf_fpreg_t)); diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 3e390a4e38974b4fb30a19abaebc2473946b05df..daf580ce5ca26445ee97c1c77ee00be6572677de 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -467,7 +467,7 @@ void __init ltq_soc_init(void) if (!np_xbar) panic("Failed to load xbar nodes from devicetree"); - if (of_address_to_resource(np_pmu, 0, &res_xbar)) + if (of_address_to_resource(np_xbar, 0, &res_xbar)) panic("Failed to get xbar resources"); if (request_mem_region(res_xbar.start, resource_size(&res_xbar), res_xbar.name) < 0) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 29f73e00253d94fbd298ff2516fca23d17edddda..63b7d6f82d24378ff88c5739fee157a502382c50 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -757,7 +757,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, struct uasm_label **l, unsigned int pte, - unsigned int ptr) + unsigned int ptr, + unsigned int flush) { #ifdef CONFIG_SMP UASM_i_SC(p, pte, 0, ptr); @@ -766,6 +767,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, #else UASM_i_SW(p, pte, 0, ptr); #endif + if (cpu_has_ftlb && flush) { + BUG_ON(!cpu_has_tlbinv); + + UASM_i_MFC0(p, ptr, C0_ENTRYHI); + uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); + UASM_i_MTC0(p, ptr, C0_ENTRYHI); + build_tlb_write_entry(p, l, r, tlb_indexed); + + uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); + UASM_i_MTC0(p, ptr, C0_ENTRYHI); + build_huge_update_entries(p, pte, ptr); + build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); + + return; + } + build_huge_update_entries(p, pte, ptr); build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); } @@ -2082,7 +2099,7 @@ static void build_r4000_tlb_load_handler(void) uasm_l_tlbl_goaround2(&l, p); } uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); #endif uasm_l_nopage_tlbl(&l, p); @@ -2137,7 +2154,7 @@ static void build_r4000_tlb_store_handler(void) build_tlb_probe_entry(&p); uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); #endif uasm_l_nopage_tlbs(&l, p); @@ -2193,7 +2210,7 @@ static void build_r4000_tlb_modify_handler(void) build_tlb_probe_entry(&p); uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); #endif uasm_l_nopage_tlbm(&l, p); diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index f42834c7f00743e61b3eff8ee09ee9b334086a7a..3c575093f8f1bf82a5b131a6da5de08953f9e595 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c @@ -36,7 +36,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; -static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; +static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; static struct rt2880_pmx_func pci_func[] = { FUNC("pci-dev", 0, 40, 32), FUNC("pci-host2", 1, 40, 32), @@ -44,7 +44,7 @@ static struct rt2880_pmx_func pci_func[] = { FUNC("pci-fnc", 3, 40, 32) }; static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; -static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; +static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; static struct rt2880_pmx_group rt3883_pinmux_data[] = { GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index 718dd197909faf863069bbb085a79b7987ee26af..de73beb36910ad350ebbc9cce83fc1eeb5abedb3 100644 --- a/arch/nios2/kernel/prom.c +++ b/arch/nios2/kernel/prom.c @@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return alloc_bootmem_align(size, align); } +int __init early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, + bool nomap) +{ + reserve_bootmem(base, size, BOOTMEM_DEFAULT); + return 0; +} + void __init early_init_devtree(void *params) { __be32 *dtb = (u32 *)__dtb_start; diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c index a4ff86d58d5cd74c5319e1042622dd2a58345291..6c4e351a7930172111d7db010c57f2970034adf7 100644 --- a/arch/nios2/kernel/setup.c +++ b/arch/nios2/kernel/setup.c @@ -195,6 +195,9 @@ void __init setup_arch(char **cmdline_p) } #endif /* CONFIG_BLK_DEV_INITRD */ + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); + unflatten_and_copy_device_tree(); setup_cpuinfo(); diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 861e72109df2da0b54c98a94584b8b4ff853026b..f080abfc2f83fbd1e7d63846904a3a21ad820cee 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -68,6 +68,7 @@ SECTIONS } #ifdef CONFIG_PPC64_BOOT_WRAPPER + . = ALIGN(256); .got : { __toc_start = .; diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 86150fbb42c39111c7440523f482dbe55e0bd4d9..91e5c1758b5c5deca004b55697500fc7238a1ea6 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -808,14 +808,25 @@ int fix_alignment(struct pt_regs *regs) nb = aligninfo[instr].len; flags = aligninfo[instr].flags; - /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ - if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { - nb = 8; - flags = LD+SW; - } else if (IS_XFORM(instruction) && - ((instruction >> 1) & 0x3ff) == 660) { - nb = 8; - flags = ST+SW; + /* + * Handle some cases which give overlaps in the DSISR values. + */ + if (IS_XFORM(instruction)) { + switch (get_xop(instruction)) { + case 532: /* ldbrx */ + nb = 8; + flags = LD+SW; + break; + case 660: /* stdbrx */ + nb = 8; + flags = ST+SW; + break; + case 20: /* lwarx */ + case 84: /* ldarx */ + case 116: /* lharx */ + case 276: /* lqarx */ + return 0; /* not emulated ever */ + } } /* Byteswap little endian loads and stores */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index edba294620db292a662cd04520e328802c5020c6..f6fd0332c3a2e56cffcd73de354b422b85cedbf2 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -716,7 +716,7 @@ resume_kernel: addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ - lwz r3,GPR1(r1) + ld r3,GPR1(r1) subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ mr r4,r1 /* src: current exception frame */ mr r1,r3 /* Reroute the trampoline frame to r1 */ @@ -730,8 +730,8 @@ resume_kernel: addi r6,r6,8 bdnz 2b - /* Do real store operation to complete stwu */ - lwz r5,GPR1(r1) + /* Do real store operation to complete stdu */ + ld r5,GPR1(r1) std r8,0(r5) /* Clear _TIF_EMULATE_STACK_STORE flag */ diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 5c03a6a9b0542fac3d042f2481f367aae9178d38..a20823210ac0ea94affc37242fab4dc78aeb1c57 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -220,6 +220,15 @@ static void cpu_ready_for_interrupts(void) unsigned long lpcr = mfspr(SPRN_LPCR); mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); } + + /* + * Fixup HFSCR:TM based on CPU features. The bit is set by our + * early asm init because at that point we haven't updated our + * CPU features from firmware and device-tree. Here we have, + * so let's do it. + */ + if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) + mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); } /* diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index 5cc2e7af3a7b96322b9f768a7aadb867ea6b7560..b379146de55bf13d76aa5882dd342148db687fb8 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -302,7 +302,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) advance = 0; printk(KERN_ERR "Couldn't emulate instruction 0x%08x " "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); - kvmppc_core_queue_program(vcpu, 0); } } diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index c8822af10a587389999473171db475eb5462714b..19d9b2d2d212168cf26465e9b5ff9ac789a35d83 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -645,6 +645,10 @@ static void native_flush_hash_range(unsigned long number, int local) unsigned long psize = batch->psize; int ssize = batch->ssize; int i; + unsigned int use_local; + + use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && + mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); local_irq_save(flags); @@ -671,8 +675,7 @@ static void native_flush_hash_range(unsigned long number, int local) } pte_iterate_hashed_end(); } - if (mmu_has_feature(MMU_FTR_TLBIEL) && - mmu_psize_defs[psize].tlbiel && local) { + if (use_local) { asm volatile("ptesync":::"memory"); for (i = 0; i < number; i++) { vpn = batch->vpn[i]; diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index 4da604ebf6fd8edd75eb01951913c79991d0eca5..ca15613eaaa46dae229dc52b6d95626b3d9a4a7a 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size) unsigned long decompress_kernel(void) { - unsigned long output_addr; - unsigned char *output; + void *output, *kernel_end; - output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL; - check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start); - memset(&_bss, 0, &_ebss - &_bss); - free_mem_ptr = (unsigned long)&_end; - free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; - output = (unsigned char *) output_addr; + output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE); + kernel_end = output + SZ__bss_start; + check_ipl_parmblock((void *) 0, (unsigned long) kernel_end); #ifdef CONFIG_BLK_DEV_INITRD /* * Move the initrd right behind the end of the decompressed - * kernel image. + * kernel image. This also prevents initrd corruption caused by + * bss clearing since kernel_end will always be located behind the + * current bss section.. */ - if (INITRD_START && INITRD_SIZE && - INITRD_START < (unsigned long) output + SZ__bss_start) { - check_ipl_parmblock(output + SZ__bss_start, - INITRD_START + INITRD_SIZE); - memmove(output + SZ__bss_start, - (void *) INITRD_START, INITRD_SIZE); - INITRD_START = (unsigned long) output + SZ__bss_start; + if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) { + check_ipl_parmblock(kernel_end, INITRD_SIZE); + memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE); + INITRD_START = (unsigned long) kernel_end; } #endif + /* + * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be + * initialized afterwards since they reside in bss. + */ + memset(&_bss, 0, &_ebss - &_bss); + free_mem_ptr = (unsigned long) &_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + puts("Uncompressing Linux... "); __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); puts("Ok, booting the kernel.\n"); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 024f85f947aec50ea93c881e56a73ba3a5591d3c..e2c0e4eab037c75d4a34e5041e1dd206283e13e2 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -829,6 +829,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; + if (pte_present(entry)) + pte_val(entry) &= ~_PAGE_UNUSED; if (mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); pgste_val(pgste) &= ~_PGSTE_GPS_ZERO; diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 5c7381c5ad7f8a93082497c2776bcb66287efe60..c8d837f0fbbc575a36b43bbba907760583ef53c9 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -150,7 +150,7 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, " jg 2b\n" \ ".popsection\n" \ EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ - : "=d" (__rc), "=Q" (*(to)) \ + : "=d" (__rc), "+Q" (*(to)) \ : "d" (size), "Q" (*(from)), \ "d" (__reg0), "K" (-EFAULT) \ : "cc"); \ diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 3a40f718baefd23b7626555d69babc4fe5c0a6f6..4004e03267cd56bce8633b1931ad9a98f99079fd 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -455,7 +455,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) zdev->dma_table = dma_alloc_cpu_table(); if (!zdev->dma_table) { rc = -ENOMEM; - goto out_clean; + goto out; } /* @@ -475,18 +475,22 @@ int zpci_dma_init_device(struct zpci_dev *zdev) zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); if (!zdev->iommu_bitmap) { rc = -ENOMEM; - goto out_reg; + goto free_dma_table; } rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, (u64) zdev->dma_table); if (rc) - goto out_reg; - return 0; + goto free_bitmap; -out_reg: + return 0; +free_bitmap: + vfree(zdev->iommu_bitmap); + zdev->iommu_bitmap = NULL; +free_dma_table: dma_free_cpu_table(zdev->dma_table); -out_clean: + zdev->dma_table = NULL; +out: return rc; } diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 408b715c95a5cad9ca0790993f9abe6762e9eb87..9d81579f3d54937c2fb2b727e50ac25576f1ab7d 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -668,26 +668,27 @@ static inline unsigned long pmd_pfn(pmd_t pmd) return pte_pfn(pte); } -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -static inline unsigned long pmd_dirty(pmd_t pmd) +#define __HAVE_ARCH_PMD_WRITE +static inline unsigned long pmd_write(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_dirty(pte); + return pte_write(pte); } -static inline unsigned long pmd_young(pmd_t pmd) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline unsigned long pmd_dirty(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_young(pte); + return pte_dirty(pte); } -static inline unsigned long pmd_write(pmd_t pmd) +static inline unsigned long pmd_young(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_write(pte); + return pte_young(pte); } static inline unsigned long pmd_trans_huge(pmd_t pmd) diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 9ddc4928a089b599568331792097c2bc35ea0be8..c1566170964f38cd9d84646402de9af4f41cbd55 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -311,7 +311,7 @@ static int genregs64_set(struct task_struct *target, } if (!ret) { - unsigned long y; + unsigned long y = regs->y; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &y, diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3d3414c14792ab192d84b8a19600b1d3580fd0ae..965655afdbb6da2c867887ff5281fe345446fa7a 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1493,7 +1493,7 @@ bool kern_addr_valid(unsigned long addr) if ((long)addr < 0L) { unsigned long pa = __pa(addr); - if ((addr >> max_phys_bits) != 0UL) + if ((pa >> max_phys_bits) != 0UL) return false; return pfn_valid(pa >> PAGE_SHIFT); diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 440df0c7a2eef7828b31a3c97db4fa110340d339..a69321a7778393f059fc43c4ead83ab1e0cd8d4e 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -219,6 +219,29 @@ static int ghash_async_final(struct ahash_request *req) } } +static int ghash_async_import(struct ahash_request *req, const void *in) +{ + struct ahash_request *cryptd_req = ahash_request_ctx(req); + struct shash_desc *desc = cryptd_shash_desc(cryptd_req); + struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); + + ghash_async_init(req); + memcpy(dctx, in, sizeof(*dctx)); + return 0; + +} + +static int ghash_async_export(struct ahash_request *req, void *out) +{ + struct ahash_request *cryptd_req = ahash_request_ctx(req); + struct shash_desc *desc = cryptd_shash_desc(cryptd_req); + struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); + + memcpy(out, dctx, sizeof(*dctx)); + return 0; + +} + static int ghash_async_digest(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); @@ -288,8 +311,11 @@ static struct ahash_alg ghash_async_alg = { .final = ghash_async_final, .setkey = ghash_async_setkey, .digest = ghash_async_digest, + .export = ghash_async_export, + .import = ghash_async_import, .halg = { .digestsize = GHASH_DIGEST_SIZE, + .statesize = sizeof(struct ghash_desc_ctx), .base = { .cra_name = "ghash", .cra_driver_name = "ghash-clmulni", diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 265c0ed6811800e3b03550cfded0c0cc743794f0..7af017a8958fe9834e53d21d918c373ca7d04f0b 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -187,10 +187,10 @@ vdso_img_insttargets := $(vdso_img_sodbg:%.dbg=install_%) $(MODLIB)/vdso: FORCE @mkdir -p $(MODLIB)/vdso -$(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso FORCE +$(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso $(call cmd,vdso_install) PHONY += vdso_install $(vdso_img_insttargets) -vdso_install: $(vdso_img_insttargets) FORCE +vdso_install: $(vdso_img_insttargets) clean-files := vdso32.so vdso32.so.dbg vdso64* vdso-image-*.c vdsox32.so* diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 08a317a9ae4b582974ec4af4842461bddb762121..a7508d7e20b7cac2e4a158742b6f03d1754ca812 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c @@ -31,8 +31,10 @@ static int __init vdso32_setup(char *s) { vdso32_enabled = simple_strtoul(s, NULL, 0); - if (vdso32_enabled > 1) + if (vdso32_enabled > 1) { pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); + vdso32_enabled = 0; + } return 1; } @@ -63,13 +65,18 @@ subsys_initcall(sysenter_setup); /* Register vsyscall32 into the ABI table */ #include +static const int zero; +static const int one = 1; + static struct ctl_table abi_table2[] = { { .procname = "vsyscall32", .data = &vdso32_enabled, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec + .proc_handler = proc_dointvec_minmax, + .extra1 = (int *)&zero, + .extra2 = (int *)&one, }, {} }; diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 1514753fd43553e079696712b48a8d08b6966e98..d262f985bbc8436884d1ae55274a6a7aebf6e19b 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -278,7 +278,7 @@ struct task_struct; #define ARCH_DLINFO_IA32 \ do { \ - if (vdso32_enabled) { \ + if (VDSO_CURRENT_BASE) { \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } \ diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index d8ce3ec816ab1a86d2d06aca917dae5aae762e40..bd8ce6bcdfc9769a40fd315bcffa030da6638edc 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -72,8 +72,8 @@ static inline void arch_wmb_pmem(void) * @size: number of bytes to write back * * Write back a cache range using the CLWB (cache line write back) - * instruction. This function requires explicit ordering with an - * arch_wmb_pmem() call. This API is internal to the x86 PMEM implementation. + * instruction. Note that @size is internally rounded up to be cache + * line size aligned. */ static inline void __arch_wb_cache_pmem(void *vaddr, size_t size) { @@ -87,15 +87,6 @@ static inline void __arch_wb_cache_pmem(void *vaddr, size_t size) clwb(p); } -/* - * copy_from_iter_nocache() on x86 only uses non-temporal stores for iovec - * iterators, so for other types (bvec & kvec) we must do a cache write-back. - */ -static inline bool __iter_needs_pmem_wb(struct iov_iter *i) -{ - return iter_is_iovec(i) == false; -} - /** * arch_copy_from_iter_pmem - copy data from an iterator to PMEM * @addr: PMEM destination address @@ -114,8 +105,36 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes, /* TODO: skip the write-back by always using non-temporal stores */ len = copy_from_iter_nocache(vaddr, bytes, i); - if (__iter_needs_pmem_wb(i)) - __arch_wb_cache_pmem(vaddr, bytes); + /* + * In the iovec case on x86_64 copy_from_iter_nocache() uses + * non-temporal stores for the bulk of the transfer, but we need + * to manually flush if the transfer is unaligned. A cached + * memory copy is used when destination or size is not naturally + * aligned. That is: + * - Require 8-byte alignment when size is 8 bytes or larger. + * - Require 4-byte alignment when size is 4 bytes. + * + * In the non-iovec case the entire destination needs to be + * flushed. + */ + if (iter_is_iovec(i)) { + unsigned long flushed, dest = (unsigned long) addr; + + if (bytes < 8) { + if (!IS_ALIGNED(dest, 4) || (bytes != 4)) + __arch_wb_cache_pmem(addr, 1); + } else { + if (!IS_ALIGNED(dest, 8)) { + dest = ALIGN(dest, boot_cpu_data.x86_clflush_size); + __arch_wb_cache_pmem(addr, 1); + } + + flushed = dest - (unsigned long) addr; + if (bytes > flushed && !IS_ALIGNED(bytes - flushed, 8)) + __arch_wb_cache_pmem(addr + bytes - 1, 1); + } + } else + __arch_wb_cache_pmem(addr, bytes); return len; } diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index e99b15077e9464b9c9f337873ae58101285e3215..62aca448726a273bfc71a2ce6e202a3364266ed8 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -53,7 +53,7 @@ static const char * const th_names[] = { "load_store", "insn_fetch", "combined_unit", - "", + "decode_unit", "northbridge", "execution_unit", }; diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index cfc4a966e2b9e2a80e1d3349c6dfdbe9c28ea08b..83b5f7a323a9a312965004a4bc8ff81b8cdf3e89 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -30,6 +30,7 @@ #include #include #include +#include struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); @@ -157,6 +158,26 @@ static unsigned char hv_get_nmi_reason(void) return 0; } +#ifdef CONFIG_X86_LOCAL_APIC +/* + * Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes + * it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle + * unknown NMI on the first CPU which gets it. + */ +static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) +{ + static atomic_t nmi_cpu = ATOMIC_INIT(-1); + + if (!unknown_nmi_panic) + return NMI_DONE; + + if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1) + return NMI_HANDLED; + + return NMI_DONE; +} +#endif + static void __init ms_hyperv_init_platform(void) { /* @@ -182,6 +203,9 @@ static void __init ms_hyperv_init_platform(void) printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", lapic_timer_frequency); } + + register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST, + "hv_nmi_unknown"); #endif if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1a8256dd6729afcc1ef6c7686b14c567463fa000..5b2f2306fbcc49426bcb65fbf5e63ffc1d373657 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1996,8 +1996,8 @@ static int x86_pmu_event_init(struct perf_event *event) static void refresh_pce(void *ignored) { - if (current->mm) - load_mm_cr4(current->mm); + if (current->active_mm) + load_mm_cr4(current->active_mm); } static void x86_pmu_event_mapped(struct perf_event *event) diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 659f01e165d57520f33b09ba68818f72cd206a4d..8900400230c623e57e2447b7288796d541c74831 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -410,6 +410,9 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].to = msr_lastbranch.to; cpuc->lbr_entries[i].mispred = 0; cpuc->lbr_entries[i].predicted = 0; + cpuc->lbr_entries[i].in_tx = 0; + cpuc->lbr_entries[i].abort = 0; + cpuc->lbr_entries[i].cycles = 0; cpuc->lbr_entries[i].reserved = 0; } cpuc->lbr_stack.nr = i; diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index eb6bd34582c692f69eb48fc50c44a9b502becd4e..1b96bfe09d42afc08512c28af14a4f1778dd3efd 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -977,6 +977,18 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, unsigned long return_hooker = (unsigned long) &return_to_handler; + /* + * When resuming from suspend-to-ram, this function can be indirectly + * called from early CPU startup code while the CPU is in real mode, + * which would fail miserably. Make sure the stack pointer is a + * virtual address. + * + * This check isn't as accurate as virt_addr_valid(), but it should be + * good enough for this purpose, and it's fast. + */ + if (unlikely((long)__builtin_frame_address(0) >= 0)) + return; + if (unlikely(ftrace_graph_is_dead())) return; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index f129a9af635747ce616e354a43f30297f3fecabf..b6b0077da1af296af7aa7ac451edb2418d8eb75b 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -4,6 +4,7 @@ * Copyright (C) 2000 Andrea Arcangeli SuSE */ +#define DISABLE_BRANCH_PROFILING #include #include #include diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3a7ae80dc49d174b4ac10014208fccbe109002ca..0a472e9865c570174c66443131feea6f03b8a355 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6678,14 +6678,20 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, } page = nested_get_page(vcpu, vmptr); - if (page == NULL || - *(u32 *)kmap(page) != VMCS12_REVISION) { + if (page == NULL) { nested_vmx_failInvalid(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } + if (*(u32 *)kmap(page) != VMCS12_REVISION) { kunmap(page); + nested_release_page_clean(page); + nested_vmx_failInvalid(vcpu); skip_emulated_instruction(vcpu); return 1; } kunmap(page); + nested_release_page_clean(page); vmx->nested.vmxon_ptr = vmptr; break; case EXIT_REASON_VMCLEAR: diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 493f54172b4a5c90b1596708f1d5cb2a0f15156c..3aebbd6c6f5f464065ccc8337ebc16bce8bc091f 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -628,21 +628,40 @@ void __init init_mem_mapping(void) * devmem_is_allowed() checks to see if /dev/mem access to a certain address * is valid. The argument is a physical page number. * - * - * On x86, access has to be given to the first megabyte of ram because that area - * contains BIOS code and data regions used by X and dosemu and similar apps. - * Access has to be given to non-kernel-ram areas as well, these contain the PCI - * mmio resources as well as potential bios/acpi data regions. + * On x86, access has to be given to the first megabyte of RAM because that + * area traditionally contains BIOS code and data regions used by X, dosemu, + * and similar apps. Since they map the entire memory range, the whole range + * must be allowed (for mapping), but any areas that would otherwise be + * disallowed are flagged as being "zero filled" instead of rejected. + * Access has to be given to non-kernel-ram areas as well, these contain the + * PCI mmio resources as well as potential bios/acpi data regions. */ int devmem_is_allowed(unsigned long pagenr) { - if (pagenr < 256) - return 1; - if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) + if (page_is_ram(pagenr)) { + /* + * For disallowed memory regions in the low 1MB range, + * request that the page be shown as all zeros. + */ + if (pagenr < 256) + return 2; + + return 0; + } + + /* + * This must follow RAM test, since System RAM is considered a + * restricted resource under CONFIG_STRICT_IOMEM. + */ + if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) { + /* Low 1MB bypasses iomem restrictions. */ + if (pagenr < 256) + return 1; + return 0; - if (!page_is_ram(pagenr)) - return 1; - return 0; + } + + return 1; } void free_init_pages(char *what, unsigned long begin, unsigned long end) diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index d470cf219a2d8f4608445b47ee8c3307d9929bd8..4e5ac46adc9d47f992cac4221f2ee949cab5dbb5 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -1,3 +1,4 @@ +#define DISABLE_BRANCH_PROFILING #define pr_fmt(fmt) "kasan: " fmt #include #include diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c6d6efed392a0d62a060f0c904f416a0525697a3..7575f07981947ab0f15c622666ceba33181ce182 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -231,23 +231,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return 1; for_each_pci_msi_entry(msidesc, dev) { - __pci_read_msi_msg(msidesc, &msg); - pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | - ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); - if (msg.data != XEN_PIRQ_MSI_DATA || - xen_irq_from_pirq(pirq) < 0) { - pirq = xen_allocate_pirq_msi(dev, msidesc); - if (pirq < 0) { - irq = -ENODEV; - goto error; - } - xen_msi_compose_msg(dev, pirq, &msg); - __pci_write_msi_msg(msidesc, &msg); - dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); - } else { - dev_dbg(&dev->dev, - "xen: msi already bound to pirq=%d\n", pirq); + pirq = xen_allocate_pirq_msi(dev, msidesc); + if (pirq < 0) { + irq = -ENODEV; + goto error; } + xen_msi_compose_msg(dev, pirq, &msg); + __pci_write_msi_msg(msidesc, &msg); + dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, (type == PCI_CAP_ID_MSI) ? nvec : 1, (type == PCI_CAP_ID_MSIX) ? diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index e345891450c3fcc2873a31d352b80afaacf7b74c..df8844a1853a8e17002a2418a75854cd1a69d08e 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -713,10 +713,9 @@ static void __init xen_reserve_xen_mfnlist(void) size = PFN_PHYS(xen_start_info->nr_p2m_frames); } - if (!xen_is_e820_reserved(start, size)) { - memblock_reserve(start, size); + memblock_reserve(start, size); + if (!xen_is_e820_reserved(start, size)) return; - } #ifdef CONFIG_X86_32 /* @@ -727,6 +726,7 @@ static void __init xen_reserve_xen_mfnlist(void) BUG(); #else xen_relocate_p2m(); + memblock_free(start, size); #endif } diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 9e2ba5c6e1dd7be4a0b10a70b315cf5f0f20c081..f42e78de1e107d662e3d806d1dc88ceeaf77ca02 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -27,6 +27,12 @@ static bool xen_pvspin = true; static void xen_qlock_kick(int cpu) { + int irq = per_cpu(lock_kicker_irq, cpu); + + /* Don't kick if the target's kicker interrupt is not initialized. */ + if (irq == -1) + return; + xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); } diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index f1ba6a092854c68017a49f9a4d6fd7c1106bde7f..8846257d8792ef5c19c463fbf5435625edeab6d5 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -343,11 +343,11 @@ static int xen_vcpuop_set_next_event(unsigned long delta, WARN_ON(!clockevent_state_oneshot(evt)); single.timeout_abs_ns = get_abs_timeout(delta); - single.flags = VCPU_SSHOTTMR_future; + /* Get an event anyway, even if the timeout is already expired */ + single.flags = 0; ret = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &single); - - BUG_ON(ret != 0 && ret != -ETIME); + BUG_ON(ret != 0); return ret; } diff --git a/block/bio.c b/block/bio.c index 02c4d9bf159021dd90d552a4a5f0d0f748596372..89782722f3ee287b708964ed35215f6b2191e12b 100644 --- a/block/bio.c +++ b/block/bio.c @@ -375,10 +375,14 @@ static void punt_bios_to_rescuer(struct bio_set *bs) bio_list_init(&punt); bio_list_init(&nopunt); - while ((bio = bio_list_pop(current->bio_list))) + while ((bio = bio_list_pop(¤t->bio_list[0]))) bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); + current->bio_list[0] = nopunt; - *current->bio_list = nopunt; + bio_list_init(&nopunt); + while ((bio = bio_list_pop(¤t->bio_list[1]))) + bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); + current->bio_list[1] = nopunt; spin_lock(&bs->rescue_lock); bio_list_merge(&bs->rescue_list, &punt); @@ -466,7 +470,9 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) * we retry with the original gfp_flags. */ - if (current->bio_list && !bio_list_empty(current->bio_list)) + if (current->bio_list && + (!bio_list_empty(¤t->bio_list[0]) || + !bio_list_empty(¤t->bio_list[1]))) gfp_mask &= ~__GFP_DIRECT_RECLAIM; p = mempool_alloc(bs->bio_pool, gfp_mask); diff --git a/block/blk-core.c b/block/blk-core.c index 500447be3db47ea4038402b51f77ba31b88fe11d..3115494c4cb211a3d1f873bb35391165a2112c65 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2038,7 +2038,14 @@ end_io: */ blk_qc_t generic_make_request(struct bio *bio) { - struct bio_list bio_list_on_stack; + /* + * bio_list_on_stack[0] contains bios submitted by the current + * make_request_fn. + * bio_list_on_stack[1] contains bios that were submitted before + * the current make_request_fn, but that haven't been processed + * yet. + */ + struct bio_list bio_list_on_stack[2]; blk_qc_t ret = BLK_QC_T_NONE; if (!generic_make_request_checks(bio)) @@ -2055,7 +2062,7 @@ blk_qc_t generic_make_request(struct bio *bio) * should be added at the tail */ if (current->bio_list) { - bio_list_add(current->bio_list, bio); + bio_list_add(¤t->bio_list[0], bio); goto out; } @@ -2074,24 +2081,39 @@ blk_qc_t generic_make_request(struct bio *bio) * bio_list, and call into ->make_request() again. */ BUG_ON(bio->bi_next); - bio_list_init(&bio_list_on_stack); - current->bio_list = &bio_list_on_stack; + bio_list_init(&bio_list_on_stack[0]); + current->bio_list = bio_list_on_stack; do { struct request_queue *q = bdev_get_queue(bio->bi_bdev); if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { + struct bio_list lower, same; + + /* Create a fresh bio_list for all subordinate requests */ + bio_list_on_stack[1] = bio_list_on_stack[0]; + bio_list_init(&bio_list_on_stack[0]); ret = q->make_request_fn(q, bio); blk_queue_exit(q); - - bio = bio_list_pop(current->bio_list); + /* sort new bios into those for a lower level + * and those for the same level + */ + bio_list_init(&lower); + bio_list_init(&same); + while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL) + if (q == bdev_get_queue(bio->bi_bdev)) + bio_list_add(&same, bio); + else + bio_list_add(&lower, bio); + /* now assemble so we handle the lowest level first */ + bio_list_merge(&bio_list_on_stack[0], &lower); + bio_list_merge(&bio_list_on_stack[0], &same); + bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]); } else { - struct bio *bio_next = bio_list_pop(current->bio_list); - bio_io_error(bio); - bio = bio_next; } + bio = bio_list_pop(&bio_list_on_stack[0]); } while (bio); current->bio_list = NULL; /* deactivate */ diff --git a/block/blk-mq.c b/block/blk-mq.c index 8bd548378822ee78f01fc79009bcf1fdc1e6f0a3..1452db06ba4568cee7e584010e243f2ba834e81d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1470,7 +1470,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, INIT_LIST_HEAD(&tags->page_list); tags->rqs = kzalloc_node(set->queue_depth * sizeof(struct request *), - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, + GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, set->numa_node); if (!tags->rqs) { blk_mq_free_tags(tags); @@ -1496,7 +1496,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, do { page = alloc_pages_node(set->numa_node, - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, + GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, this_order); if (page) break; @@ -1517,7 +1517,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, * Allow kmemleak to scan these pages as they contain pointers * to additional allocations like via ops->init_request(). */ - kmemleak_alloc(p, order_to_size(this_order), 1, GFP_KERNEL); + kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO); entries_per_page = order_to_size(this_order) / rq_size; to_do = min(entries_per_page, set->queue_depth - i); left -= to_do * rq_size; diff --git a/block/genhd.c b/block/genhd.c index 7f1e8f81ceb4b938d4e823628397bd8a40e68931..de2a6162e3f3ab1b5e606d7966087b1953230ea0 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -673,7 +673,6 @@ void del_gendisk(struct gendisk *disk) kobject_put(disk->part0.holder_dir); kobject_put(disk->slave_dir); - disk->driverfs_dev = NULL; if (!sysfs_deprecated) sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 0774799942e06a8d890a5c88e40990cd53a15037..c6fee7437be44573ade684d064e161954485301a 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) __set_bit(WRITE_16, filter->write_ok); __set_bit(WRITE_LONG, filter->write_ok); __set_bit(WRITE_LONG_2, filter->write_ok); + __set_bit(WRITE_SAME, filter->write_ok); + __set_bit(WRITE_SAME_16, filter->write_ok); + __set_bit(WRITE_SAME_32, filter->write_ok); __set_bit(ERASE, filter->write_ok); __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); __set_bit(MODE_SELECT, filter->write_ok); diff --git a/build.config.goldfish.arm b/build.config.goldfish.arm new file mode 100644 index 0000000000000000000000000000000000000000..866da9361b71102e3f6ba0be60fcc3ff044d2e88 --- /dev/null +++ b/build.config.goldfish.arm @@ -0,0 +1,12 @@ +ARCH=arm +BRANCH=android-4.4 +CROSS_COMPILE=arm-linux-androidkernel- +DEFCONFIG=ranchu_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin +FILES=" +arch/arm/boot/zImage +vmlinux +System.map +" diff --git a/build.config.goldfish.arm64 b/build.config.goldfish.arm64 new file mode 100644 index 0000000000000000000000000000000000000000..9c963cf4a3d8d76737eeb994943bb33fb8a004f4 --- /dev/null +++ b/build.config.goldfish.arm64 @@ -0,0 +1,12 @@ +ARCH=arm64 +BRANCH=android-4.4 +CROSS_COMPILE=aarch64-linux-android- +DEFCONFIG=ranchu64_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin +FILES=" +arch/arm64/boot/Image +vmlinux +System.map +" diff --git a/build.config.goldfish.mips b/build.config.goldfish.mips new file mode 100644 index 0000000000000000000000000000000000000000..8af53d2c294048247d791061ae097a8b88d16fce --- /dev/null +++ b/build.config.goldfish.mips @@ -0,0 +1,11 @@ +ARCH=mips +BRANCH=android-4.4 +CROSS_COMPILE=mips64el-linux-android- +DEFCONFIG=ranchu_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9/bin +FILES=" +vmlinux +System.map +" diff --git a/build.config.goldfish.mips64 b/build.config.goldfish.mips64 new file mode 100644 index 0000000000000000000000000000000000000000..2a33d36dc4c8e8f78ae79902e3a60fa5d6fe0a3d --- /dev/null +++ b/build.config.goldfish.mips64 @@ -0,0 +1,11 @@ +ARCH=mips +BRANCH=android-4.4 +CROSS_COMPILE=mips64el-linux-android- +DEFCONFIG=ranchu64_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9/bin +FILES=" +vmlinux +System.map +" diff --git a/build.config.goldfish.x86 b/build.config.goldfish.x86 new file mode 100644 index 0000000000000000000000000000000000000000..f86253f58d4d17c6b4beaeb74efee11125a299df --- /dev/null +++ b/build.config.goldfish.x86 @@ -0,0 +1,12 @@ +ARCH=x86 +BRANCH=android-4.4 +CROSS_COMPILE=x86_64-linux-android- +DEFCONFIG=i386_ranchu_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin +FILES=" +arch/x86/boot/bzImage +vmlinux +System.map +" diff --git a/build.config.goldfish.x86_64 b/build.config.goldfish.x86_64 new file mode 100644 index 0000000000000000000000000000000000000000..e1738861ec5c25c17234c92a68e9bfe322398bd4 --- /dev/null +++ b/build.config.goldfish.x86_64 @@ -0,0 +1,12 @@ +ARCH=x86_64 +BRANCH=android-4.4 +CROSS_COMPILE=x86_64-linux-android- +DEFCONFIG=x86_64_ranchu_defconfig +EXTRA_CMDS='' +KERNEL_DIR=common +LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin +FILES=" +arch/x86/boot/bzImage +vmlinux +System.map +" diff --git a/crypto/Kconfig b/crypto/Kconfig index 7240821137fde371f0e32d9ae8ac25b64ab58862..3240d394426c046b27b233562a62d3628d7c6866 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -289,6 +289,24 @@ config CRYPTO_CBC CBC: Cipher Block Chaining mode This block cipher algorithm is required for IPSec. +config CRYPTO_HEH + tristate "HEH support" + select CRYPTO_CMAC + select CRYPTO_ECB + select CRYPTO_GF128MUL + select CRYPTO_MANAGER + select CRYPTO_POLY_HASH_ARM64_CE if ARM64 && KERNEL_MODE_NEON + help + HEH: Hash-Encrypt-Hash mode + HEH is a proposed block cipher mode of operation which extends the + strong pseudo-random permutation (SPRP) property of block ciphers to + arbitrary-length input strings. This provides a stronger notion of + security than existing block cipher modes of operation (e.g. CBC, CTR, + XTS), though it is usually less performant. Applications include disk + encryption and encryption of file names and contents. Currently, this + implementation only provides a symmetric cipher interface, so it can't + yet be used as an AEAD. + config CRYPTO_CTR tristate "CTR support" select CRYPTO_BLKCIPHER diff --git a/crypto/Makefile b/crypto/Makefile index 03e66097eb0cde5be07f86a75961c187a4a51f41..8507d1fab3ac18719a554e21c9ee82b762696c93 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o +obj-$(CONFIG_CRYPTO_HEH) += heh.o obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o obj-$(CONFIG_CRYPTO_CTS) += cts.o obj-$(CONFIG_CRYPTO_LRW) += lrw.o diff --git a/crypto/ahash.c b/crypto/ahash.c index dac1c24e9c3e5d0771beeb8bea56e89f1c88efbc..f9caf0f74199c07db313d4fb65712c495025ada9 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -31,6 +31,7 @@ struct ahash_request_priv { crypto_completion_t complete; void *data; u8 *result; + u32 flags; void *ubuf[] CRYPTO_MINALIGN_ATTR; }; @@ -270,6 +271,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) priv->result = req->result; priv->complete = req->base.complete; priv->data = req->base.data; + priv->flags = req->base.flags; + /* * WARNING: We do not backup req->priv here! The req->priv * is for internal use of the Crypto API and the @@ -284,38 +287,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) return 0; } -static void ahash_restore_req(struct ahash_request *req) +static void ahash_restore_req(struct ahash_request *req, int err) { struct ahash_request_priv *priv = req->priv; + if (!err) + memcpy(priv->result, req->result, + crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); + /* Restore the original crypto request. */ req->result = priv->result; - req->base.complete = priv->complete; - req->base.data = priv->data; + + ahash_request_set_callback(req, priv->flags, + priv->complete, priv->data); req->priv = NULL; /* Free the req->priv.priv from the ADJUSTED request. */ kzfree(priv); } -static void ahash_op_unaligned_finish(struct ahash_request *req, int err) +static void ahash_notify_einprogress(struct ahash_request *req) { struct ahash_request_priv *priv = req->priv; + struct crypto_async_request oreq; - if (err == -EINPROGRESS) - return; - - if (!err) - memcpy(priv->result, req->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); + oreq.data = priv->data; - ahash_restore_req(req); + priv->complete(&oreq, -EINPROGRESS); } static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) { struct ahash_request *areq = req->data; + if (err == -EINPROGRESS) { + ahash_notify_einprogress(areq); + return; + } + /* * Restore the original request, see ahash_op_unaligned() for what * goes where. @@ -326,7 +335,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) */ /* First copy req->result into req->priv.result */ - ahash_op_unaligned_finish(areq, err); + ahash_restore_req(areq, err); /* Complete the ORIGINAL request. */ areq->base.complete(&areq->base, err); @@ -342,7 +351,12 @@ static int ahash_op_unaligned(struct ahash_request *req, return err; err = op(req); - ahash_op_unaligned_finish(req, err); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; + + ahash_restore_req(req, err); return err; } @@ -377,25 +391,14 @@ int crypto_ahash_digest(struct ahash_request *req) } EXPORT_SYMBOL_GPL(crypto_ahash_digest); -static void ahash_def_finup_finish2(struct ahash_request *req, int err) +static void ahash_def_finup_done2(struct crypto_async_request *req, int err) { - struct ahash_request_priv *priv = req->priv; + struct ahash_request *areq = req->data; if (err == -EINPROGRESS) return; - if (!err) - memcpy(priv->result, req->result, - crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); - - ahash_restore_req(req); -} - -static void ahash_def_finup_done2(struct crypto_async_request *req, int err) -{ - struct ahash_request *areq = req->data; - - ahash_def_finup_finish2(areq, err); + ahash_restore_req(areq, err); areq->base.complete(&areq->base, err); } @@ -406,11 +409,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err) goto out; req->base.complete = ahash_def_finup_done2; - req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + err = crypto_ahash_reqtfm(req)->final(req); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; out: - ahash_def_finup_finish2(req, err); + ahash_restore_req(req, err); return err; } @@ -418,7 +425,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err) { struct ahash_request *areq = req->data; + if (err == -EINPROGRESS) { + ahash_notify_einprogress(areq); + return; + } + + areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + err = ahash_def_finup_finish1(areq, err); + if (areq->priv) + return; areq->base.complete(&areq->base, err); } @@ -433,6 +449,11 @@ static int ahash_def_finup(struct ahash_request *req) return err; err = tfm->update(req); + if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags(req) & + CRYPTO_TFM_REQ_MAY_BACKLOG))) + return err; + return ahash_def_finup_finish1(req, err); } diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 68a5ceaa04c81072f453a7b2ca2605bed39bd5a1..8d8b3eeba72577704f14056199e151d2e29618cd 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -184,7 +184,7 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags) struct alg_sock *ask = alg_sk(sk); struct hash_ctx *ctx = ask->private; struct ahash_request *req = &ctx->req; - char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))]; + char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req)) ? : 1]; struct sock *sk2; struct alg_sock *ask2; struct hash_ctx *ctx2; diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index dca7bc87dad9d326e39d44d1b62baad5006460da..7bbfadc195a64424ac238170f45e5ed5ca6cf3d4 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c @@ -373,6 +373,27 @@ int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc, } EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block); +/* + * This function allows ablkcipher algorithms to use the blkcipher_walk API to + * walk over their data. The specified crypto_ablkcipher tfm is used to + * initialize the struct blkcipher_walk, and the crypto_blkcipher specified in + * desc->tfm is never used so it can be left NULL. (Yes, this design is ugly, + * but it parallels blkcipher_aead_walk_virt_block() above. In the 4.10 kernel + * this is starting to be cleaned up...) + */ +int blkcipher_ablkcipher_walk_virt(struct blkcipher_desc *desc, + struct blkcipher_walk *walk, + struct crypto_ablkcipher *tfm) +{ + walk->flags &= ~BLKCIPHER_WALK_PHYS; + walk->walk_blocksize = crypto_ablkcipher_blocksize(tfm); + walk->cipher_blocksize = walk->walk_blocksize; + walk->ivsize = crypto_ablkcipher_ivsize(tfm); + walk->alignmask = crypto_ablkcipher_alignmask(tfm); + return blkcipher_walk_first(desc, walk); +} +EXPORT_SYMBOL_GPL(blkcipher_ablkcipher_walk_virt); + static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { diff --git a/crypto/cryptd.c b/crypto/cryptd.c index e7aa904cb20bae034cf9520c5f67fe7da0358cda..26a504db3f530270bd1988e74dfbbf704e65eaec 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -642,6 +642,7 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, inst->alg.halg.base.cra_flags = type; inst->alg.halg.digestsize = salg->digestsize; + inst->alg.halg.statesize = salg->statesize; inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx); inst->alg.halg.base.cra_init = cryptd_hash_init_tfm; diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c index 5276607c72d04ca0e72f1b74a86c2acef1962073..f3d9f6da0767e354c1f1f29e00991a4d805a5cbe 100644 --- a/crypto/gf128mul.c +++ b/crypto/gf128mul.c @@ -44,7 +44,7 @@ --------------------------------------------------------------------------- Issue 31/01/2006 - This file provides fast multiplication in GF(128) as required by several + This file provides fast multiplication in GF(2^128) as required by several cryptographic authentication modes */ @@ -88,37 +88,52 @@ q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) \ } -/* Given the value i in 0..255 as the byte overflow when a field element - in GHASH is multiplied by x^8, this function will return the values that - are generated in the lo 16-bit word of the field value by applying the - modular polynomial. The values lo_byte and hi_byte are returned via the - macro xp_fun(lo_byte, hi_byte) so that the values can be assembled into - memory as required by a suitable definition of this macro operating on - the table above -*/ - -#define xx(p, q) 0x##p##q +/* + * Given a value i in 0..255 as the byte overflow when a field element + * in GF(2^128) is multiplied by x^8, the following macro returns the + * 16-bit value that must be XOR-ed into the low-degree end of the + * product to reduce it modulo the irreducible polynomial x^128 + x^7 + + * x^2 + x + 1. + * + * There are two versions of the macro, and hence two tables: one for + * the "be" convention where the highest-order bit is the coefficient of + * the highest-degree polynomial term, and one for the "le" convention + * where the highest-order bit is the coefficient of the lowest-degree + * polynomial term. In both cases the values are stored in CPU byte + * endianness such that the coefficients are ordered consistently across + * bytes, i.e. in the "be" table bits 15..0 of the stored value + * correspond to the coefficients of x^15..x^0, and in the "le" table + * bits 15..0 correspond to the coefficients of x^0..x^15. + * + * Therefore, provided that the appropriate byte endianness conversions + * are done by the multiplication functions (and these must be in place + * anyway to support both little endian and big endian CPUs), the "be" + * table can be used for multiplications of both "bbe" and "ble" + * elements, and the "le" table can be used for multiplications of both + * "lle" and "lbe" elements. + */ -#define xda_bbe(i) ( \ - (i & 0x80 ? xx(43, 80) : 0) ^ (i & 0x40 ? xx(21, c0) : 0) ^ \ - (i & 0x20 ? xx(10, e0) : 0) ^ (i & 0x10 ? xx(08, 70) : 0) ^ \ - (i & 0x08 ? xx(04, 38) : 0) ^ (i & 0x04 ? xx(02, 1c) : 0) ^ \ - (i & 0x02 ? xx(01, 0e) : 0) ^ (i & 0x01 ? xx(00, 87) : 0) \ +#define xda_be(i) ( \ + (i & 0x80 ? 0x4380 : 0) ^ (i & 0x40 ? 0x21c0 : 0) ^ \ + (i & 0x20 ? 0x10e0 : 0) ^ (i & 0x10 ? 0x0870 : 0) ^ \ + (i & 0x08 ? 0x0438 : 0) ^ (i & 0x04 ? 0x021c : 0) ^ \ + (i & 0x02 ? 0x010e : 0) ^ (i & 0x01 ? 0x0087 : 0) \ ) -#define xda_lle(i) ( \ - (i & 0x80 ? xx(e1, 00) : 0) ^ (i & 0x40 ? xx(70, 80) : 0) ^ \ - (i & 0x20 ? xx(38, 40) : 0) ^ (i & 0x10 ? xx(1c, 20) : 0) ^ \ - (i & 0x08 ? xx(0e, 10) : 0) ^ (i & 0x04 ? xx(07, 08) : 0) ^ \ - (i & 0x02 ? xx(03, 84) : 0) ^ (i & 0x01 ? xx(01, c2) : 0) \ +#define xda_le(i) ( \ + (i & 0x80 ? 0xe100 : 0) ^ (i & 0x40 ? 0x7080 : 0) ^ \ + (i & 0x20 ? 0x3840 : 0) ^ (i & 0x10 ? 0x1c20 : 0) ^ \ + (i & 0x08 ? 0x0e10 : 0) ^ (i & 0x04 ? 0x0708 : 0) ^ \ + (i & 0x02 ? 0x0384 : 0) ^ (i & 0x01 ? 0x01c2 : 0) \ ) -static const u16 gf128mul_table_lle[256] = gf128mul_dat(xda_lle); -static const u16 gf128mul_table_bbe[256] = gf128mul_dat(xda_bbe); +static const u16 gf128mul_table_le[256] = gf128mul_dat(xda_le); +static const u16 gf128mul_table_be[256] = gf128mul_dat(xda_be); -/* These functions multiply a field element by x, by x^4 and by x^8 - * in the polynomial field representation. It uses 32-bit word operations - * to gain speed but compensates for machine endianess and hence works +/* + * The following functions multiply a field element by x or by x^8 in + * the polynomial field representation. They use 64-bit word operations + * to gain speed but compensate for machine endianness and hence work * correctly on both styles of machine. */ @@ -126,7 +141,7 @@ static void gf128mul_x_lle(be128 *r, const be128 *x) { u64 a = be64_to_cpu(x->a); u64 b = be64_to_cpu(x->b); - u64 _tt = gf128mul_table_lle[(b << 7) & 0xff]; + u64 _tt = gf128mul_table_le[(b << 7) & 0xff]; r->b = cpu_to_be64((b >> 1) | (a << 63)); r->a = cpu_to_be64((a >> 1) ^ (_tt << 48)); @@ -136,7 +151,7 @@ static void gf128mul_x_bbe(be128 *r, const be128 *x) { u64 a = be64_to_cpu(x->a); u64 b = be64_to_cpu(x->b); - u64 _tt = gf128mul_table_bbe[a >> 63]; + u64 _tt = gf128mul_table_be[a >> 63]; r->a = cpu_to_be64((a << 1) | (b >> 63)); r->b = cpu_to_be64((b << 1) ^ _tt); @@ -146,7 +161,7 @@ void gf128mul_x_ble(be128 *r, const be128 *x) { u64 a = le64_to_cpu(x->a); u64 b = le64_to_cpu(x->b); - u64 _tt = gf128mul_table_bbe[b >> 63]; + u64 _tt = gf128mul_table_be[b >> 63]; r->a = cpu_to_le64((a << 1) ^ _tt); r->b = cpu_to_le64((b << 1) | (a >> 63)); @@ -157,7 +172,7 @@ static void gf128mul_x8_lle(be128 *x) { u64 a = be64_to_cpu(x->a); u64 b = be64_to_cpu(x->b); - u64 _tt = gf128mul_table_lle[b & 0xff]; + u64 _tt = gf128mul_table_le[b & 0xff]; x->b = cpu_to_be64((b >> 8) | (a << 56)); x->a = cpu_to_be64((a >> 8) ^ (_tt << 48)); @@ -167,12 +182,22 @@ static void gf128mul_x8_bbe(be128 *x) { u64 a = be64_to_cpu(x->a); u64 b = be64_to_cpu(x->b); - u64 _tt = gf128mul_table_bbe[a >> 56]; + u64 _tt = gf128mul_table_be[a >> 56]; x->a = cpu_to_be64((a << 8) | (b >> 56)); x->b = cpu_to_be64((b << 8) ^ _tt); } +static void gf128mul_x8_ble(be128 *x) +{ + u64 a = le64_to_cpu(x->b); + u64 b = le64_to_cpu(x->a); + u64 _tt = gf128mul_table_be[a >> 56]; + + x->b = cpu_to_le64((a << 8) | (b >> 56)); + x->a = cpu_to_le64((b << 8) ^ _tt); +} + void gf128mul_lle(be128 *r, const be128 *b) { be128 p[8]; @@ -249,9 +274,48 @@ void gf128mul_bbe(be128 *r, const be128 *b) } EXPORT_SYMBOL(gf128mul_bbe); +void gf128mul_ble(be128 *r, const be128 *b) +{ + be128 p[8]; + int i; + + p[0] = *r; + for (i = 0; i < 7; ++i) + gf128mul_x_ble((be128 *)&p[i + 1], (be128 *)&p[i]); + + memset(r, 0, sizeof(*r)); + for (i = 0;;) { + u8 ch = ((u8 *)b)[15 - i]; + + if (ch & 0x80) + be128_xor(r, r, &p[7]); + if (ch & 0x40) + be128_xor(r, r, &p[6]); + if (ch & 0x20) + be128_xor(r, r, &p[5]); + if (ch & 0x10) + be128_xor(r, r, &p[4]); + if (ch & 0x08) + be128_xor(r, r, &p[3]); + if (ch & 0x04) + be128_xor(r, r, &p[2]); + if (ch & 0x02) + be128_xor(r, r, &p[1]); + if (ch & 0x01) + be128_xor(r, r, &p[0]); + + if (++i >= 16) + break; + + gf128mul_x8_ble(r); + } +} +EXPORT_SYMBOL(gf128mul_ble); + + /* This version uses 64k bytes of table space. A 16 byte buffer has to be multiplied by a 16 byte key - value in GF(128). If we consider a GF(128) value in + value in GF(2^128). If we consider a GF(2^128) value in the buffer's lowest byte, we can construct a table of the 256 16 byte values that result from the 256 values of this byte. This requires 4096 bytes. But we also @@ -352,8 +416,8 @@ void gf128mul_free_64k(struct gf128mul_64k *t) int i; for (i = 0; i < 16; i++) - kfree(t->t[i]); - kfree(t); + kzfree(t->t[i]); + kzfree(t); } EXPORT_SYMBOL(gf128mul_free_64k); @@ -385,7 +449,7 @@ EXPORT_SYMBOL(gf128mul_64k_bbe); /* This version uses 4k bytes of table space. A 16 byte buffer has to be multiplied by a 16 byte key - value in GF(128). If we consider a GF(128) value in a + value in GF(2^128). If we consider a GF(2^128) value in a single byte, we can construct a table of the 256 16 byte values that result from the 256 values of this byte. This requires 4096 bytes. If we take the highest byte in @@ -443,6 +507,28 @@ out: } EXPORT_SYMBOL(gf128mul_init_4k_bbe); +struct gf128mul_4k *gf128mul_init_4k_ble(const be128 *g) +{ + struct gf128mul_4k *t; + int j, k; + + t = kzalloc(sizeof(*t), GFP_KERNEL); + if (!t) + goto out; + + t->t[1] = *g; + for (j = 1; j <= 64; j <<= 1) + gf128mul_x_ble(&t->t[j + j], &t->t[j]); + + for (j = 2; j < 256; j += j) + for (k = 1; k < j; ++k) + be128_xor(&t->t[j + k], &t->t[j], &t->t[k]); + +out: + return t; +} +EXPORT_SYMBOL(gf128mul_init_4k_ble); + void gf128mul_4k_lle(be128 *a, struct gf128mul_4k *t) { u8 *ap = (u8 *)a; @@ -473,5 +559,20 @@ void gf128mul_4k_bbe(be128 *a, struct gf128mul_4k *t) } EXPORT_SYMBOL(gf128mul_4k_bbe); +void gf128mul_4k_ble(be128 *a, struct gf128mul_4k *t) +{ + u8 *ap = (u8 *)a; + be128 r[1]; + int i = 15; + + *r = t->t[ap[15]]; + while (i--) { + gf128mul_x8_ble(r); + be128_xor(r, r, &t->t[ap[i]]); + } + *a = *r; +} +EXPORT_SYMBOL(gf128mul_4k_ble); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Functions for multiplying elements of GF(2^128)"); diff --git a/crypto/heh.c b/crypto/heh.c new file mode 100644 index 0000000000000000000000000000000000000000..10c00aaf797eb36b648856bf3a40550aa4baf95b --- /dev/null +++ b/crypto/heh.c @@ -0,0 +1,1033 @@ +/* + * HEH: Hash-Encrypt-Hash mode + * + * Copyright (c) 2016 Google Inc. + * + * Authors: + * Alex Cope + * Eric Biggers + */ + +/* + * Hash-Encrypt-Hash (HEH) is a proposed block cipher mode of operation which + * extends the strong pseudo-random permutation (SPRP) property of block ciphers + * (e.g. AES) to arbitrary length input strings. It uses two keyed invertible + * hash functions with a layer of ECB encryption applied in-between. The + * algorithm is specified by the following Internet Draft: + * + * https://tools.ietf.org/html/draft-cope-heh-01 + * + * Although HEH can be used as either a regular symmetric cipher or as an AEAD, + * currently this module only provides it as a symmetric cipher. Additionally, + * only 16-byte nonces are supported. + */ + +#include +#include +#include +#include +#include +#include "internal.h" + +/* + * The block size is the size of GF(2^128) elements and also the required block + * size of the underlying block cipher. + */ +#define HEH_BLOCK_SIZE 16 + +struct heh_instance_ctx { + struct crypto_shash_spawn cmac; + struct crypto_shash_spawn poly_hash; + struct crypto_skcipher_spawn ecb; +}; + +struct heh_tfm_ctx { + struct crypto_shash *cmac; + struct crypto_shash *poly_hash; /* keyed with tau_key */ + struct crypto_ablkcipher *ecb; +}; + +struct heh_cmac_data { + u8 nonce[HEH_BLOCK_SIZE]; + __le32 nonce_length; + __le32 aad_length; + __le32 message_length; + __le32 padding; +}; + +struct heh_req_ctx { /* aligned to alignmask */ + be128 beta1_key; + be128 beta2_key; + union { + struct { + struct heh_cmac_data data; + struct shash_desc desc; + /* + crypto_shash_descsize(cmac) */ + } cmac; + struct { + struct shash_desc desc; + /* + crypto_shash_descsize(poly_hash) */ + } poly_hash; + struct { + u8 keystream[HEH_BLOCK_SIZE]; + u8 tmp[HEH_BLOCK_SIZE]; + struct scatterlist tmp_sgl[2]; + struct ablkcipher_request req; + /* + crypto_ablkcipher_reqsize(ecb) */ + } ecb; + } u; +}; + +/* + * Get the offset in bytes to the last full block, or equivalently the length of + * all full blocks excluding the last + */ +static inline unsigned int get_tail_offset(unsigned int len) +{ + len -= len % HEH_BLOCK_SIZE; + return len - HEH_BLOCK_SIZE; +} + +static inline struct heh_req_ctx *heh_req_ctx(struct ablkcipher_request *req) +{ + unsigned int alignmask = crypto_ablkcipher_alignmask( + crypto_ablkcipher_reqtfm(req)); + + return (void *)PTR_ALIGN((u8 *)ablkcipher_request_ctx(req), + alignmask + 1); +} + +static inline void async_done(struct crypto_async_request *areq, int err, + int (*next_step)(struct ablkcipher_request *, + u32)) +{ + struct ablkcipher_request *req = areq->data; + + if (err) + goto out; + + err = next_step(req, req->base.flags & ~CRYPTO_TFM_REQ_MAY_SLEEP); + if (err == -EINPROGRESS || + (err == -EBUSY && (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))) + return; +out: + ablkcipher_request_complete(req, err); +} + +/* + * Generate the per-message "beta" keys used by the hashing layers of HEH. The + * first beta key is the CMAC of the nonce, the additional authenticated data + * (AAD), and the lengths in bytes of the nonce, AAD, and message. The nonce + * and AAD are each zero-padded to the next 16-byte block boundary, and the + * lengths are serialized as 4-byte little endian integers and zero-padded to + * the next 16-byte block boundary. + * The second beta key is the first one interpreted as an element in GF(2^128) + * and multiplied by x. + * + * Note that because the nonce and AAD may, in general, be variable-length, the + * key generation must be done by a pseudo-random function (PRF) on + * variable-length inputs. CBC-MAC does not satisfy this, as it is only a PRF + * on fixed-length inputs. CMAC remedies this flaw. Including the lengths of + * the nonce, AAD, and message is also critical to avoid collisions. + * + * That being said, this implementation does not yet operate as an AEAD and + * therefore there is never any AAD, nor are variable-length nonces supported. + */ +static int generate_betas(struct ablkcipher_request *req, + be128 *beta1_key, be128 *beta2_key) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct heh_tfm_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct heh_req_ctx *rctx = heh_req_ctx(req); + struct heh_cmac_data *data = &rctx->u.cmac.data; + struct shash_desc *desc = &rctx->u.cmac.desc; + int err; + + BUILD_BUG_ON(sizeof(*data) != 2 * HEH_BLOCK_SIZE); + memcpy(data->nonce, req->info, HEH_BLOCK_SIZE); + data->nonce_length = cpu_to_le32(HEH_BLOCK_SIZE); + data->aad_length = cpu_to_le32(0); + data->message_length = cpu_to_le32(req->nbytes); + data->padding = cpu_to_le32(0); + + desc->tfm = ctx->cmac; + desc->flags = req->base.flags; + + err = crypto_shash_digest(desc, (const u8 *)data, sizeof(*data), + (u8 *)beta1_key); + if (err) + return err; + + gf128mul_x_ble(beta2_key, beta1_key); + return 0; +} + +/*****************************************************************************/ + +/* + * This is the generic version of poly_hash. It does the GF(2^128) + * multiplication by 'tau_key' using a precomputed table, without using any + * special CPU instructions. On some platforms, an accelerated version (with + * higher cra_priority) may be used instead. + */ + +struct poly_hash_tfm_ctx { + struct gf128mul_4k *tau_key; +}; + +struct poly_hash_desc_ctx { + be128 digest; + unsigned int count; +}; + +static int poly_hash_setkey(struct crypto_shash *tfm, + const u8 *key, unsigned int keylen) +{ + struct poly_hash_tfm_ctx *tctx = crypto_shash_ctx(tfm); + be128 key128; + + if (keylen != HEH_BLOCK_SIZE) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + if (tctx->tau_key) + gf128mul_free_4k(tctx->tau_key); + memcpy(&key128, key, HEH_BLOCK_SIZE); + tctx->tau_key = gf128mul_init_4k_ble(&key128); + if (!tctx->tau_key) + return -ENOMEM; + return 0; +} + +static int poly_hash_init(struct shash_desc *desc) +{ + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + + ctx->digest = (be128) { 0 }; + ctx->count = 0; + return 0; +} + +static int poly_hash_update(struct shash_desc *desc, const u8 *src, + unsigned int len) +{ + struct poly_hash_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + unsigned int partial = ctx->count % HEH_BLOCK_SIZE; + u8 *dst = (u8 *)&ctx->digest + partial; + + ctx->count += len; + + /* Finishing at least one block? */ + if (partial + len >= HEH_BLOCK_SIZE) { + + if (partial) { + /* Finish the pending block. */ + unsigned int n = HEH_BLOCK_SIZE - partial; + + len -= n; + do { + *dst++ ^= *src++; + } while (--n); + + gf128mul_4k_ble(&ctx->digest, tctx->tau_key); + } + + /* Process zero or more full blocks. */ + while (len >= HEH_BLOCK_SIZE) { + be128 coeff; + + memcpy(&coeff, src, HEH_BLOCK_SIZE); + be128_xor(&ctx->digest, &ctx->digest, &coeff); + src += HEH_BLOCK_SIZE; + len -= HEH_BLOCK_SIZE; + gf128mul_4k_ble(&ctx->digest, tctx->tau_key); + } + dst = (u8 *)&ctx->digest; + } + + /* Continue adding the next block to 'digest'. */ + while (len--) + *dst++ ^= *src++; + return 0; +} + +static int poly_hash_final(struct shash_desc *desc, u8 *out) +{ + struct poly_hash_desc_ctx *ctx = shash_desc_ctx(desc); + + /* Finish the last block if needed. */ + if (ctx->count % HEH_BLOCK_SIZE) { + struct poly_hash_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + + gf128mul_4k_ble(&ctx->digest, tctx->tau_key); + } + + memcpy(out, &ctx->digest, HEH_BLOCK_SIZE); + return 0; +} + +static void poly_hash_exit(struct crypto_tfm *tfm) +{ + struct poly_hash_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + + gf128mul_free_4k(tctx->tau_key); +} + +static struct shash_alg poly_hash_alg = { + .digestsize = HEH_BLOCK_SIZE, + .init = poly_hash_init, + .update = poly_hash_update, + .final = poly_hash_final, + .setkey = poly_hash_setkey, + .descsize = sizeof(struct poly_hash_desc_ctx), + .base = { + .cra_name = "poly_hash", + .cra_driver_name = "poly_hash-generic", + .cra_priority = 100, + .cra_ctxsize = sizeof(struct poly_hash_tfm_ctx), + .cra_exit = poly_hash_exit, + .cra_module = THIS_MODULE, + }, +}; + +/*****************************************************************************/ + +/* + * Split the message into 16 byte blocks, padding out the last block, and use + * the blocks as coefficients in the evaluation of a polynomial over GF(2^128) + * at the secret point 'tau_key'. For ease of implementing the higher-level + * heh_hash_inv() function, the constant and degree-1 coefficients are swapped + * if there is a partial block. + * + * Mathematically, compute: + * if (no partial block) + * k^{N-1} * m_0 + ... + k * m_{N-2} + m_{N-1} + * else if (partial block) + * k^N * m_0 + ... + k^2 * m_{N-2} + k * m_N + m_{N-1} + * + * where: + * t is tau_key + * N is the number of full blocks in the message + * m_i is the i-th full block in the message for i = 0 to N-1 inclusive + * m_N is the partial block of the message zero-padded up to 16 bytes + * + * Note that most of this is now separated out into its own keyed hash + * algorithm, to allow optimized implementations. However, we still handle the + * swapping of the last two coefficients here in the HEH template because this + * simplifies the poly_hash algorithms: they don't have to buffer an extra + * block, don't have to duplicate as much code, and are more similar to GHASH. + */ +static int poly_hash(struct ablkcipher_request *req, struct scatterlist *sgl, + be128 *hash) +{ + struct heh_req_ctx *rctx = heh_req_ctx(req); + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct heh_tfm_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct shash_desc *desc = &rctx->u.poly_hash.desc; + unsigned int tail_offset = get_tail_offset(req->nbytes); + unsigned int tail_len = req->nbytes - tail_offset; + be128 tail[2]; + unsigned int i, n; + struct sg_mapping_iter miter; + int err; + + desc->tfm = ctx->poly_hash; + desc->flags = req->base.flags; + + /* Handle all full blocks except the last */ + err = crypto_shash_init(desc); + sg_miter_start(&miter, sgl, sg_nents(sgl), + SG_MITER_FROM_SG | SG_MITER_ATOMIC); + for (i = 0; i < tail_offset && !err; i += n) { + sg_miter_next(&miter); + n = min_t(unsigned int, miter.length, tail_offset - i); + err = crypto_shash_update(desc, miter.addr, n); + } + sg_miter_stop(&miter); + if (err) + return err; + + /* Handle the last full block and the partial block */ + scatterwalk_map_and_copy(tail, sgl, tail_offset, tail_len, 0); + + if (tail_len != HEH_BLOCK_SIZE) { + /* handle the partial block */ + memset((u8 *)tail + tail_len, 0, sizeof(tail) - tail_len); + err = crypto_shash_update(desc, (u8 *)&tail[1], HEH_BLOCK_SIZE); + if (err) + return err; + } + err = crypto_shash_final(desc, (u8 *)hash); + if (err) + return err; + be128_xor(hash, hash, &tail[0]); + return 0; +} + +/* + * Transform all full blocks except the last. + * This is used by both the hash and inverse hash phases. + */ +static int heh_tfm_blocks(struct ablkcipher_request *req, + struct scatterlist *src_sgl, + struct scatterlist *dst_sgl, unsigned int len, + const be128 *hash, const be128 *beta_key) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct blkcipher_desc desc = { .flags = req->base.flags }; + struct blkcipher_walk walk; + be128 e = *beta_key; + int err; + unsigned int nbytes; + + blkcipher_walk_init(&walk, dst_sgl, src_sgl, len); + + err = blkcipher_ablkcipher_walk_virt(&desc, &walk, tfm); + + while ((nbytes = walk.nbytes)) { + const be128 *src = (be128 *)walk.src.virt.addr; + be128 *dst = (be128 *)walk.dst.virt.addr; + + do { + gf128mul_x_ble(&e, &e); + be128_xor(dst, src, hash); + be128_xor(dst, dst, &e); + src++; + dst++; + } while ((nbytes -= HEH_BLOCK_SIZE) >= HEH_BLOCK_SIZE); + err = blkcipher_walk_done(&desc, &walk, nbytes); + } + return err; +} + +/* + * The hash phase of HEH. Given a message, compute: + * + * (m_0 + H, ..., m_{N-2} + H, H, m_N) + (xb, x^2b, ..., x^{N-1}b, b, 0) + * + * where: + * N is the number of full blocks in the message + * m_i is the i-th full block in the message for i = 0 to N-1 inclusive + * m_N is the unpadded partial block, possibly empty + * H is the poly_hash() of the message, keyed by tau_key + * b is beta_key + * x is the element x in our representation of GF(2^128) + * + * Note that the partial block remains unchanged, but it does affect the result + * of poly_hash() and therefore the transformation of all the full blocks. + */ +static int heh_hash(struct ablkcipher_request *req, const be128 *beta_key) +{ + be128 hash; + unsigned int tail_offset = get_tail_offset(req->nbytes); + unsigned int partial_len = req->nbytes % HEH_BLOCK_SIZE; + int err; + + /* poly_hash() the full message including the partial block */ + err = poly_hash(req, req->src, &hash); + if (err) + return err; + + /* Transform all full blocks except the last */ + err = heh_tfm_blocks(req, req->src, req->dst, tail_offset, &hash, + beta_key); + if (err) + return err; + + /* Set the last full block to hash XOR beta_key */ + be128_xor(&hash, &hash, beta_key); + scatterwalk_map_and_copy(&hash, req->dst, tail_offset, HEH_BLOCK_SIZE, + 1); + + /* Copy the partial block if needed */ + if (partial_len != 0 && req->src != req->dst) { + unsigned int offs = tail_offset + HEH_BLOCK_SIZE; + + scatterwalk_map_and_copy(&hash, req->src, offs, partial_len, 0); + scatterwalk_map_and_copy(&hash, req->dst, offs, partial_len, 1); + } + return 0; +} + +/* + * The inverse hash phase of HEH. This undoes the result of heh_hash(). + */ +static int heh_hash_inv(struct ablkcipher_request *req, const be128 *beta_key) +{ + be128 hash; + be128 tmp; + struct scatterlist tmp_sgl[2]; + struct scatterlist *tail_sgl; + unsigned int tail_offset = get_tail_offset(req->nbytes); + struct scatterlist *sgl = req->dst; + int err; + + /* + * The last full block was computed as hash XOR beta_key, so XOR it with + * beta_key to recover hash. + */ + tail_sgl = scatterwalk_ffwd(tmp_sgl, sgl, tail_offset); + scatterwalk_map_and_copy(&hash, tail_sgl, 0, HEH_BLOCK_SIZE, 0); + be128_xor(&hash, &hash, beta_key); + + /* Transform all full blocks except the last */ + err = heh_tfm_blocks(req, sgl, sgl, tail_offset, &hash, beta_key); + if (err) + return err; + + /* + * Recover the last full block. We know 'hash', i.e. the poly_hash() of + * the the original message. The last full block was the constant term + * of the polynomial. To recover the last full block, temporarily zero + * it, compute the poly_hash(), and take the difference from 'hash'. + */ + memset(&tmp, 0, sizeof(tmp)); + scatterwalk_map_and_copy(&tmp, tail_sgl, 0, HEH_BLOCK_SIZE, 1); + err = poly_hash(req, sgl, &tmp); + if (err) + return err; + be128_xor(&tmp, &tmp, &hash); + scatterwalk_map_and_copy(&tmp, tail_sgl, 0, HEH_BLOCK_SIZE, 1); + return 0; +} + +static int heh_hash_inv_step(struct ablkcipher_request *req, u32 flags) +{ + struct heh_req_ctx *rctx = heh_req_ctx(req); + + return heh_hash_inv(req, &rctx->beta2_key); +} + +static int heh_ecb_step_3(struct ablkcipher_request *req, u32 flags) +{ + struct heh_req_ctx *rctx = heh_req_ctx(req); + u8 partial_block[HEH_BLOCK_SIZE] __aligned(__alignof__(u32)); + unsigned int tail_offset = get_tail_offset(req->nbytes); + unsigned int partial_offset = tail_offset + HEH_BLOCK_SIZE; + unsigned int partial_len = req->nbytes - partial_offset; + + /* + * Extract the pad in req->dst at tail_offset, and xor the partial block + * with it to create encrypted partial block + */ + scatterwalk_map_and_copy(rctx->u.ecb.keystream, req->dst, tail_offset, + HEH_BLOCK_SIZE, 0); + scatterwalk_map_and_copy(partial_block, req->dst, partial_offset, + partial_len, 0); + crypto_xor(partial_block, rctx->u.ecb.keystream, partial_len); + + /* + * Store the encrypted final block and partial block back in dst_sg + */ + scatterwalk_map_and_copy(&rctx->u.ecb.tmp, req->dst, tail_offset, + HEH_BLOCK_SIZE, 1); + scatterwalk_map_and_copy(partial_block, req->dst, partial_offset, + partial_len, 1); + + return heh_hash_inv_step(req, flags); +} + +static void heh_ecb_step_2_done(struct crypto_async_request *areq, int err) +{ + return async_done(areq, err, heh_ecb_step_3); +} + +static int heh_ecb_step_2(struct ablkcipher_request *req, u32 flags) +{ + struct heh_req_ctx *rctx = heh_req_ctx(req); + unsigned int partial_len = req->nbytes % HEH_BLOCK_SIZE; + struct scatterlist *tmp_sgl; + int err; + unsigned int tail_offset = get_tail_offset(req->nbytes); + + if (partial_len == 0) + return heh_hash_inv_step(req, flags); + + /* + * Extract the final full block, store it in tmp, and then xor that with + * the value saved in u.ecb.keystream + */ + scatterwalk_map_and_copy(rctx->u.ecb.tmp, req->dst, tail_offset, + HEH_BLOCK_SIZE, 0); + crypto_xor(rctx->u.ecb.keystream, rctx->u.ecb.tmp, HEH_BLOCK_SIZE); + + /* + * Encrypt the value in rctx->u.ecb.keystream to create the pad for the + * partial block. + * We cannot encrypt stack buffers, so re-use the dst_sg to do this + * encryption to avoid a malloc. The value at tail_offset is stored in + * tmp, and will be restored later. + */ + scatterwalk_map_and_copy(rctx->u.ecb.keystream, req->dst, tail_offset, + HEH_BLOCK_SIZE, 1); + tmp_sgl = scatterwalk_ffwd(rctx->u.ecb.tmp_sgl, req->dst, tail_offset); + ablkcipher_request_set_callback(&rctx->u.ecb.req, flags, + heh_ecb_step_2_done, req); + ablkcipher_request_set_crypt(&rctx->u.ecb.req, tmp_sgl, tmp_sgl, + HEH_BLOCK_SIZE, NULL); + err = crypto_ablkcipher_encrypt(&rctx->u.ecb.req); + if (err) + return err; + return heh_ecb_step_3(req, flags); +} + +static void heh_ecb_full_done(struct crypto_async_request *areq, int err) +{ + return async_done(areq, err, heh_ecb_step_2); +} + +/* + * The encrypt phase of HEH. This uses ECB encryption, with special handling + * for the partial block at the end if any. The source data is already in + * req->dst, so the encryption happens in-place. + * + * After the encrypt phase we continue on to the inverse hash phase. The + * functions calls are chained to support asynchronous ECB algorithms. + */ +static int heh_ecb(struct ablkcipher_request *req, bool decrypt) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct heh_tfm_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct heh_req_ctx *rctx = heh_req_ctx(req); + struct ablkcipher_request *ecb_req = &rctx->u.ecb.req; + unsigned int tail_offset = get_tail_offset(req->nbytes); + unsigned int full_len = tail_offset + HEH_BLOCK_SIZE; + int err; + + /* + * Save the last full block before it is encrypted/decrypted. This will + * be used later to encrypt/decrypt the partial block + */ + scatterwalk_map_and_copy(rctx->u.ecb.keystream, req->dst, tail_offset, + HEH_BLOCK_SIZE, 0); + + /* Encrypt/decrypt all full blocks */ + ablkcipher_request_set_tfm(ecb_req, ctx->ecb); + ablkcipher_request_set_callback(ecb_req, req->base.flags, + heh_ecb_full_done, req); + ablkcipher_request_set_crypt(ecb_req, req->dst, req->dst, full_len, + NULL); + if (decrypt) + err = crypto_ablkcipher_decrypt(ecb_req); + else + err = crypto_ablkcipher_encrypt(ecb_req); + if (err) + return err; + + return heh_ecb_step_2(req, req->base.flags); +} + +static int heh_crypt(struct ablkcipher_request *req, bool decrypt) +{ + struct heh_req_ctx *rctx = heh_req_ctx(req); + int err; + + /* Inputs must be at least one full block */ + if (req->nbytes < HEH_BLOCK_SIZE) + return -EINVAL; + + err = generate_betas(req, &rctx->beta1_key, &rctx->beta2_key); + if (err) + return err; + + if (decrypt) + swap(rctx->beta1_key, rctx->beta2_key); + + err = heh_hash(req, &rctx->beta1_key); + if (err) + return err; + + return heh_ecb(req, decrypt); +} + +static int heh_encrypt(struct ablkcipher_request *req) +{ + return heh_crypt(req, false); +} + +static int heh_decrypt(struct ablkcipher_request *req) +{ + return heh_crypt(req, true); +} + +static int heh_setkey(struct crypto_ablkcipher *parent, const u8 *key, + unsigned int keylen) +{ + struct heh_tfm_ctx *ctx = crypto_ablkcipher_ctx(parent); + struct crypto_shash *cmac = ctx->cmac; + struct crypto_ablkcipher *ecb = ctx->ecb; + SHASH_DESC_ON_STACK(desc, cmac); + u8 *derived_keys; + u8 digest[HEH_BLOCK_SIZE]; + unsigned int i; + int err; + + /* set prf_key = key */ + crypto_shash_clear_flags(cmac, CRYPTO_TFM_REQ_MASK); + crypto_shash_set_flags(cmac, crypto_ablkcipher_get_flags(parent) & + CRYPTO_TFM_REQ_MASK); + err = crypto_shash_setkey(cmac, key, keylen); + crypto_ablkcipher_set_flags(parent, crypto_shash_get_flags(cmac) & + CRYPTO_TFM_RES_MASK); + if (err) + return err; + + /* + * Generate tau_key and ecb_key as follows: + * tau_key = cmac(prf_key, 0x00...01) + * ecb_key = cmac(prf_key, 0x00...02) || cmac(prf_key, 0x00...03) || ... + * truncated to keylen bytes + */ + derived_keys = kzalloc(round_up(HEH_BLOCK_SIZE + keylen, + HEH_BLOCK_SIZE), GFP_KERNEL); + if (!derived_keys) + return -ENOMEM; + desc->tfm = cmac; + desc->flags = (crypto_shash_get_flags(cmac) & CRYPTO_TFM_REQ_MASK); + for (i = 0; i < keylen + HEH_BLOCK_SIZE; i += HEH_BLOCK_SIZE) { + derived_keys[i + HEH_BLOCK_SIZE - 1] = + 0x01 + i / HEH_BLOCK_SIZE; + err = crypto_shash_digest(desc, derived_keys + i, + HEH_BLOCK_SIZE, digest); + if (err) + goto out; + memcpy(derived_keys + i, digest, HEH_BLOCK_SIZE); + } + + err = crypto_shash_setkey(ctx->poly_hash, derived_keys, HEH_BLOCK_SIZE); + if (err) + goto out; + + crypto_ablkcipher_clear_flags(ecb, CRYPTO_TFM_REQ_MASK); + crypto_ablkcipher_set_flags(ecb, crypto_ablkcipher_get_flags(parent) & + CRYPTO_TFM_REQ_MASK); + err = crypto_ablkcipher_setkey(ecb, derived_keys + HEH_BLOCK_SIZE, + keylen); + crypto_ablkcipher_set_flags(parent, crypto_ablkcipher_get_flags(ecb) & + CRYPTO_TFM_RES_MASK); +out: + kzfree(derived_keys); + return err; +} + +static int heh_init_tfm(struct crypto_tfm *tfm) +{ + struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); + struct heh_instance_ctx *ictx = crypto_instance_ctx(inst); + struct heh_tfm_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_shash *cmac; + struct crypto_shash *poly_hash; + struct crypto_ablkcipher *ecb; + unsigned int reqsize; + int err; + + cmac = crypto_spawn_shash(&ictx->cmac); + if (IS_ERR(cmac)) + return PTR_ERR(cmac); + + poly_hash = crypto_spawn_shash(&ictx->poly_hash); + err = PTR_ERR(poly_hash); + if (IS_ERR(poly_hash)) + goto err_free_cmac; + + ecb = crypto_spawn_skcipher(&ictx->ecb); + err = PTR_ERR(ecb); + if (IS_ERR(ecb)) + goto err_free_poly_hash; + + ctx->cmac = cmac; + ctx->poly_hash = poly_hash; + ctx->ecb = ecb; + + reqsize = crypto_tfm_alg_alignmask(tfm) & + ~(crypto_tfm_ctx_alignment() - 1); + reqsize += max3(offsetof(struct heh_req_ctx, u.cmac.desc) + + sizeof(struct shash_desc) + + crypto_shash_descsize(cmac), + offsetof(struct heh_req_ctx, u.poly_hash.desc) + + sizeof(struct shash_desc) + + crypto_shash_descsize(poly_hash), + offsetof(struct heh_req_ctx, u.ecb.req) + + sizeof(struct ablkcipher_request) + + crypto_ablkcipher_reqsize(ecb)); + tfm->crt_ablkcipher.reqsize = reqsize; + + return 0; + +err_free_poly_hash: + crypto_free_shash(poly_hash); +err_free_cmac: + crypto_free_shash(cmac); + return err; +} + +static void heh_exit_tfm(struct crypto_tfm *tfm) +{ + struct heh_tfm_ctx *ctx = crypto_tfm_ctx(tfm); + + crypto_free_shash(ctx->cmac); + crypto_free_shash(ctx->poly_hash); + crypto_free_ablkcipher(ctx->ecb); +} + +static void heh_free_instance(struct crypto_instance *inst) +{ + struct heh_instance_ctx *ctx = crypto_instance_ctx(inst); + + crypto_drop_shash(&ctx->cmac); + crypto_drop_shash(&ctx->poly_hash); + crypto_drop_skcipher(&ctx->ecb); + kfree(inst); +} + +/* + * Create an instance of HEH as a ablkcipher. + * + * This relies on underlying CMAC and ECB algorithms, usually cmac(aes) and + * ecb(aes). For performance reasons we support asynchronous ECB algorithms. + * However, we do not yet support asynchronous CMAC algorithms because CMAC is + * only used on a small fixed amount of data per request, independent of the + * request length. This would change if AEAD or variable-length nonce support + * were to be exposed. + */ +static int heh_create_common(struct crypto_template *tmpl, struct rtattr **tb, + const char *full_name, const char *cmac_name, + const char *poly_hash_name, const char *ecb_name) +{ + struct crypto_attr_type *algt; + struct crypto_instance *inst; + struct heh_instance_ctx *ctx; + struct shash_alg *cmac; + struct shash_alg *poly_hash; + struct crypto_alg *ecb; + int err; + + algt = crypto_get_attr_type(tb); + if (IS_ERR(algt)) + return PTR_ERR(algt); + + /* User must be asking for something compatible with ablkcipher */ + if ((algt->type ^ CRYPTO_ALG_TYPE_ABLKCIPHER) & algt->mask) + return -EINVAL; + + /* Allocate the ablkcipher instance */ + inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + ctx = crypto_instance_ctx(inst); + + /* Set up the cmac spawn */ + ctx->cmac.base.inst = inst; + err = crypto_grab_shash(&ctx->cmac, cmac_name, 0, 0); + if (err) + goto err_free_inst; + cmac = crypto_spawn_shash_alg(&ctx->cmac); + err = -EINVAL; + if (cmac->digestsize != HEH_BLOCK_SIZE) + goto err_drop_cmac; + + /* Set up the poly_hash spawn */ + ctx->poly_hash.base.inst = inst; + err = crypto_grab_shash(&ctx->poly_hash, poly_hash_name, 0, 0); + if (err) + goto err_drop_cmac; + poly_hash = crypto_spawn_shash_alg(&ctx->poly_hash); + err = -EINVAL; + if (poly_hash->digestsize != HEH_BLOCK_SIZE) + goto err_drop_poly_hash; + + /* Set up the ecb spawn */ + ctx->ecb.base.inst = inst; + err = crypto_grab_skcipher(&ctx->ecb, ecb_name, 0, + crypto_requires_sync(algt->type, + algt->mask)); + if (err) + goto err_drop_poly_hash; + ecb = crypto_skcipher_spawn_alg(&ctx->ecb); + + /* HEH only supports block ciphers with 16 byte block size */ + err = -EINVAL; + if (ecb->cra_blocksize != HEH_BLOCK_SIZE) + goto err_drop_ecb; + + /* The underlying "ECB" algorithm must not require an IV */ + err = -EINVAL; + if ((ecb->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_BLKCIPHER) { + if (ecb->cra_blkcipher.ivsize != 0) + goto err_drop_ecb; + } else { + if (ecb->cra_ablkcipher.ivsize != 0) + goto err_drop_ecb; + } + + /* Set the instance names */ + err = -ENAMETOOLONG; + if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, + "heh_base(%s,%s,%s)", cmac->base.cra_driver_name, + poly_hash->base.cra_driver_name, + ecb->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) + goto err_drop_ecb; + + err = -ENAMETOOLONG; + if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, + "%s", full_name) >= CRYPTO_MAX_ALG_NAME) + goto err_drop_ecb; + + /* Finish initializing the instance */ + + inst->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + (ecb->cra_flags & CRYPTO_ALG_ASYNC); + inst->alg.cra_blocksize = HEH_BLOCK_SIZE; + inst->alg.cra_ctxsize = sizeof(struct heh_tfm_ctx); + inst->alg.cra_alignmask = ecb->cra_alignmask | (__alignof__(be128) - 1); + inst->alg.cra_priority = ecb->cra_priority; + inst->alg.cra_type = &crypto_ablkcipher_type; + inst->alg.cra_init = heh_init_tfm; + inst->alg.cra_exit = heh_exit_tfm; + + inst->alg.cra_ablkcipher.setkey = heh_setkey; + inst->alg.cra_ablkcipher.encrypt = heh_encrypt; + inst->alg.cra_ablkcipher.decrypt = heh_decrypt; + if ((ecb->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_BLKCIPHER) { + inst->alg.cra_ablkcipher.min_keysize = ecb->cra_blkcipher.min_keysize; + inst->alg.cra_ablkcipher.max_keysize = ecb->cra_blkcipher.max_keysize; + } else { + inst->alg.cra_ablkcipher.min_keysize = ecb->cra_ablkcipher.min_keysize; + inst->alg.cra_ablkcipher.max_keysize = ecb->cra_ablkcipher.max_keysize; + } + inst->alg.cra_ablkcipher.ivsize = HEH_BLOCK_SIZE; + + /* Register the instance */ + err = crypto_register_instance(tmpl, inst); + if (err) + goto err_drop_ecb; + return 0; + +err_drop_ecb: + crypto_drop_skcipher(&ctx->ecb); +err_drop_poly_hash: + crypto_drop_shash(&ctx->poly_hash); +err_drop_cmac: + crypto_drop_shash(&ctx->cmac); +err_free_inst: + kfree(inst); + return err; +} + +static int heh_create(struct crypto_template *tmpl, struct rtattr **tb) +{ + const char *cipher_name; + char full_name[CRYPTO_MAX_ALG_NAME]; + char cmac_name[CRYPTO_MAX_ALG_NAME]; + char ecb_name[CRYPTO_MAX_ALG_NAME]; + + /* Get the name of the requested block cipher (e.g. aes) */ + cipher_name = crypto_attr_alg_name(tb[1]); + if (IS_ERR(cipher_name)) + return PTR_ERR(cipher_name); + + if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "heh(%s)", cipher_name) >= + CRYPTO_MAX_ALG_NAME) + return -ENAMETOOLONG; + + if (snprintf(cmac_name, CRYPTO_MAX_ALG_NAME, "cmac(%s)", cipher_name) >= + CRYPTO_MAX_ALG_NAME) + return -ENAMETOOLONG; + + if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", cipher_name) >= + CRYPTO_MAX_ALG_NAME) + return -ENAMETOOLONG; + + return heh_create_common(tmpl, tb, full_name, cmac_name, "poly_hash", + ecb_name); +} + +static struct crypto_template heh_tmpl = { + .name = "heh", + .create = heh_create, + .free = heh_free_instance, + .module = THIS_MODULE, +}; + +static int heh_base_create(struct crypto_template *tmpl, struct rtattr **tb) +{ + char full_name[CRYPTO_MAX_ALG_NAME]; + const char *cmac_name; + const char *poly_hash_name; + const char *ecb_name; + + cmac_name = crypto_attr_alg_name(tb[1]); + if (IS_ERR(cmac_name)) + return PTR_ERR(cmac_name); + + poly_hash_name = crypto_attr_alg_name(tb[2]); + if (IS_ERR(poly_hash_name)) + return PTR_ERR(poly_hash_name); + + ecb_name = crypto_attr_alg_name(tb[3]); + if (IS_ERR(ecb_name)) + return PTR_ERR(ecb_name); + + if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "heh_base(%s,%s,%s)", + cmac_name, poly_hash_name, ecb_name) >= + CRYPTO_MAX_ALG_NAME) + return -ENAMETOOLONG; + + return heh_create_common(tmpl, tb, full_name, cmac_name, poly_hash_name, + ecb_name); +} + +/* + * If HEH is instantiated as "heh_base" instead of "heh", then specific + * implementations of cmac, poly_hash, and ecb can be specified instead of just + * the cipher. + */ +static struct crypto_template heh_base_tmpl = { + .name = "heh_base", + .create = heh_base_create, + .free = heh_free_instance, + .module = THIS_MODULE, +}; + +static int __init heh_module_init(void) +{ + int err; + + err = crypto_register_template(&heh_tmpl); + if (err) + return err; + + err = crypto_register_template(&heh_base_tmpl); + if (err) + goto out_undo_heh; + + err = crypto_register_shash(&poly_hash_alg); + if (err) + goto out_undo_heh_base; + + return 0; + +out_undo_heh_base: + crypto_unregister_template(&heh_base_tmpl); +out_undo_heh: + crypto_unregister_template(&heh_tmpl); + return err; +} + +static void __exit heh_module_exit(void) +{ + crypto_unregister_template(&heh_tmpl); + crypto_unregister_template(&heh_base_tmpl); + crypto_unregister_shash(&poly_hash_alg); +} + +module_init(heh_module_init); +module_exit(heh_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Hash-Encrypt-Hash block cipher mode"); +MODULE_ALIAS_CRYPTO("heh"); +MODULE_ALIAS_CRYPTO("heh_base"); diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c index a0ceb41d5cccc17e7f0932eca3f2dbaa71905865..b4f3930266b11329117e2ea318a36ef1681af3b6 100644 --- a/crypto/mcryptd.c +++ b/crypto/mcryptd.c @@ -531,6 +531,7 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, inst->alg.halg.base.cra_flags = type; inst->alg.halg.digestsize = salg->digestsize; + inst->alg.halg.statesize = salg->statesize; inst->alg.halg.base.cra_ctxsize = sizeof(struct mcryptd_hash_ctx); inst->alg.halg.base.cra_init = mcryptd_hash_init_tfm; diff --git a/crypto/shash.c b/crypto/shash.c index 359754591653c7b265a5e6b89d70e9a9d16d33e3..9ae1e891308d9495d7027a73271424b29c71f0e1 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -683,6 +683,14 @@ void shash_free_instance(struct crypto_instance *inst) } EXPORT_SYMBOL_GPL(shash_free_instance); +int crypto_grab_shash(struct crypto_shash_spawn *spawn, + const char *name, u32 type, u32 mask) +{ + spawn->base.frontend = &crypto_shash_type; + return crypto_grab_spawn(&spawn->base, name, type, mask); +} +EXPORT_SYMBOL_GPL(crypto_grab_shash); + int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn, struct shash_alg *alg, struct crypto_instance *inst) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index d4944318ca1f708356fda74131260446f0b7b16b..6d4da8fd24fde98d1cb9451ac4b5924fcce58bd4 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -488,6 +488,8 @@ static int __test_aead(struct crypto_aead *tfm, int enc, aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &result); + iv_len = crypto_aead_ivsize(tfm); + for (i = 0, j = 0; i < tcount; i++) { if (template[i].np) continue; @@ -508,7 +510,6 @@ static int __test_aead(struct crypto_aead *tfm, int enc, memcpy(input, template[i].input, template[i].ilen); memcpy(assoc, template[i].assoc, template[i].alen); - iv_len = crypto_aead_ivsize(tfm); if (template[i].iv) memcpy(iv, template[i].iv, iv_len); else @@ -617,7 +618,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc, j++; if (template[i].iv) - memcpy(iv, template[i].iv, MAX_IVLEN); + memcpy(iv, template[i].iv, iv_len); else memset(iv, 0, MAX_IVLEN); @@ -3213,6 +3214,21 @@ static const struct alg_test_desc alg_test_descs[] = { .count = GHASH_TEST_VECTORS } } + }, { + .alg = "heh(aes)", + .test = alg_test_skcipher, + .suite = { + .cipher = { + .enc = { + .vecs = aes_heh_enc_tv_template, + .count = AES_HEH_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_heh_dec_tv_template, + .count = AES_HEH_DEC_TEST_VECTORS + } + } + } }, { .alg = "hmac(crc32)", .test = alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 0e02c60a57b66cfc809e0d5736b683fdbc5962f3..ba6530d8ba58ab2ab574667fa88bf3a23ed8cfc9 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -14139,6 +14139,8 @@ static struct cipher_testvec cast6_xts_dec_tv_template[] = { #define AES_DEC_TEST_VECTORS 4 #define AES_CBC_ENC_TEST_VECTORS 5 #define AES_CBC_DEC_TEST_VECTORS 5 +#define AES_HEH_ENC_TEST_VECTORS 4 +#define AES_HEH_DEC_TEST_VECTORS 4 #define HMAC_MD5_ECB_CIPHER_NULL_ENC_TEST_VECTORS 2 #define HMAC_MD5_ECB_CIPHER_NULL_DEC_TEST_VECTORS 2 #define HMAC_SHA1_ECB_CIPHER_NULL_ENC_TEST_VEC 2 @@ -14511,6 +14513,198 @@ static struct cipher_testvec aes_dec_tv_template[] = { }, }; +static struct cipher_testvec aes_heh_enc_tv_template[] = { + { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .ilen = 16, + .result = "\xd8\xbd\x40\xbf\xca\xe5\xee\x81" + "\x0f\x3d\x1f\x1f\xae\x89\x07\x55", + .rlen = 16, + .also_non_np = 1, + .np = 2, + .tap = { 8, 8 }, + }, { + .key = "\xa8\xda\x24\x9b\x5e\xfa\x13\xc2" + "\xc1\x94\xbf\x32\xba\x38\xa3\x77", + .klen = 16, + .iv = "\x4d\x47\x61\x37\x2b\x47\x86\xf0" + "\xd6\x47\xb5\xc2\xe8\xcf\x85\x27", + .input = "\xb8\xee\x29\xe4\xa5\xd1\xe7\x55" + "\xd0\xfd\xe7\x22\x63\x76\x36\xe2" + "\xf8\x0c\xf8\xfe\x65\x76\xe7\xca" + "\xc1\x42\xf5\xca\x5a\xa8\xac\x2a", + .ilen = 32, + .result = "\x59\xf2\x78\x4e\x10\x94\xf9\x5c" + "\x22\x23\x78\x2a\x30\x48\x11\x97" + "\xb1\xfe\x70\xc4\xef\xdf\x04\xef" + "\x16\x39\x04\xcf\xc0\x95\x9a\x98", + .rlen = 32, + .also_non_np = 1, + .np = 3, + .tap = { 16, 13, 3 }, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00", + .ilen = 63, + .result = "\xe0\x40\xeb\xe9\x52\xbe\x65\x60" + "\xe4\x68\x68\xa3\x73\x75\xb8\x52" + "\xef\x38\x6a\x87\x25\x25\xf6\x04" + "\xe5\x8e\xbe\x14\x8b\x02\x14\x1f" + "\xa9\x73\xb7\xad\x15\xbe\x9c\xa0" + "\xd2\x8a\x2c\xdc\xd4\xe3\x05\x55" + "\x0a\xf5\xf8\x51\xee\xe5\x62\xa5" + "\x71\xa7\x7c\x15\x5d\x7a\x9e", + .rlen = 63, + .also_non_np = 1, + .np = 8, + .tap = { 20, 20, 10, 8, 2, 1, 1, 1 }, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00", + .ilen = 63, + .result = "\x4b\x1a\x15\xa0\xaf\x08\x6d\x70" + "\xf0\xa7\x97\xb5\x31\x4b\x8c\xc3" + "\x4d\xf2\x7a\x9d\xdd\xd4\x15\x99" + "\x57\xad\xc6\xb1\x35\x69\xf5\x6a" + "\x2d\x70\xe4\x97\x49\xb2\x9f\x71" + "\xde\x22\xb5\x70\x8c\x69\x24\xd3" + "\xad\x80\x58\x48\x90\xe4\xed\xba" + "\x76\x3d\x71\x7c\x57\x25\x87", + .rlen = 63, + .also_non_np = 1, + .np = 8, + .tap = { 20, 20, 10, 8, 2, 1, 1, 1 }, + } +}; + +static struct cipher_testvec aes_heh_dec_tv_template[] = { + { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\xd8\xbd\x40\xbf\xca\xe5\xee\x81" + "\x0f\x3d\x1f\x1f\xae\x89\x07\x55", + .ilen = 16, + .result = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .rlen = 16, + .also_non_np = 1, + .np = 2, + .tap = { 8, 8 }, + }, { + .key = "\xa8\xda\x24\x9b\x5e\xfa\x13\xc2" + "\xc1\x94\xbf\x32\xba\x38\xa3\x77", + .klen = 16, + .iv = "\x4d\x47\x61\x37\x2b\x47\x86\xf0" + "\xd6\x47\xb5\xc2\xe8\xcf\x85\x27", + .input = "\x59\xf2\x78\x4e\x10\x94\xf9\x5c" + "\x22\x23\x78\x2a\x30\x48\x11\x97" + "\xb1\xfe\x70\xc4\xef\xdf\x04\xef" + "\x16\x39\x04\xcf\xc0\x95\x9a\x98", + .ilen = 32, + .result = "\xb8\xee\x29\xe4\xa5\xd1\xe7\x55" + "\xd0\xfd\xe7\x22\x63\x76\x36\xe2" + "\xf8\x0c\xf8\xfe\x65\x76\xe7\xca" + "\xc1\x42\xf5\xca\x5a\xa8\xac\x2a", + .rlen = 32, + .also_non_np = 1, + .np = 3, + .tap = { 16, 13, 3 }, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\xe0\x40\xeb\xe9\x52\xbe\x65\x60" + "\xe4\x68\x68\xa3\x73\x75\xb8\x52" + "\xef\x38\x6a\x87\x25\x25\xf6\x04" + "\xe5\x8e\xbe\x14\x8b\x02\x14\x1f" + "\xa9\x73\xb7\xad\x15\xbe\x9c\xa0" + "\xd2\x8a\x2c\xdc\xd4\xe3\x05\x55" + "\x0a\xf5\xf8\x51\xee\xe5\x62\xa5" + "\x71\xa7\x7c\x15\x5d\x7a\x9e", + .ilen = 63, + .result = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00", + .rlen = 63, + .also_non_np = 1, + .np = 8, + .tap = { 20, 20, 10, 8, 2, 1, 1, 1 }, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", + .klen = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .input = "\x4b\x1a\x15\xa0\xaf\x08\x6d\x70" + "\xf0\xa7\x97\xb5\x31\x4b\x8c\xc3" + "\x4d\xf2\x7a\x9d\xdd\xd4\x15\x99" + "\x57\xad\xc6\xb1\x35\x69\xf5\x6a" + "\x2d\x70\xe4\x97\x49\xb2\x9f\x71" + "\xde\x22\xb5\x70\x8c\x69\x24\xd3" + "\xad\x80\x58\x48\x90\xe4\xed\xba" + "\x76\x3d\x71\x7c\x57\x25\x87", + .ilen = 63, + .result = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00", + .rlen = 63, + .also_non_np = 1, + .np = 8, + .tap = { 20, 20, 10, 8, 2, 1, 1, 1 }, + } +}; + static struct cipher_testvec aes_cbc_enc_tv_template[] = { { /* From RFC 3602 */ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 675eaf3371789618cdfb21ead69e121844dc006e..b9cebca376f9e6b2ec2fd143cce1d9603886595e 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -2,7 +2,6 @@ # Makefile for the Linux ACPI interpreter # -ccflags-y := -Os ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 296b7a14893aabba895c578e8671e36b34875a37..5365ff6e69c10e5e7b12a2f3c59bdcdad6336509 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -24,9 +24,11 @@ ACPI_MODULE_NAME("platform"); static const struct acpi_device_id forbidden_id_list[] = { - {"PNP0000", 0}, /* PIC */ - {"PNP0100", 0}, /* Timer */ - {"PNP0200", 0}, /* AT DMA Controller */ + {"PNP0000", 0}, /* PIC */ + {"PNP0100", 0}, /* Timer */ + {"PNP0200", 0}, /* AT DMA Controller */ + {"ACPI0009", 0}, /* IOxAPIC */ + {"ACPI000A", 0}, /* IOAPIC */ {"", 0}, }; diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 5fdac394207afabef12a380ef8a20eca4a9bad05..549cdbed7b0e423cae9ee5e69848f818cc8722df 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -1211,6 +1211,9 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) union acpi_object *dod = NULL; union acpi_object *obj; + if (!video->cap._DOD) + return AE_NOT_EXIST; + status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); if (!ACPI_SUCCESS(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 96809cd99ace8c539e5f842639e98ba4bd22502e..2f24b578bcaf1f3e0ec18e5b8bdebdb80feab127 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -346,6 +346,34 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"), }, }, + { + .callback = dmi_enable_rev_override, + .ident = "DELL Precision 5520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"), + }, + }, + { + .callback = dmi_enable_rev_override, + .ident = "DELL Precision 3520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"), + }, + }, + /* + * Resolves a quirk with the Dell Latitude 3350 that + * causes the ethernet adapter to not function. + */ + { + .callback = dmi_enable_rev_override, + .ident = "DELL Latitude 3350", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"), + }, + }, #endif {} }; diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index 14c2a07c9f3ff6a3f9473ce69b72dcd773b9f3c0..67d7489ced016e7c0cc7b1ac5481baea115a1540 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c @@ -979,7 +979,11 @@ static int cmp_map(const void *m0, const void *m1) const struct nfit_set_info_map *map0 = m0; const struct nfit_set_info_map *map1 = m1; - return map0->region_offset - map1->region_offset; + if (map0->region_offset < map1->region_offset) + return -1; + else if (map0->region_offset > map1->region_offset) + return 1; + return 0; } /* Retrieve the nth entry referencing this spa */ diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fcd4ce6f78d5d387080343d96738c3b7275d0324..1c2b846c577604d0b471e87d19cecea6caa286f9 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -200,6 +200,7 @@ static int acpi_power_get_list_state(struct list_head *list, int *state) return -EINVAL; /* The state of the list is 'on' IFF all resources are 'on'. */ + cur_state = 0; list_for_each_entry(entry, list, node) { struct acpi_power_resource *resource = entry->resource; acpi_handle handle = resource->device.handle; diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 37b9eecf5c71bc34f40136190631ddf3e04ab329..d1490be45c6759a7efcc197e82e4986771f66331 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -18,6 +18,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -46,19 +47,11 @@ #include #include "binder_trace.h" -static DEFINE_MUTEX(binder_main_lock); -static DEFINE_MUTEX(binder_deferred_lock); -static DEFINE_MUTEX(binder_mmap_lock); - static HLIST_HEAD(binder_devices); -static HLIST_HEAD(binder_procs); -static HLIST_HEAD(binder_deferred_list); -static HLIST_HEAD(binder_dead_nodes); static struct dentry *binder_debugfs_dir_entry_root; static struct dentry *binder_debugfs_dir_entry_proc; -static int binder_last_id; -static struct workqueue_struct *binder_deferred_workqueue; +atomic_t binder_last_id; #define BINDER_DEBUG_ENTRY(name) \ static int binder_##name##_open(struct inode *inode, struct file *file) \ @@ -173,20 +166,24 @@ enum binder_stat_types { struct binder_stats { int br[_IOC_NR(BR_FAILED_REPLY) + 1]; int bc[_IOC_NR(BC_REPLY_SG) + 1]; - int obj_created[BINDER_STAT_COUNT]; - int obj_deleted[BINDER_STAT_COUNT]; }; -static struct binder_stats binder_stats; +/* These are still global, since it's not always easy to get the context */ +struct binder_obj_stats { + atomic_t obj_created[BINDER_STAT_COUNT]; + atomic_t obj_deleted[BINDER_STAT_COUNT]; +}; + +static struct binder_obj_stats binder_obj_stats; static inline void binder_stats_deleted(enum binder_stat_types type) { - binder_stats.obj_deleted[type]++; + atomic_inc(&binder_obj_stats.obj_deleted[type]); } static inline void binder_stats_created(enum binder_stat_types type) { - binder_stats.obj_created[type]++; + atomic_inc(&binder_obj_stats.obj_created[type]); } struct binder_transaction_log_entry { @@ -207,8 +204,6 @@ struct binder_transaction_log { int full; struct binder_transaction_log_entry entry[32]; }; -static struct binder_transaction_log binder_transaction_log; -static struct binder_transaction_log binder_transaction_log_failed; static struct binder_transaction_log_entry *binder_transaction_log_add( struct binder_transaction_log *log) @@ -229,6 +224,21 @@ struct binder_context { struct binder_node *binder_context_mgr_node; kuid_t binder_context_mgr_uid; const char *name; + + struct mutex binder_main_lock; + struct mutex binder_deferred_lock; + struct mutex binder_mmap_lock; + + struct hlist_head binder_procs; + struct hlist_head binder_dead_nodes; + struct hlist_head binder_deferred_list; + + struct work_struct deferred_work; + struct workqueue_struct *binder_deferred_workqueue; + struct binder_transaction_log transaction_log; + struct binder_transaction_log transaction_log_failed; + + struct binder_stats binder_stats; }; struct binder_device { @@ -459,18 +469,19 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) return retval; } -static inline void binder_lock(const char *tag) +static inline void binder_lock(struct binder_context *context, const char *tag) { trace_binder_lock(tag); - mutex_lock(&binder_main_lock); + mutex_lock(&context->binder_main_lock); preempt_disable(); trace_binder_locked(tag); } -static inline void binder_unlock(const char *tag) +static inline void binder_unlock(struct binder_context *context, + const char *tag) { trace_binder_unlock(tag); - mutex_unlock(&binder_main_lock); + mutex_unlock(&context->binder_main_lock); preempt_enable(); } @@ -1017,7 +1028,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, binder_stats_created(BINDER_STAT_NODE); rb_link_node(&node->rb_node, parent, p); rb_insert_color(&node->rb_node, &proc->nodes); - node->debug_id = ++binder_last_id; + node->debug_id = atomic_inc_return(&binder_last_id); node->proc = proc; node->ptr = ptr; node->cookie = cookie; @@ -1159,7 +1170,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, if (new_ref == NULL) return NULL; binder_stats_created(BINDER_STAT_REF); - new_ref->debug_id = ++binder_last_id; + new_ref->debug_id = atomic_inc_return(&binder_last_id); new_ref->proc = proc; new_ref->node = node; rb_link_node(&new_ref->rb_node_node, parent, p); @@ -1920,7 +1931,7 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; - e = binder_transaction_log_add(&binder_transaction_log); + e = binder_transaction_log_add(&context->transaction_log); e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); e->from_proc = proc->pid; e->from_thread = thread->pid; @@ -2042,7 +2053,7 @@ static void binder_transaction(struct binder_proc *proc, } binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); - t->debug_id = ++binder_last_id; + t->debug_id = atomic_inc_return(&binder_last_id); e->debug_id = t->debug_id; if (reply) @@ -2315,7 +2326,8 @@ err_no_context_mgr_node: { struct binder_transaction_log_entry *fe; - fe = binder_transaction_log_add(&binder_transaction_log_failed); + fe = binder_transaction_log_add( + &context->transaction_log_failed); *fe = *e; } @@ -2343,8 +2355,8 @@ static int binder_thread_write(struct binder_proc *proc, return -EFAULT; ptr += sizeof(uint32_t); trace_binder_command(cmd); - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { - binder_stats.bc[_IOC_NR(cmd)]++; + if (_IOC_NR(cmd) < ARRAY_SIZE(context->binder_stats.bc)) { + context->binder_stats.bc[_IOC_NR(cmd)]++; proc->stats.bc[_IOC_NR(cmd)]++; thread->stats.bc[_IOC_NR(cmd)]++; } @@ -2710,8 +2722,8 @@ static void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, uint32_t cmd) { trace_binder_return(cmd); - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { - binder_stats.br[_IOC_NR(cmd)]++; + if (_IOC_NR(cmd) < ARRAY_SIZE(proc->stats.br)) { + proc->context->binder_stats.br[_IOC_NR(cmd)]++; proc->stats.br[_IOC_NR(cmd)]++; thread->stats.br[_IOC_NR(cmd)]++; } @@ -2775,7 +2787,7 @@ retry: if (wait_for_proc_work) proc->ready_threads++; - binder_unlock(__func__); + binder_unlock(proc->context, __func__); trace_binder_wait_for_work(wait_for_proc_work, !!thread->transaction_stack, @@ -2802,7 +2814,7 @@ retry: ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread)); } - binder_lock(__func__); + binder_lock(proc->context, __func__); if (wait_for_proc_work) proc->ready_threads--; @@ -3188,14 +3200,14 @@ static unsigned int binder_poll(struct file *filp, struct binder_thread *thread = NULL; int wait_for_proc_work; - binder_lock(__func__); + binder_lock(proc->context, __func__); thread = binder_get_thread(proc); wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo) && thread->return_error == BR_OK; - binder_unlock(__func__); + binder_unlock(proc->context, __func__); if (wait_for_proc_work) { if (binder_has_proc_work(proc, thread)) @@ -3322,6 +3334,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret; struct binder_proc *proc = filp->private_data; + struct binder_context *context = proc->context; struct binder_thread *thread; unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; @@ -3335,7 +3348,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (ret) goto err_unlocked; - binder_lock(__func__); + binder_lock(context, __func__); thread = binder_get_thread(proc); if (thread == NULL) { ret = -ENOMEM; @@ -3386,7 +3399,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) err: if (thread) thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; - binder_unlock(__func__); + binder_unlock(context, __func__); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret && ret != -ERESTARTSYS) pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); @@ -3459,7 +3472,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) } vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; - mutex_lock(&binder_mmap_lock); + mutex_lock(&proc->context->binder_mmap_lock); if (proc->buffer) { ret = -EBUSY; failure_string = "already mapped"; @@ -3474,7 +3487,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) } proc->buffer = area->addr; proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; - mutex_unlock(&binder_mmap_lock); + mutex_unlock(&proc->context->binder_mmap_lock); #ifdef CONFIG_CPU_CACHE_VIPT if (cache_is_vipt_aliasing()) { @@ -3523,12 +3536,12 @@ err_alloc_small_buf_failed: kfree(proc->pages); proc->pages = NULL; err_alloc_pages_failed: - mutex_lock(&binder_mmap_lock); + mutex_lock(&proc->context->binder_mmap_lock); vfree(proc->buffer); proc->buffer = NULL; err_get_vm_area_failed: err_already_mapped: - mutex_unlock(&binder_mmap_lock); + mutex_unlock(&proc->context->binder_mmap_lock); err_bad_arg: pr_err("binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); @@ -3555,15 +3568,15 @@ static int binder_open(struct inode *nodp, struct file *filp) miscdev); proc->context = &binder_dev->context; - binder_lock(__func__); + binder_lock(proc->context, __func__); binder_stats_created(BINDER_STAT_PROC); - hlist_add_head(&proc->proc_node, &binder_procs); + hlist_add_head(&proc->proc_node, &proc->context->binder_procs); proc->pid = current->group_leader->pid; INIT_LIST_HEAD(&proc->delivered_death); filp->private_data = proc; - binder_unlock(__func__); + binder_unlock(proc->context, __func__); if (binder_debugfs_dir_entry_proc) { char strbuf[11]; @@ -3628,6 +3641,7 @@ static int binder_release(struct inode *nodp, struct file *filp) static int binder_node_release(struct binder_node *node, int refs) { struct binder_ref *ref; + struct binder_context *context = node->proc->context; int death = 0; list_del_init(&node->work.entry); @@ -3643,7 +3657,7 @@ static int binder_node_release(struct binder_node *node, int refs) node->proc = NULL; node->local_strong_refs = 0; node->local_weak_refs = 0; - hlist_add_head(&node->dead_node, &binder_dead_nodes); + hlist_add_head(&node->dead_node, &context->binder_dead_nodes); hlist_for_each_entry(ref, &node->refs, node_entry) { refs++; @@ -3708,7 +3722,8 @@ static void binder_deferred_release(struct binder_proc *proc) node = rb_entry(n, struct binder_node, rb_node); nodes++; rb_erase(&node->rb_node, &proc->nodes); - incoming_refs = binder_node_release(node, incoming_refs); + incoming_refs = binder_node_release(node, + incoming_refs); } outgoing_refs = 0; @@ -3780,18 +3795,20 @@ static void binder_deferred_func(struct work_struct *work) { struct binder_proc *proc; struct files_struct *files; + struct binder_context *context = + container_of(work, struct binder_context, deferred_work); int defer; do { trace_binder_lock(__func__); - mutex_lock(&binder_main_lock); + mutex_lock(&context->binder_main_lock); trace_binder_locked(__func__); - mutex_lock(&binder_deferred_lock); + mutex_lock(&context->binder_deferred_lock); preempt_disable(); - if (!hlist_empty(&binder_deferred_list)) { - proc = hlist_entry(binder_deferred_list.first, + if (!hlist_empty(&context->binder_deferred_list)) { + proc = hlist_entry(context->binder_deferred_list.first, struct binder_proc, deferred_work_node); hlist_del_init(&proc->deferred_work_node); defer = proc->deferred_work; @@ -3800,7 +3817,7 @@ static void binder_deferred_func(struct work_struct *work) proc = NULL; defer = 0; } - mutex_unlock(&binder_deferred_lock); + mutex_unlock(&context->binder_deferred_lock); files = NULL; if (defer & BINDER_DEFERRED_PUT_FILES) { @@ -3816,25 +3833,25 @@ static void binder_deferred_func(struct work_struct *work) binder_deferred_release(proc); /* frees proc */ trace_binder_unlock(__func__); - mutex_unlock(&binder_main_lock); + mutex_unlock(&context->binder_main_lock); preempt_enable_no_resched(); if (files) put_files_struct(files); } while (proc); } -static DECLARE_WORK(binder_deferred_work, binder_deferred_func); static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) { - mutex_lock(&binder_deferred_lock); + mutex_lock(&proc->context->binder_deferred_lock); proc->deferred_work |= defer; if (hlist_unhashed(&proc->deferred_work_node)) { hlist_add_head(&proc->deferred_work_node, - &binder_deferred_list); - queue_work(binder_deferred_workqueue, &binder_deferred_work); + &proc->context->binder_deferred_list); + queue_work(proc->context->binder_deferred_workqueue, + &proc->context->deferred_work); } - mutex_unlock(&binder_deferred_lock); + mutex_unlock(&proc->context->binder_deferred_lock); } static void print_binder_transaction(struct seq_file *m, const char *prefix, @@ -4065,8 +4082,20 @@ static const char * const binder_objstat_strings[] = { "transaction_complete" }; +static void add_binder_stats(struct binder_stats *from, struct binder_stats *to) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(to->bc); i++) + to->bc[i] += from->bc[i]; + + for (i = 0; i < ARRAY_SIZE(to->br); i++) + to->br[i] += from->br[i]; +} + static void print_binder_stats(struct seq_file *m, const char *prefix, - struct binder_stats *stats) + struct binder_stats *stats, + struct binder_obj_stats *obj_stats) { int i; @@ -4086,16 +4115,21 @@ static void print_binder_stats(struct seq_file *m, const char *prefix, binder_return_strings[i], stats->br[i]); } - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != + if (!obj_stats) + return; + + BUILD_BUG_ON(ARRAY_SIZE(obj_stats->obj_created) != ARRAY_SIZE(binder_objstat_strings)); - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(stats->obj_deleted)); - for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { - if (stats->obj_created[i] || stats->obj_deleted[i]) + BUILD_BUG_ON(ARRAY_SIZE(obj_stats->obj_created) != + ARRAY_SIZE(obj_stats->obj_deleted)); + for (i = 0; i < ARRAY_SIZE(obj_stats->obj_created); i++) { + int obj_created = atomic_read(&obj_stats->obj_created[i]); + int obj_deleted = atomic_read(&obj_stats->obj_deleted[i]); + + if (obj_created || obj_deleted) seq_printf(m, "%s%s: active %d total %d\n", prefix, - binder_objstat_strings[i], - stats->obj_created[i] - stats->obj_deleted[i], - stats->obj_created[i]); + binder_objstat_strings[i], + obj_created - obj_deleted, obj_created); } } @@ -4150,85 +4184,131 @@ static void print_binder_proc_stats(struct seq_file *m, } seq_printf(m, " pending transactions: %d\n", count); - print_binder_stats(m, " ", &proc->stats); + print_binder_stats(m, " ", &proc->stats, NULL); } static int binder_state_show(struct seq_file *m, void *unused) { + struct binder_device *device; + struct binder_context *context; struct binder_proc *proc; struct binder_node *node; int do_lock = !binder_debug_no_lock; - - if (do_lock) - binder_lock(__func__); + bool wrote_dead_nodes_header = false; seq_puts(m, "binder state:\n"); - if (!hlist_empty(&binder_dead_nodes)) - seq_puts(m, "dead nodes:\n"); - hlist_for_each_entry(node, &binder_dead_nodes, dead_node) - print_binder_node(m, node); + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); + if (!wrote_dead_nodes_header && + !hlist_empty(&context->binder_dead_nodes)) { + seq_puts(m, "dead nodes:\n"); + wrote_dead_nodes_header = true; + } + hlist_for_each_entry(node, &context->binder_dead_nodes, + dead_node) + print_binder_node(m, node); + + if (do_lock) + binder_unlock(context, __func__); + } - hlist_for_each_entry(proc, &binder_procs, proc_node) - print_binder_proc(m, proc, 1); - if (do_lock) - binder_unlock(__func__); + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); + + hlist_for_each_entry(proc, &context->binder_procs, proc_node) + print_binder_proc(m, proc, 1); + if (do_lock) + binder_unlock(context, __func__); + } return 0; } static int binder_stats_show(struct seq_file *m, void *unused) { + struct binder_device *device; + struct binder_context *context; struct binder_proc *proc; + struct binder_stats total_binder_stats; int do_lock = !binder_debug_no_lock; - if (do_lock) - binder_lock(__func__); + memset(&total_binder_stats, 0, sizeof(struct binder_stats)); + + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); + + add_binder_stats(&context->binder_stats, &total_binder_stats); + + if (do_lock) + binder_unlock(context, __func__); + } seq_puts(m, "binder stats:\n"); + print_binder_stats(m, "", &total_binder_stats, &binder_obj_stats); - print_binder_stats(m, "", &binder_stats); + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); - hlist_for_each_entry(proc, &binder_procs, proc_node) - print_binder_proc_stats(m, proc); - if (do_lock) - binder_unlock(__func__); + hlist_for_each_entry(proc, &context->binder_procs, proc_node) + print_binder_proc_stats(m, proc); + if (do_lock) + binder_unlock(context, __func__); + } return 0; } static int binder_transactions_show(struct seq_file *m, void *unused) { + struct binder_device *device; + struct binder_context *context; struct binder_proc *proc; int do_lock = !binder_debug_no_lock; - if (do_lock) - binder_lock(__func__); - seq_puts(m, "binder transactions:\n"); - hlist_for_each_entry(proc, &binder_procs, proc_node) - print_binder_proc(m, proc, 0); - if (do_lock) - binder_unlock(__func__); + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); + + hlist_for_each_entry(proc, &context->binder_procs, proc_node) + print_binder_proc(m, proc, 0); + if (do_lock) + binder_unlock(context, __func__); + } return 0; } static int binder_proc_show(struct seq_file *m, void *unused) { + struct binder_device *device; + struct binder_context *context; struct binder_proc *itr; int pid = (unsigned long)m->private; int do_lock = !binder_debug_no_lock; - if (do_lock) - binder_lock(__func__); + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + if (do_lock) + binder_lock(context, __func__); - hlist_for_each_entry(itr, &binder_procs, proc_node) { - if (itr->pid == pid) { - seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, itr, 1); + hlist_for_each_entry(itr, &context->binder_procs, proc_node) { + if (itr->pid == pid) { + seq_puts(m, "binder proc state:\n"); + print_binder_proc(m, itr, 1); + } } + if (do_lock) + binder_unlock(context, __func__); } - if (do_lock) - binder_unlock(__func__); return 0; } @@ -4243,11 +4323,10 @@ static void print_binder_transaction_log_entry(struct seq_file *m, e->to_node, e->target_handle, e->data_size, e->offsets_size); } -static int binder_transaction_log_show(struct seq_file *m, void *unused) +static int print_binder_transaction_log(struct seq_file *m, + struct binder_transaction_log *log) { - struct binder_transaction_log *log = m->private; int i; - if (log->full) { for (i = log->next; i < ARRAY_SIZE(log->entry); i++) print_binder_transaction_log_entry(m, &log->entry[i]); @@ -4257,6 +4336,31 @@ static int binder_transaction_log_show(struct seq_file *m, void *unused) return 0; } +static int binder_transaction_log_show(struct seq_file *m, void *unused) +{ + struct binder_device *device; + struct binder_context *context; + + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + print_binder_transaction_log(m, &context->transaction_log); + } + return 0; +} + +static int binder_failed_transaction_log_show(struct seq_file *m, void *unused) +{ + struct binder_device *device; + struct binder_context *context; + + hlist_for_each_entry(device, &binder_devices, hlist) { + context = &device->context; + print_binder_transaction_log(m, + &context->transaction_log_failed); + } + return 0; +} + static const struct file_operations binder_fops = { .owner = THIS_MODULE, .poll = binder_poll, @@ -4272,11 +4376,20 @@ BINDER_DEBUG_ENTRY(state); BINDER_DEBUG_ENTRY(stats); BINDER_DEBUG_ENTRY(transactions); BINDER_DEBUG_ENTRY(transaction_log); +BINDER_DEBUG_ENTRY(failed_transaction_log); + +static void __init free_binder_device(struct binder_device *device) +{ + if (device->context.binder_deferred_workqueue) + destroy_workqueue(device->context.binder_deferred_workqueue); + kfree(device); +} static int __init init_binder_device(const char *name) { int ret; struct binder_device *binder_device; + struct binder_context *context; binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL); if (!binder_device) @@ -4286,31 +4399,65 @@ static int __init init_binder_device(const char *name) binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; binder_device->miscdev.name = name; - binder_device->context.binder_context_mgr_uid = INVALID_UID; - binder_device->context.name = name; + context = &binder_device->context; + context->binder_context_mgr_uid = INVALID_UID; + context->name = name; + + mutex_init(&context->binder_main_lock); + mutex_init(&context->binder_deferred_lock); + mutex_init(&context->binder_mmap_lock); + + context->binder_deferred_workqueue = + create_singlethread_workqueue(name); + + if (!context->binder_deferred_workqueue) { + ret = -ENOMEM; + goto err_create_singlethread_workqueue_failed; + } + + INIT_HLIST_HEAD(&context->binder_procs); + INIT_HLIST_HEAD(&context->binder_dead_nodes); + INIT_HLIST_HEAD(&context->binder_deferred_list); + INIT_WORK(&context->deferred_work, binder_deferred_func); ret = misc_register(&binder_device->miscdev); if (ret < 0) { - kfree(binder_device); - return ret; + goto err_misc_register_failed; } hlist_add_head(&binder_device->hlist, &binder_devices); + return ret; + +err_create_singlethread_workqueue_failed: +err_misc_register_failed: + free_binder_device(binder_device); return ret; } static int __init binder_init(void) { - int ret; + int ret = 0; char *device_name, *device_names; struct binder_device *device; struct hlist_node *tmp; - binder_deferred_workqueue = create_singlethread_workqueue("binder"); - if (!binder_deferred_workqueue) + /* + * Copy the module_parameter string, because we don't want to + * tokenize it in-place. + */ + device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL); + if (!device_names) return -ENOMEM; + strcpy(device_names, binder_devices_param); + + while ((device_name = strsep(&device_names, ","))) { + ret = init_binder_device(device_name); + if (ret) + goto err_init_binder_device_failed; + } + binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); if (binder_debugfs_dir_entry_root) binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", @@ -4335,30 +4482,13 @@ static int __init binder_init(void) debugfs_create_file("transaction_log", S_IRUGO, binder_debugfs_dir_entry_root, - &binder_transaction_log, + NULL, &binder_transaction_log_fops); debugfs_create_file("failed_transaction_log", S_IRUGO, binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); - } - - /* - * Copy the module_parameter string, because we don't want to - * tokenize it in-place. - */ - device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL); - if (!device_names) { - ret = -ENOMEM; - goto err_alloc_device_names_failed; - } - strcpy(device_names, binder_devices_param); - - while ((device_name = strsep(&device_names, ","))) { - ret = init_binder_device(device_name); - if (ret) - goto err_init_binder_device_failed; + NULL, + &binder_failed_transaction_log_fops); } return ret; @@ -4367,12 +4497,8 @@ err_init_binder_device_failed: hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) { misc_deregister(&device->miscdev); hlist_del(&device->hlist); - kfree(device); + free_binder_device(device); } -err_alloc_device_names_failed: - debugfs_remove_recursive(binder_debugfs_dir_entry_root); - - destroy_workqueue(binder_deferred_workqueue); return ret; } diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 09c07f519952d7afa342fb8e1156c6f15497f9c8..0e494108c20ccec68abb460ccf2f1853976fb6b9 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -1042,7 +1042,7 @@ static int print_wakeup_source_stats(struct seq_file *m, active_time = ktime_set(0, 0); } - seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n", + seq_printf(m, "%-32s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n", ws->name, active_count, ws->event_count, ws->wakeup_count, ws->expire_count, ktime_to_ms(active_time), ktime_to_ms(total_time), @@ -1062,7 +1062,7 @@ static int wakeup_sources_stats_show(struct seq_file *m, void *unused) { struct wakeup_source *ws; - seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t" + seq_puts(m, "name\t\t\t\t\tactive_count\tevent_count\twakeup_count\t" "expire_count\tactive_since\ttotal_time\tmax_time\t" "last_change\tprevent_suspend_time\n"); diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 9462d27528507d693d8e4efe0e6464597ab1768b..8bdc34dbaedfc94eb4b9c469bef8d4c9c09a9254 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device) * this masks out the remaining bits. * Returns the number of bits cleared. */ +#ifndef BITS_PER_PAGE #define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3)) #define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1) +#else +# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3)) +# error "ambiguous BITS_PER_PAGE" +# endif +#endif #define BITS_PER_LONG_MASK (BITS_PER_LONG - 1) static int bm_clear_surplus(struct drbd_bitmap *b) { diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 76ac3179f25c9906372c121918f634705c4b1dc7..c5a2057ef6681de751aea3825de12e5e7be6cac4 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -581,13 +581,13 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) { bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); - clear_page(mem); + memset(mem, 0, PAGE_SIZE); return 0; } cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) - copy_page(mem, cmem); + memcpy(mem, cmem, PAGE_SIZE); else ret = zcomp_decompress(zram->comp, cmem, size, mem); zs_unmap_object(meta->mem_pool, handle); @@ -750,7 +750,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) { src = kmap_atomic(page); - copy_page(cmem, src); + memcpy(cmem, src, PAGE_SIZE); kunmap_atomic(src); } else { memcpy(cmem, src, clen); diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c index b05b999fbbdc167f08ca247f7fe5d08468d056a8..59245ba320f6ebc71e01d4f574352c2053195ddb 100644 --- a/drivers/bluetooth/bluetooth-power.c +++ b/drivers/bluetooth/bluetooth-power.c @@ -704,6 +704,7 @@ static long bt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } else { BT_PWR_ERR("BT chip state is already :%d no change d\n" , pwr_state); + ret = 0; } break; default: diff --git a/drivers/bluetooth/btfm_slim.h b/drivers/bluetooth/btfm_slim.h index 5d105fba21938ff7e7178637666f2287d4e5952b..e67c6964ee6574aaec9e839b094cab7f8132e8aa 100644 --- a/drivers/bluetooth/btfm_slim.h +++ b/drivers/bluetooth/btfm_slim.h @@ -13,7 +13,7 @@ #define BTFM_SLIM_H #include -#define BTFMSLIM_DBG(fmt, arg...) pr_debug(fmt "\n", ## arg) +#define BTFMSLIM_DBG(fmt, arg...) pr_debug("%s: " fmt "\n", __func__, ## arg) #define BTFMSLIM_INFO(fmt, arg...) pr_info("%s: " fmt "\n", __func__, ## arg) #define BTFMSLIM_ERR(fmt, arg...) pr_err("%s: " fmt "\n", __func__, ## arg) diff --git a/drivers/bluetooth/btfm_slim_codec.c b/drivers/bluetooth/btfm_slim_codec.c index 1ed366fd3d7164faf76c3cfd8f67ae787eaead3d..4dd8e6833ccf4799e144849330be15d4d6030fcb 100644 --- a/drivers/bluetooth/btfm_slim_codec.c +++ b/drivers/bluetooth/btfm_slim_codec.c @@ -332,6 +332,9 @@ static int btfm_slim_dai_get_channel_map(struct snd_soc_dai *dai, *tx_num = 0; *rx_num = num; break; + default: + BTFMSLIM_ERR("Unsupported DAI %d", dai->id); + return -EINVAL; } do { diff --git a/drivers/bluetooth/btfm_slim_wcn3990.c b/drivers/bluetooth/btfm_slim_wcn3990.c index d61454ac6e849b3bdb6b3702b9455e050b9e2e7b..a451ff33103c45facba2fe68e194c29950372723 100644 --- a/drivers/bluetooth/btfm_slim_wcn3990.c +++ b/drivers/bluetooth/btfm_slim_wcn3990.c @@ -69,28 +69,49 @@ error: return ret; } +static inline int is_fm_port(uint8_t port_num) +{ + if (port_num == CHRK_SB_PGD_PORT_TX1_FM || + port_num == CHRK_SB_PGD_PORT_TX2_FM) + return 1; + else + return 0; +} int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, uint8_t rxport, uint8_t enable) { int ret = 0; uint8_t reg_val = 0; + uint8_t port_bit = 0; uint16_t reg; BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable); if (rxport) { + if (enable) { + /* For SCO Rx, A2DP Rx */ + reg_val = 0x1; + port_bit = port_num - 0x10; + reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(port_bit); + BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)", + reg_val, reg); + ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); + if (ret) { + BTFMSLIM_ERR("failed to write (%d) reg 0x%x", + ret, reg); + goto error; + } + } /* Port enable */ reg = CHRK_SB_PGD_PORT_RX_CFGN(port_num - 0x10); goto enable_disable_rxport; } - /* txport */ if (!enable) goto enable_disable_txport; - /* Multiple Channel Setting - only for FM Tx */ - if (port_num == CHRK_SB_PGD_PORT_TX1_FM || - port_num == CHRK_SB_PGD_PORT_TX2_FM) { - + /* txport */ + /* Multiple Channel Setting */ + if (is_fm_port(port_num)) { reg_val = (0x1 << CHRK_SB_PGD_PORT_TX1_FM) | (0x1 << CHRK_SB_PGD_PORT_TX2_FM); reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num); @@ -99,6 +120,18 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg); goto error; } + } else if (port_num == CHRK_SB_PGD_PORT_TX_SCO) { + /* SCO Tx */ + reg_val = 0x1 << CHRK_SB_PGD_PORT_TX_SCO; + reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num); + BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)", + reg_val, reg); + ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); + if (ret) { + BTFMSLIM_ERR("failed to write (%d) reg 0x%x", + ret, reg); + goto error; + } } /* Enable Tx port hw auto recovery for underrun or overrun error */ @@ -116,10 +149,14 @@ enable_disable_txport: reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num); enable_disable_rxport: - if (enable) - /* Set water mark to 1 and enable the port */ - reg_val = CHRK_SB_PGD_PORT_ENABLE | CHRK_SB_PGD_PORT_WM_LB; - else + if (enable) { + if (is_fm_port(port_num)) + reg_val = CHRK_SB_PGD_PORT_ENABLE | + CHRK_SB_PGD_PORT_WM_L3; + else + reg_val = CHRK_SB_PGD_PORT_ENABLE | + CHRK_SB_PGD_PORT_WM_LB; + } else reg_val = CHRK_SB_PGD_PORT_DISABLE; ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ebbe31fee7ae02344b96e33a07ac2d4722ffe9b5..db8eb7ccd74494bd9366e51dbfb70e5d91c6879c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -585,13 +585,25 @@ config TELCLOCK controlling the behavior of this hardware. config DEVPORT - bool - depends on !M68K + bool "/dev/port character device" depends on ISA || PCI default y + help + Say Y here if you want to support the /dev/port device. The /dev/port + device is similar to /dev/mem, but for I/O ports. source "drivers/s390/char/Kconfig" +config MSM_SMD_PKT + bool "Enable device interface for some SMD packet ports" + default n + depends on MSM_SMD + help + smd_pkt driver provides the interface for the userspace clients + to communicate over smd via device nodes. This enable the + usersapce clients to read and write to some smd packets channel + for MSM chipset. + config TILE_SROM bool "Character-device access via hypervisor to the Tilera SPI ROM" depends on TILE @@ -607,7 +619,7 @@ source "drivers/char/xillybus/Kconfig" config MSM_ADSPRPC tristate "QTI ADSP RPC driver" - depends on MSM_GLINK + depends on MSM_SMD help Provides a communication mechanism that allows for clients to make remote method invocations across processor boundary to diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 7b0bd5408324b728f8ae6369478565080ed8cde7..77697b8c42c018c1caa0029dcb954ca0e905ae28 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o +obj-$(CONFIG_MSM_SMD_PKT) += msm_smd_pkt.o obj-$(CONFIG_MSPEC) += mspec.o obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 4795994733815c624a8ae599a960d718461bc9a5..38da42906994ce1196fb0057155fee685a70255d 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -213,6 +214,7 @@ struct fastrpc_channel_ctx { struct completion work; struct notifier_block nb; struct kref kref; + int channel; int sesscount; int ssrcount; void *handle; @@ -238,6 +240,7 @@ struct fastrpc_apps { spinlock_t hlock; struct ion_client *client; struct device *dev; + bool glink; }; struct fastrpc_mmap { @@ -298,18 +301,21 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { { .name = "adsprpc-smd", .subsys = "adsp", + .channel = SMD_APPS_QDSP, .link.link_info.edge = "lpass", .link.link_info.transport = "smem", }, { .name = "mdsprpc-smd", .subsys = "modem", + .channel = SMD_APPS_MODEM, .link.link_info.edge = "mpss", .link.link_info.transport = "smem", }, { .name = "sdsprpc-smd", .subsys = "slpi", + .channel = SMD_APPS_DSPS, .link.link_info.edge = "dsps", .link.link_info.transport = "smem", .vmid = VMID_SSC_Q6, @@ -1382,7 +1388,7 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, struct smq_msg *msg = &ctx->msg; struct fastrpc_file *fl = ctx->fl; struct fastrpc_channel_ctx *channel_ctx = &fl->apps->channel[fl->cid]; - int err = 0; + int err = 0, len; VERIFY(err, 0 != channel_ctx->chan); if (err) @@ -1397,25 +1403,69 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, msg->invoke.page.addr = ctx->buf ? ctx->buf->phys : 0; msg->invoke.page.size = buf_page_size(ctx->used); - if (fl->ssrcount != channel_ctx->ssrcount) { - err = -ECONNRESET; - goto bail; + if (fl->apps->glink) { + if (fl->ssrcount != channel_ctx->ssrcount) { + err = -ECONNRESET; + goto bail; + } + VERIFY(err, channel_ctx->link.port_state == + FASTRPC_LINK_CONNECTED); + if (err) + goto bail; + err = glink_tx(channel_ctx->chan, + (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), + GLINK_TX_REQ_INTENT); + } else { + spin_lock(&fl->apps->hlock); + len = smd_write((smd_channel_t *) + channel_ctx->chan, + msg, sizeof(*msg)); + spin_unlock(&fl->apps->hlock); + VERIFY(err, len == sizeof(*msg)); } - VERIFY(err, channel_ctx->link.port_state == - FASTRPC_LINK_CONNECTED); - if (err) - goto bail; - err = glink_tx(channel_ctx->chan, - (void *)&fl->apps->channel[fl->cid], msg, sizeof(*msg), - GLINK_TX_REQ_INTENT); bail: return err; } +static void fastrpc_smd_read_handler(int cid) +{ + struct fastrpc_apps *me = &gfa; + struct smq_invoke_rsp rsp = {0}; + int ret = 0; + + do { + ret = smd_read_from_cb(me->channel[cid].chan, &rsp, + sizeof(rsp)); + if (ret != sizeof(rsp)) + break; + rsp.ctx = rsp.ctx & ~1; + context_notify_user(uint64_to_ptr(rsp.ctx), rsp.retval); + } while (ret == sizeof(rsp)); +} + +static void smd_event_handler(void *priv, unsigned event) +{ + struct fastrpc_apps *me = &gfa; + int cid = (int)(uintptr_t)priv; + + switch (event) { + case SMD_EVENT_OPEN: + complete(&me->channel[cid].work); + break; + case SMD_EVENT_CLOSE: + fastrpc_notify_drivers(me, cid); + break; + case SMD_EVENT_DATA: + fastrpc_smd_read_handler(cid); + break; + } +} + static void fastrpc_init(struct fastrpc_apps *me) { int i; INIT_HLIST_HEAD(&me->drivers); + INIT_HLIST_HEAD(&me->maps); spin_lock_init(&me->hlock); mutex_init(&me->smd_mutex); me->channel = &gcinfo[0]; @@ -1438,14 +1488,15 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, int err = 0; struct timespec invoket; + if (fl->profile) + getnstimeofday(&invoket); + VERIFY(err, fl->sctx); if (err) goto bail; VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS); if (err) goto bail; - if (fl->profile) - getnstimeofday(&invoket); if (!kernel) { VERIFY(err, 0 == context_restore_interrupted(fl, inv, &ctx)); @@ -1987,10 +2038,12 @@ static void fastrpc_channel_close(struct kref *kref) ctx = container_of(kref, struct fastrpc_channel_ctx, kref); cid = ctx - &gcinfo[0]; - fastrpc_glink_close(ctx->chan, cid); + if (!me->glink) + smd_close(ctx->chan); + else + fastrpc_glink_close(ctx->chan, cid); + ctx->chan = 0; - glink_unregister_link_state_cb(ctx->link.link_notify_handle); - ctx->link.link_notify_handle = 0; mutex_unlock(&me->smd_mutex); pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); @@ -2074,11 +2127,9 @@ void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event) link->port_state = FASTRPC_LINK_DISCONNECTED; break; case GLINK_REMOTE_DISCONNECTED: - if (me->channel[cid].chan && - link->link_state == FASTRPC_LINK_STATE_UP) { + if (me->channel[cid].chan) { fastrpc_glink_close(me->channel[cid].chan, cid); me->channel[cid].chan = 0; - link->port_state = FASTRPC_LINK_DISCONNECTED; } break; default: @@ -2244,10 +2295,9 @@ static int fastrpc_glink_open(int cid) if (err) goto bail; - if (link->port_state == FASTRPC_LINK_CONNECTED || - link->port_state == FASTRPC_LINK_CONNECTING) { + VERIFY(err, (link->port_state == FASTRPC_LINK_DISCONNECTED)); + if (err) goto bail; - } link->port_state = FASTRPC_LINK_CONNECTING; cfg->priv = (void *)(uintptr_t)cid; @@ -2391,6 +2441,9 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) if (err) goto bail; cid = fl->cid; + VERIFY(err, cid >= 0 && cid < NUM_CHANNELS); + if (err) + goto bail; if (me->channel[cid].ssrcount != me->channel[cid].prevssrcount) { if (!me->channel[cid].issubsystemup) { @@ -2399,14 +2452,21 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) goto bail; } } - VERIFY(err, cid >= 0 && cid < NUM_CHANNELS); - if (err) - goto bail; fl->ssrcount = me->channel[cid].ssrcount; if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) || (me->channel[cid].chan == 0)) { - fastrpc_glink_register(cid, me); - VERIFY(err, 0 == fastrpc_glink_open(cid)); + if (me->glink) { + VERIFY(err, 0 == fastrpc_glink_register(cid, me)); + if (err) + goto bail; + VERIFY(err, 0 == fastrpc_glink_open(cid)); + } else { + VERIFY(err, !smd_named_open_on_edge(FASTRPC_SMD_GUID, + gcinfo[cid].channel, + (smd_channel_t **)&me->channel[cid].chan, + (void *)(uintptr_t)cid, + smd_event_handler)); + } if (err) goto bail; @@ -2635,7 +2695,11 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, ctx->ssrcount++; ctx->issubsystemup = 0; if (ctx->chan) { - fastrpc_glink_close(ctx->chan, cid); + if (me->glink) + fastrpc_glink_close(ctx->chan, cid); + else + smd_close(ctx->chan); + ctx->chan = 0; pr_info("'restart notifier: closed /dev/%s c %d %d'\n", gcinfo[cid].name, MAJOR(me->dev_no), cid); @@ -2728,7 +2792,7 @@ static int fastrpc_cb_probe(struct device *dev) start = 0x60000000; VERIFY(err, !IS_ERR_OR_NULL(sess->smmu.mapping = arm_iommu_create_mapping(&platform_bus_type, - start, 0x7fffffff))); + start, 0x70000000))); if (err) goto bail; iommu_set_fault_handler(sess->smmu.mapping->domain, @@ -2859,7 +2923,7 @@ static int fastrpc_probe(struct platform_device *pdev) } return 0; } - + me->glink = of_property_read_bool(dev->of_node, "qcom,fastrpc-glink"); VERIFY(err, !of_platform_populate(pdev->dev.of_node, fastrpc_match_table, NULL, &pdev->dev)); diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index 437077c4d44d533c20de881a84c4999683f482c2..382717bad828aa770192919008886e458603dd90 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -309,10 +309,12 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last) if (!mask_info || !mask_info->ptr || !mask_info->update_buf) return; - + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)mask_info->ptr; - if (!mask->ptr) + if (!mask->ptr) { + mutex_unlock(&driver->msg_mask_lock); return; + } buf = mask_info->update_buf; mutex_lock(&mask_info->lock); switch (mask_info->status) { @@ -385,6 +387,7 @@ proceed: } err: mutex_unlock(&mask_info->lock); + mutex_unlock(&driver->msg_mask_lock); } static void diag_send_time_sync_update(uint8_t peripheral) @@ -457,7 +460,9 @@ static void diag_send_feature_mask_update(uint8_t peripheral) if (driver->supports_apps_hdlc_encoding) DIAG_SET_FEATURE_MASK(F_DIAG_APPS_HDLC_ENCODE); if (driver->supports_apps_header_untagging) { - if (peripheral == PERIPHERAL_MODEM) { + if (peripheral == PERIPHERAL_MODEM || + peripheral == PERIPHERAL_LPASS || + peripheral == PERIPHERAL_CDSP) { DIAG_SET_FEATURE_MASK(F_DIAG_PKT_HEADER_UNTAG); driver->peripheral_untag[peripheral] = ENABLE_PKT_HEADER_UNTAGGING; @@ -504,7 +509,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; - + mutex_lock(&driver->msg_mask_lock); rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE; rsp.status = MSG_STATUS_SUCCESS; @@ -512,7 +517,6 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, rsp.count = driver->msg_mask_tbl_count; memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); - mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask_ptr++) { if (write_len + sizeof(ssid_range) > dest_len) { @@ -525,7 +529,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range)); write_len += sizeof(ssid_range); } - + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -549,7 +553,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; - + mutex_lock(&driver->msg_mask_lock); req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_BUILD_MASK; @@ -557,9 +561,8 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, rsp.ssid_last = req->ssid_last; rsp.status = MSG_STATUS_FAIL; rsp.padding = 0; - build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr; - for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) { + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { if (build_mask->ssid_first != req->ssid_first) continue; num_entries = req->ssid_last - req->ssid_first + 1; @@ -580,7 +583,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, } memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); - + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -608,6 +611,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; + mutex_lock(&driver->msg_mask_lock); req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK; @@ -615,7 +619,6 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, rsp.ssid_last = req->ssid_last; rsp.status = MSG_STATUS_FAIL; rsp.padding = 0; - mask = (struct diag_msg_mask_t *)mask_info->ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { if ((req->ssid_first < mask->ssid_first) || @@ -633,7 +636,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, } memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); - + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -664,7 +667,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, } req = (struct diag_msg_build_mask_t *)src_buf; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&mask_info->lock); mask = (struct diag_msg_mask_t *)mask_info->ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -724,7 +727,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, break; } mutex_unlock(&mask_info->lock); - + mutex_unlock(&driver->msg_mask_lock); if (diag_check_update(APPS_DATA)) diag_update_userspace_clients(MSG_MASKS_TYPE); @@ -777,7 +780,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, } req = (struct diag_msg_config_rsp_t *)src_buf; - + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)mask_info->ptr; mutex_lock(&mask_info->lock); mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED : @@ -789,6 +792,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mutex_unlock(&mask->lock); } mutex_unlock(&mask_info->lock); + mutex_unlock(&driver->msg_mask_lock); if (diag_check_update(APPS_DATA)) diag_update_userspace_clients(MSG_MASKS_TYPE); @@ -1292,6 +1296,7 @@ static int diag_create_msg_mask_table(void) struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; struct diag_ssid_range_t range; + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_mask.lock); driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -1302,6 +1307,7 @@ static int diag_create_msg_mask_table(void) break; } mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); return err; } @@ -1314,9 +1320,11 @@ static int diag_create_build_time_mask(void) struct diag_msg_mask_t *build_mask = NULL; struct diag_ssid_range_t range; + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_bt_mask.lock); + driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT; build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr; - for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) { + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { range.ssid_first = msg_mask_tbl[i].ssid_first; range.ssid_last = msg_mask_tbl[i].ssid_last; err = diag_create_msg_mask_table_entry(build_mask, &range); @@ -1427,6 +1435,7 @@ static int diag_create_build_time_mask(void) memcpy(build_mask->ptr, tbl, tbl_size); } mutex_unlock(&msg_bt_mask.lock); + mutex_unlock(&driver->msg_mask_lock); return err; } @@ -1574,10 +1583,11 @@ static int diag_msg_mask_init(void) pr_err("diag: Unable to create msg masks, err: %d\n", err); return err; } + mutex_lock(&driver->msg_mask_lock); driver->msg_mask = &msg_mask; - for (i = 0; i < NUM_PERIPHERALS; i++) driver->max_ssid_count[i] = 0; + mutex_unlock(&driver->msg_mask_lock); return 0; } @@ -1596,7 +1606,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE); if (err) return err; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&dest->lock); src_mask = (struct diag_msg_mask_t *)src->ptr; dest_mask = (struct diag_msg_mask_t *)dest->ptr; @@ -1615,6 +1625,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src) dest_mask++; } mutex_unlock(&dest->lock); + mutex_unlock(&driver->msg_mask_lock); return err; } @@ -1626,7 +1637,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info) if (!mask_info) return; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&mask_info->lock); mask = (struct diag_msg_mask_t *)mask_info->ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -1634,7 +1645,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info) mask->ptr = NULL; } mutex_unlock(&mask_info->lock); - + mutex_unlock(&driver->msg_mask_lock); __diag_mask_exit(mask_info); } @@ -1642,15 +1653,17 @@ static void diag_msg_mask_exit(void) { int i; struct diag_msg_mask_t *mask = NULL; - + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)(msg_mask.ptr); if (mask) { for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) kfree(mask->ptr); kfree(msg_mask.ptr); + msg_mask.ptr = NULL; } - kfree(msg_mask.update_buf); + msg_mask.update_buf = NULL; + mutex_unlock(&driver->msg_mask_lock); } static int diag_build_time_mask_init(void) @@ -1675,13 +1688,15 @@ static void diag_build_time_mask_exit(void) { int i; struct diag_msg_mask_t *mask = NULL; - + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)(msg_bt_mask.ptr); if (mask) { - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, mask++) kfree(mask->ptr); - kfree(msg_mask.ptr); + kfree(msg_bt_mask.ptr); + msg_bt_mask.ptr = NULL; } + mutex_unlock(&driver->msg_mask_lock); } static int diag_log_mask_init(void) @@ -1799,7 +1814,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, return -EIO; } mutex_unlock(&driver->diag_maskclear_mutex); - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&mask_info->lock); mask = (struct diag_msg_mask_t *)(mask_info->ptr); for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -1838,7 +1853,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count, total_len += len; } mutex_unlock(&mask_info->lock); - + mutex_unlock(&driver->msg_mask_lock); return err ? err : total_len; } diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c index dc3029cc459d120c024f3e0f4b640fc1fab75b7f..a5d92c51cc0b30b7c4978a35c413e7e4ac564d9d 100644 --- a/drivers/char/diag/diag_memorydevice.c +++ b/drivers/char/diag/diag_memorydevice.c @@ -129,6 +129,37 @@ void diag_md_close_all() diag_ws_reset(DIAG_WS_MUX); } +static int diag_md_get_peripheral(int ctxt) +{ + int peripheral; + + if (driver->num_pd_session) { + peripheral = GET_PD_CTXT(ctxt); + switch (peripheral) { + case UPD_WLAN: + case UPD_AUDIO: + case UPD_SENSORS: + break; + case DIAG_ID_MPSS: + case DIAG_ID_LPASS: + case DIAG_ID_CDSP: + default: + peripheral = + GET_BUF_PERIPHERAL(ctxt); + if (peripheral > NUM_PERIPHERALS) + peripheral = -EINVAL; + break; + } + } else { + /* Account for Apps data as well */ + peripheral = GET_BUF_PERIPHERAL(ctxt); + if (peripheral > NUM_PERIPHERALS) + peripheral = -EINVAL; + } + + return peripheral; +} + int diag_md_write(int id, unsigned char *buf, int len, int ctx) { int i; @@ -144,26 +175,13 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx) if (!buf || len < 0) return -EINVAL; - if (driver->pd_logging_mode) { - peripheral = GET_PD_CTXT(ctx); - switch (peripheral) { - case UPD_WLAN: - break; - case DIAG_ID_MPSS: - default: - peripheral = GET_BUF_PERIPHERAL(ctx); - if (peripheral > NUM_PERIPHERALS) - return -EINVAL; - break; - } - } else { - /* Account for Apps data as well */ - peripheral = GET_BUF_PERIPHERAL(ctx); - if (peripheral > NUM_PERIPHERALS) - return -EINVAL; - } + peripheral = + diag_md_get_peripheral(ctx); + if (peripheral < 0) + return -EINVAL; - session_info = diag_md_session_get_peripheral(peripheral); + session_info = + diag_md_session_get_peripheral(peripheral); if (!session_info) return -EIO; @@ -234,6 +252,7 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size, uint8_t drain_again = 0; uint8_t peripheral = 0; struct diag_md_session_t *session_info = NULL; + struct pid *pid_struct = NULL; mutex_lock(&driver->diagfwd_untag_mutex); @@ -243,31 +262,15 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size, entry = &ch->tbl[j]; if (entry->len <= 0) continue; - if (driver->pd_logging_mode) { - peripheral = GET_PD_CTXT(entry->ctx); - switch (peripheral) { - case UPD_WLAN: - break; - case DIAG_ID_MPSS: - default: - peripheral = - GET_BUF_PERIPHERAL(entry->ctx); - if (peripheral > NUM_PERIPHERALS) - goto drop_data; - break; - } - } else { - /* Account for Apps data as well */ - peripheral = GET_BUF_PERIPHERAL(entry->ctx); - if (peripheral > NUM_PERIPHERALS) - goto drop_data; - } + + peripheral = diag_md_get_peripheral(entry->ctx); + if (peripheral < 0) + goto drop_data; session_info = diag_md_session_get_peripheral(peripheral); if (!session_info) { - mutex_unlock(&driver->diagfwd_untag_mutex); - return -EIO; + goto drop_data; } if (session_info && info && @@ -276,6 +279,14 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size, if ((info && (info->peripheral_mask & MD_PERIPHERAL_MASK(peripheral)) == 0)) goto drop_data; + pid_struct = find_get_pid(session_info->pid); + if (!pid_struct) { + err = -ESRCH; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: No such md_session_map[%d] with pid = %d err=%d exists..\n", + peripheral, session_info->pid, err); + goto drop_data; + } /* * If the data is from remote processor, copy the remote * token first @@ -295,27 +306,35 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size, } if (i > 0) { remote_token = diag_get_remote(i); - err = copy_to_user(buf + ret, &remote_token, - sizeof(int)); + if (get_pid_task(pid_struct, PIDTYPE_PID)) { + err = copy_to_user(buf + ret, + &remote_token, + sizeof(int)); + if (err) + goto drop_data; + ret += sizeof(int); + } + } + + /* Copy the length of data being passed */ + if (get_pid_task(pid_struct, PIDTYPE_PID)) { + err = copy_to_user(buf + ret, + (void *)&(entry->len), + sizeof(int)); if (err) goto drop_data; ret += sizeof(int); } - /* Copy the length of data being passed */ - err = copy_to_user(buf + ret, (void *)&(entry->len), - sizeof(int)); - if (err) - goto drop_data; - ret += sizeof(int); - /* Copy the actual data being passed */ - err = copy_to_user(buf + ret, (void *)entry->buf, - entry->len); - if (err) - goto drop_data; - ret += entry->len; - + if (get_pid_task(pid_struct, PIDTYPE_PID)) { + err = copy_to_user(buf + ret, + (void *)entry->buf, + entry->len); + if (err) + goto drop_data; + ret += entry->len; + } /* * The data is now copied to the user space client, * Notify that the write is complete and delete its @@ -337,7 +356,15 @@ drop_data: } *pret = ret; - err = copy_to_user(buf + sizeof(int), (void *)&num_data, sizeof(int)); + if (pid_struct && get_pid_task(pid_struct, PIDTYPE_PID)) { + err = copy_to_user(buf + sizeof(int), + (void *)&num_data, + sizeof(int)); + } else { + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "diag: md_session_map[%d] with pid = %d Exited..\n", + peripheral, driver->md_session_map[peripheral]->pid); + } diag_ws_on_copy_complete(DIAG_WS_MUX); if (drain_again) chk_logging_wakeup(); @@ -363,9 +390,15 @@ int diag_md_close_peripheral(int id, uint8_t peripheral) spin_lock_irqsave(&ch->lock, flags); for (i = 0; i < ch->num_tbl_entries && !found; i++) { entry = &ch->tbl[i]; - if ((GET_BUF_PERIPHERAL(entry->ctx) != peripheral) || - (GET_PD_CTXT(entry->ctx) != peripheral)) - continue; + + if (peripheral > NUM_PERIPHERALS) { + if (GET_PD_CTXT(entry->ctx) != peripheral) + continue; + } else { + if (GET_BUF_PERIPHERAL(entry->ctx) != + peripheral) + continue; + } found = 1; if (ch->ops && ch->ops->write_done) { ch->ops->write_done(entry->buf, entry->len, diff --git a/drivers/char/diag/diag_mux.c b/drivers/char/diag/diag_mux.c index 55c5de1ea9fc24c26dd1fa771cc5d0581be3a4c4..d6f6ea7af8ea5f3afe3753e007dc7fa71d117544 100644 --- a/drivers/char/diag/diag_mux.c +++ b/drivers/char/diag/diag_mux.c @@ -27,7 +27,7 @@ #include "diag_mux.h" #include "diag_usb.h" #include "diag_memorydevice.h" - +#include "diag_ipc_logging.h" struct diag_mux_state_t *diag_mux; static struct diag_logger_t usb_logger; @@ -146,7 +146,20 @@ int diag_mux_write(int proc, unsigned char *buf, int len, int ctx) case DIAG_ID_MPSS: upd = PERIPHERAL_MODEM; break; + case DIAG_ID_LPASS: + upd = PERIPHERAL_LPASS; + break; + case DIAG_ID_CDSP: + upd = PERIPHERAL_CDSP; + break; case UPD_WLAN: + if (!driver->num_pd_session) + upd = PERIPHERAL_MODEM; + break; + case UPD_AUDIO: + case UPD_SENSORS: + if (!driver->num_pd_session) + upd = PERIPHERAL_LPASS; break; default: pr_err("diag: invalid pd ctxt= %d\n", upd); diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index b68a47219132fb642cb197de412b8ae75c8d0a01..4047a2c42bb7a36ff79b2293885624ad29f438ee 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -76,7 +76,9 @@ | DIAG_CON_LPASS | DIAG_CON_WCNSS \ | DIAG_CON_SENSORS | DIAG_CON_WDSP \ | DIAG_CON_CDSP) -#define DIAG_CON_UPD_ALL (DIAG_CON_UPD_WLAN) +#define DIAG_CON_UPD_ALL (DIAG_CON_UPD_WLAN \ + | DIAG_CON_UPD_AUDIO \ + | DIAG_CON_UPD_SENSORS) #define DIAG_STM_MODEM 0x01 #define DIAG_STM_LPASS 0x02 @@ -222,6 +224,10 @@ #define DIAG_ID_APPS 1 #define DIAG_ID_MPSS 2 #define DIAG_ID_WLAN 3 +#define DIAG_ID_LPASS 4 +#define DIAG_ID_CDSP 5 +#define DIAG_ID_AUDIO 6 +#define DIAG_ID_SENSORS 7 /* Number of sessions possible in Memory Device Mode. +1 for Apps data */ #define NUM_MD_SESSIONS (NUM_PERIPHERALS \ @@ -598,10 +604,15 @@ struct diagchar_dev { int in_busy_dcipktdata; int logging_mode; int logging_mask; - int pd_logging_mode; + int pd_logging_mode[NUM_UPD]; + int pd_session_clear[NUM_UPD]; int num_pd_session; - int cpd_len_1; - int cpd_len_2; + int cpd_len_1[NUM_PERIPHERALS]; + int cpd_len_2[NUM_PERIPHERALS]; + int upd_len_1_a[NUM_PERIPHERALS]; + int upd_len_1_b[NUM_PERIPHERALS]; + int upd_len_2_a; + int upd_len_2_b; int mask_check; uint32_t md_session_mask; uint8_t md_session_mode; @@ -616,8 +627,10 @@ struct diagchar_dev { struct diag_mask_info *event_mask; struct diag_mask_info *build_time_mask; uint8_t msg_mask_tbl_count; + uint8_t bt_msg_mask_tbl_count; uint16_t event_mask_size; uint16_t last_event_id; + struct mutex msg_mask_lock; /* Variables for Mask Centralization */ uint16_t num_event_id[NUM_PERIPHERALS]; uint32_t num_equip_id[NUM_PERIPHERALS]; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 4f56696f52e9f1ca4e9a79e2e9b704b232e73d39..60bfb2af49d091bd2fdca9f90906ec6df4a4cf3f 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -397,6 +397,10 @@ static uint32_t diag_translate_kernel_to_user_mask(uint32_t peripheral_mask) ret |= DIAG_CON_CDSP; if (peripheral_mask & MD_PERIPHERAL_MASK(UPD_WLAN)) ret |= DIAG_CON_UPD_WLAN; + if (peripheral_mask & MD_PERIPHERAL_MASK(UPD_AUDIO)) + ret |= DIAG_CON_UPD_AUDIO; + if (peripheral_mask & MD_PERIPHERAL_MASK(UPD_SENSORS)) + ret |= DIAG_CON_UPD_SENSORS; return ret; } int diag_mask_param(void) @@ -426,8 +430,8 @@ void diag_clear_masks(struct diag_md_session_t *info) static void diag_close_logging_process(const int pid) { - int i; - int session_peripheral_mask; + int i, j; + int session_mask; struct diag_md_session_t *session_info = NULL; struct diag_logging_mode_param_t params; @@ -443,27 +447,34 @@ static void diag_close_logging_process(const int pid) mutex_unlock(&driver->diag_maskclear_mutex); mutex_lock(&driver->diagchar_mutex); - session_peripheral_mask = session_info->peripheral_mask; + + session_mask = session_info->peripheral_mask; diag_md_session_close(session_info); - mutex_unlock(&driver->diagchar_mutex); + for (i = 0; i < NUM_MD_SESSIONS; i++) - if (MD_PERIPHERAL_MASK(i) & session_peripheral_mask) + if (MD_PERIPHERAL_MASK(i) & session_mask) diag_mux_close_peripheral(DIAG_LOCAL_PROC, i); params.req_mode = USB_MODE; params.mode_param = 0; params.peripheral_mask = - diag_translate_kernel_to_user_mask(session_peripheral_mask); - if (driver->pd_logging_mode) - params.pd_mask = - diag_translate_kernel_to_user_mask(session_peripheral_mask); - - if (session_peripheral_mask & MD_PERIPHERAL_MASK(UPD_WLAN)) { - driver->pd_logging_mode--; - driver->num_pd_session--; + diag_translate_kernel_to_user_mask(session_mask); + + for (i = UPD_WLAN; i < NUM_MD_SESSIONS; i++) { + if (session_mask & + MD_PERIPHERAL_MASK(i)) { + j = i - UPD_WLAN; + driver->pd_session_clear[j] = 1; + driver->pd_logging_mode[j] = 0; + driver->num_pd_session -= 1; + params.pd_mask = + diag_translate_kernel_to_user_mask(session_mask); + } else + params.pd_mask = 0; } - mutex_lock(&driver->diagchar_mutex); + diag_switch_logging(¶ms); + mutex_unlock(&driver->diagchar_mutex); } @@ -985,6 +996,11 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) { payload = *(uint16_t *)(buf + 2); + if (payload > DIAG_MAX_HDLC_BUF_SIZE) { + pr_err("diag: Dropping packet, payload size is %d\n", + payload); + return -EBADMSG; + } driver->hdlc_encode_buf_len = payload; /* * Adding 4 bytes for start (1 byte), version (1 byte) and @@ -1562,17 +1578,22 @@ static uint32_t diag_translate_mask(uint32_t peripheral_mask) ret |= (1 << PERIPHERAL_CDSP); if (peripheral_mask & DIAG_CON_UPD_WLAN) ret |= (1 << UPD_WLAN); + if (peripheral_mask & DIAG_CON_UPD_AUDIO) + ret |= (1 << UPD_AUDIO); + if (peripheral_mask & DIAG_CON_UPD_SENSORS) + ret |= (1 << UPD_SENSORS); return ret; } static int diag_switch_logging(struct diag_logging_mode_param_t *param) { - int new_mode; + int new_mode, i; int curr_mode; int err = 0; uint8_t do_switch = 1; uint32_t peripheral_mask = 0; + uint8_t peripheral, upd; if (!param) return -EINVAL; @@ -1583,10 +1604,28 @@ static int diag_switch_logging(struct diag_logging_mode_param_t *param) return -EINVAL; } - switch (param->pd_mask) { - case DIAG_CON_UPD_WLAN: - if (driver->md_session_map[PERIPHERAL_MODEM] && - (MD_PERIPHERAL_MASK(PERIPHERAL_MODEM) & + if (param->pd_mask) { + switch (param->pd_mask) { + case DIAG_CON_UPD_WLAN: + peripheral = PERIPHERAL_MODEM; + upd = UPD_WLAN; + break; + case DIAG_CON_UPD_AUDIO: + peripheral = PERIPHERAL_LPASS; + upd = UPD_AUDIO; + break; + case DIAG_CON_UPD_SENSORS: + peripheral = PERIPHERAL_LPASS; + upd = UPD_SENSORS; + break; + default: + DIAG_LOG(DIAG_DEBUG_USERSPACE, + "asking for mode switch with no pd mask set\n"); + return -EINVAL; + } + + if (driver->md_session_map[peripheral] && + (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask)) { DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag_fr: User PD is already logging onto active peripheral logging\n"); @@ -1595,15 +1634,16 @@ static int diag_switch_logging(struct diag_logging_mode_param_t *param) peripheral_mask = diag_translate_mask(param->pd_mask); param->peripheral_mask = peripheral_mask; - driver->pd_logging_mode++; - driver->num_pd_session++; - break; - - default: + i = upd - UPD_WLAN; + if (!driver->pd_session_clear[i]) { + driver->pd_logging_mode[i] = 1; + driver->num_pd_session += 1; + driver->pd_session_clear[i] = 0; + } + } else { peripheral_mask = diag_translate_mask(param->peripheral_mask); param->peripheral_mask = peripheral_mask; - break; } switch (param->req_mode) { @@ -1945,9 +1985,36 @@ static int diag_ioctl_hdlc_toggle(unsigned long ioarg) return 0; } -static int diag_ioctl_query_pd_logging(unsigned long ioarg) +static int diag_ioctl_query_pd_logging(struct diag_logging_mode_param_t *param) { int ret = -EINVAL; + int peripheral; + char *p_str = NULL; + + if (!param) + return -EINVAL; + + if (!param->pd_mask) { + DIAG_LOG(DIAG_DEBUG_USERSPACE, + "query with no pd mask set, returning error\n"); + return -EINVAL; + } + + switch (param->pd_mask) { + case DIAG_CON_UPD_WLAN: + peripheral = PERIPHERAL_MODEM; + p_str = "MODEM"; + break; + case DIAG_CON_UPD_AUDIO: + case DIAG_CON_UPD_SENSORS: + peripheral = PERIPHERAL_LPASS; + p_str = "LPASS"; + break; + default: + DIAG_LOG(DIAG_DEBUG_USERSPACE, + "Invalid pd mask, returning EINVAL\n"); + return -EINVAL; + } DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s: Untagging support on APPS is %s\n", __func__, @@ -1955,12 +2022,13 @@ static int diag_ioctl_query_pd_logging(unsigned long ioarg) "present" : "absent")); DIAG_LOG(DIAG_DEBUG_USERSPACE, - "diag: %s: Tagging support on MODEM is %s\n", __func__, - (driver->feature[PERIPHERAL_MODEM].untag_header ? + "diag: %s: Tagging support on %s is %s\n", + __func__, p_str, + (driver->feature[peripheral].untag_header ? "present" : "absent")); if (driver->supports_apps_header_untagging && - driver->feature[PERIPHERAL_MODEM].untag_header) + driver->feature[peripheral].untag_header) ret = 0; return ret; @@ -2206,7 +2274,10 @@ long diagchar_compat_ioctl(struct file *filp, result = diag_ioctl_hdlc_toggle(ioarg); break; case DIAG_IOCTL_QUERY_PD_LOGGING: - result = diag_ioctl_query_pd_logging(ioarg); + if (copy_from_user((void *)&mode_param, (void __user *)ioarg, + sizeof(mode_param))) + return -EFAULT; + result = diag_ioctl_query_pd_logging(&mode_param); break; } return result; @@ -2270,7 +2341,9 @@ long diagchar_ioctl(struct file *filp, mutex_unlock(&driver->dci_mutex); break; case DIAG_IOCTL_DCI_EVENT_STATUS: + mutex_lock(&driver->dci_mutex); result = diag_ioctl_dci_event_status(ioarg); + mutex_unlock(&driver->dci_mutex); break; case DIAG_IOCTL_DCI_CLEAR_LOGS: mutex_lock(&driver->dci_mutex); @@ -2332,7 +2405,10 @@ long diagchar_ioctl(struct file *filp, result = diag_ioctl_hdlc_toggle(ioarg); break; case DIAG_IOCTL_QUERY_PD_LOGGING: - result = diag_ioctl_query_pd_logging(ioarg); + if (copy_from_user((void *)&mode_param, (void __user *)ioarg, + sizeof(mode_param))) + return -EFAULT; + result = diag_ioctl_query_pd_logging(&mode_param); break; } return result; @@ -3474,7 +3550,10 @@ static int __init diagchar_init(void) poolsize_usb_apps + 1 + (NUM_PERIPHERALS * 6)); driver->num_clients = max_clients; driver->logging_mode = DIAG_USB_MODE; - driver->pd_logging_mode = 0; + for (i = 0; i < NUM_UPD; i++) { + driver->pd_logging_mode[i] = 0; + driver->pd_session_clear[i] = 0; + } driver->num_pd_session = 0; driver->mask_check = 0; driver->in_busy_pktdata = 0; @@ -3491,6 +3570,7 @@ static int __init diagchar_init(void) mutex_init(&driver->diag_file_mutex); mutex_init(&driver->delayed_rsp_mutex); mutex_init(&apps_data_mutex); + mutex_init(&driver->msg_mask_lock); for (i = 0; i < NUM_PERIPHERALS; i++) mutex_init(&driver->diagfwd_channel_mutex[i]); mutex_init(&driver->diagfwd_untag_mutex); diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c index 07c90b741fa03728a05b777767258a9b6f0d34d1..8fb724305c03a01328c0d8e423aeea3fd1076fb6 100644 --- a/drivers/char/diag/diagfwd.c +++ b/drivers/char/diag/diagfwd.c @@ -38,6 +38,7 @@ #include "diag_masks.h" #include "diag_usb.h" #include "diag_mux.h" +#include "diag_ipc_logging.h" #define STM_CMD_VERSION_OFFSET 4 #define STM_CMD_MASK_OFFSET 5 diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index ae749725f6dbf5005f871cebe32635e86cb66523..729fbf4fc145cbc8096c1d6d136d869574482538 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -110,6 +110,8 @@ void diag_notify_md_client(uint8_t peripheral, int data) { int stat = 0; struct siginfo info; + struct pid *pid_struct; + struct task_struct *result; if (peripheral > NUM_PERIPHERALS) return; @@ -122,20 +124,38 @@ void diag_notify_md_client(uint8_t peripheral, int data) info.si_code = SI_QUEUE; info.si_int = (PERIPHERAL_MASK(peripheral) | data); info.si_signo = SIGCONT; - if (driver->md_session_map[peripheral] && - driver->md_session_map[peripheral]->task) { - if (driver->md_session_map[peripheral]-> - md_client_thread_info->task != NULL - && driver->md_session_map[peripheral]->pid == - driver->md_session_map[peripheral]->task->tgid) { + + if (!driver->md_session_map[peripheral] || + driver->md_session_map[peripheral]->pid <= 0) { + pr_err("diag: md_session_map[%d] is invalid\n", peripheral); + mutex_unlock(&driver->md_session_lock); + return; + } + + pid_struct = find_get_pid( + driver->md_session_map[peripheral]->pid); + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, + "md_session_map[%d] pid = %d task = %pK\n", + peripheral, + driver->md_session_map[peripheral]->pid, + driver->md_session_map[peripheral]->task); + + if (pid_struct) { + result = get_pid_task(pid_struct, PIDTYPE_PID); + + if (!result) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, - "md_session %d pid = %d, md_session %d task tgid = %d\n", - peripheral, - driver->md_session_map[peripheral]->pid, + "diag: md_session_map[%d] with pid = %d Exited..\n", peripheral, - driver->md_session_map[peripheral]->task->tgid); - stat = send_sig_info(info.si_signo, &info, - driver->md_session_map[peripheral]->task); + driver->md_session_map[peripheral]->pid); + mutex_unlock(&driver->md_session_lock); + return; + } + + if (driver->md_session_map[peripheral] && + driver->md_session_map[peripheral]->task == result) { + stat = send_sig_info(info.si_signo, + &info, result); if (stat) pr_err("diag: Err sending signal to memory device client, signal data: 0x%x, stat: %d\n", info.si_int, stat); @@ -528,6 +548,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len, /* Don't account for pkt_id and length */ read_len += header_len - (2 * sizeof(uint32_t)); + mutex_lock(&driver->msg_mask_lock); driver->max_ssid_count[peripheral] = header->count; for (i = 0; i < header->count && read_len < len; i++) { ssid_range = (struct diag_ssid_range_t *)ptr; @@ -571,6 +592,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len, } driver->msg_mask_tbl_count += 1; } + mutex_unlock(&driver->msg_mask_lock); } static void diag_build_time_mask_update(uint8_t *buf, @@ -595,11 +617,11 @@ static void diag_build_time_mask_update(uint8_t *buf, __func__, range->ssid_first, range->ssid_last); return; } - + mutex_lock(&driver->msg_mask_lock); build_mask = (struct diag_msg_mask_t *)(driver->build_time_mask->ptr); num_items = range->ssid_last - range->ssid_first + 1; - for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) { + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { if (build_mask->ssid_first != range->ssid_first) continue; found = 1; @@ -618,7 +640,7 @@ static void diag_build_time_mask_update(uint8_t *buf, if (found) goto end; - new_size = (driver->msg_mask_tbl_count + 1) * + new_size = (driver->bt_msg_mask_tbl_count + 1) * sizeof(struct diag_msg_mask_t); temp = krealloc(driver->build_time_mask->ptr, new_size, GFP_KERNEL); if (!temp) { @@ -633,8 +655,9 @@ static void diag_build_time_mask_update(uint8_t *buf, __func__, err); goto end; } - driver->msg_mask_tbl_count += 1; + driver->bt_msg_mask_tbl_count += 1; end: + mutex_unlock(&driver->msg_mask_lock); return; } diff --git a/drivers/char/diag/diagfwd_glink.c b/drivers/char/diag/diagfwd_glink.c index 2784cf71cc2b5b16a0f98e1a28acb2a8606e05bc..03d496c2dd91764e5d4439660223ad9a37916087 100644 --- a/drivers/char/diag/diagfwd_glink.c +++ b/drivers/char/diag/diagfwd_glink.c @@ -487,6 +487,18 @@ static void diag_glink_remote_disconnect_work_fn(struct work_struct *work) atomic_set(&glink_info->tx_intent_ready, 0); } +static void diag_glink_late_init_work_fn(struct work_struct *work) +{ + struct diag_glink_info *glink_info = container_of(work, + struct diag_glink_info, + late_init_work); + if (!glink_info || !glink_info->hdl) + return; + DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d\n", + glink_info->peripheral, glink_info->type); + diagfwd_channel_open(glink_info->fwd_ctxt); +} + static void diag_glink_transport_notify_state(void *handle, const void *priv, unsigned event) { @@ -617,7 +629,7 @@ static void glink_late_init(struct diag_glink_info *glink_info) glink_info->inited = 1; if (atomic_read(&glink_info->opened)) - diagfwd_channel_open(glink_info->fwd_ctxt); + queue_work(glink_info->wq, &(glink_info->late_init_work)); DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s exiting\n", glink_info->name); @@ -665,6 +677,7 @@ static void __diag_glink_init(struct diag_glink_info *glink_info) INIT_WORK(&(glink_info->connect_work), diag_glink_connect_work_fn); INIT_WORK(&(glink_info->remote_disconnect_work), diag_glink_remote_disconnect_work_fn); + INIT_WORK(&(glink_info->late_init_work), diag_glink_late_init_work_fn); link_info.glink_link_state_notif_cb = diag_glink_notify_cb; link_info.transport = NULL; link_info.edge = glink_info->edge; diff --git a/drivers/char/diag/diagfwd_glink.h b/drivers/char/diag/diagfwd_glink.h index 5c1abeffd498700482c4a83081bfc96a5559018d..a84fa4edfca08d4af2e236416881a418390a7d49 100644 --- a/drivers/char/diag/diagfwd_glink.h +++ b/drivers/char/diag/diagfwd_glink.h @@ -37,6 +37,7 @@ struct diag_glink_info { struct work_struct read_work; struct work_struct connect_work; struct work_struct remote_disconnect_work; + struct work_struct late_init_work; struct diagfwd_info *fwd_ctxt; }; diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 4b5db01dbdf30abb487ac2c11c530d637f1ce46e..e86dc8292bf0b11b4699b9acf485400b936ef521 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -244,9 +244,14 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info, mutex_lock(&driver->hdlc_disable_mutex); mutex_lock(&fwd_info->data_mutex); + peripheral = GET_PD_CTXT(buf->ctxt); if (peripheral == DIAG_ID_MPSS) peripheral = PERIPHERAL_MODEM; + if (peripheral == DIAG_ID_LPASS) + peripheral = PERIPHERAL_LPASS; + if (peripheral == DIAG_ID_CDSP) + peripheral = PERIPHERAL_CDSP; session_info = diag_md_session_get_peripheral(peripheral); @@ -323,15 +328,19 @@ end: static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info, unsigned char *buf, int len) { - int len_cpd = 0, len_upd_1 = 0; - int ctxt_cpd = 0, ctxt_upd_1 = 0; + int len_cpd = 0; + int len_upd_1 = 0, len_upd_2 = 0; + int ctxt_cpd = 0; + int ctxt_upd_1 = 0, ctxt_upd_2 = 0; int buf_len = 0, processed = 0; unsigned char *temp_buf_main = NULL; unsigned char *temp_buf_cpd = NULL; unsigned char *temp_buf_upd_1 = NULL; + unsigned char *temp_buf_upd_2 = NULL; struct diagfwd_buf_t *temp_ptr_upd = NULL; struct diagfwd_buf_t *temp_ptr_cpd = NULL; int flag_buf_1 = 0, flag_buf_2 = 0; + uint8_t peripheral; if (!fwd_info || !buf || len <= 0) { diag_ws_release(); @@ -349,24 +358,42 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info, diag_ws_release(); return; } + peripheral = fwd_info->peripheral; - if (driver->feature[fwd_info->peripheral].encode_hdlc && - driver->feature[fwd_info->peripheral].untag_header && - driver->peripheral_untag[fwd_info->peripheral]) { + if (driver->feature[peripheral].encode_hdlc && + driver->feature[peripheral].untag_header && + driver->peripheral_untag[peripheral]) { mutex_lock(&driver->diagfwd_untag_mutex); temp_buf_cpd = buf; temp_buf_main = buf; if (fwd_info->buf_1 && fwd_info->buf_1->data_raw == buf) { flag_buf_1 = 1; - if (fwd_info->type == TYPE_DATA) + temp_ptr_cpd = fwd_info->buf_1; + if (fwd_info->type == TYPE_DATA) { temp_buf_upd_1 = fwd_info->buf_upd_1_a->data_raw; - } else { + if (peripheral == + PERIPHERAL_LPASS) + temp_buf_upd_2 = + fwd_info->buf_upd_2_a->data_raw; + } + } else if (fwd_info->buf_2 && + fwd_info->buf_2->data_raw == buf) { flag_buf_2 = 1; + temp_ptr_cpd = fwd_info->buf_2; if (fwd_info->type == TYPE_DATA) temp_buf_upd_1 = fwd_info->buf_upd_1_b->data_raw; + if (peripheral == + PERIPHERAL_LPASS) + temp_buf_upd_2 = + fwd_info->buf_upd_2_b->data_raw; + } else { + pr_err("diag: In %s, no match for buffer %pK, peripheral %d, type: %d\n", + __func__, buf, peripheral, + fwd_info->type); + goto end; } while (processed < len) { buf_len = @@ -390,31 +417,97 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info, temp_buf_upd_1 += buf_len; } break; + case DIAG_ID_LPASS: + ctxt_cpd = DIAG_ID_LPASS; + len_cpd += buf_len; + if (temp_buf_cpd) { + memcpy(temp_buf_cpd, + (temp_buf_main + 4), buf_len); + temp_buf_cpd += buf_len; + } + break; + case DIAG_ID_AUDIO: + ctxt_upd_1 = UPD_AUDIO; + len_upd_1 += buf_len; + if (temp_buf_upd_1) { + memcpy(temp_buf_upd_1, + (temp_buf_main + 4), buf_len); + temp_buf_upd_1 += buf_len; + } + break; + case DIAG_ID_SENSORS: + ctxt_upd_2 = UPD_SENSORS; + len_upd_2 += buf_len; + if (temp_buf_upd_2) { + memcpy(temp_buf_upd_2, + (temp_buf_main + 4), buf_len); + temp_buf_upd_2 += buf_len; + } + break; + case DIAG_ID_CDSP: + ctxt_cpd = DIAG_ID_CDSP; + len_cpd += buf_len; + if (temp_buf_cpd) { + memcpy(temp_buf_cpd, + (temp_buf_main + 4), buf_len); + temp_buf_cpd += buf_len; + } + break; + default: + goto end; } len = len - 4; temp_buf_main += (buf_len + 4); processed += buf_len; } - if (fwd_info->type == TYPE_DATA && len_upd_1) { + if (peripheral == PERIPHERAL_LPASS && + fwd_info->type == TYPE_DATA && len_upd_2) { + if (flag_buf_1) { + driver->upd_len_2_a = len_upd_2; + temp_ptr_upd = fwd_info->buf_upd_2_a; + } else { + driver->upd_len_2_b = len_upd_2; + temp_ptr_upd = fwd_info->buf_upd_2_b; + } + temp_ptr_upd->ctxt &= 0x00FFFFFF; + temp_ptr_upd->ctxt |= + (SET_PD_CTXT(ctxt_upd_2)); + atomic_set(&temp_ptr_upd->in_busy, 1); + diagfwd_data_process_done(fwd_info, + temp_ptr_upd, len_upd_2); + } else { if (flag_buf_1) + driver->upd_len_2_a = 0; + if (flag_buf_2) + driver->upd_len_2_b = 0; + } + if (fwd_info->type == TYPE_DATA && len_upd_1) { + if (flag_buf_1) { + driver->upd_len_1_a[peripheral] = + len_upd_1; temp_ptr_upd = fwd_info->buf_upd_1_a; - else + } else { + driver->upd_len_1_b[peripheral] = + len_upd_1; temp_ptr_upd = fwd_info->buf_upd_1_b; + } temp_ptr_upd->ctxt &= 0x00FFFFFF; temp_ptr_upd->ctxt |= (SET_PD_CTXT(ctxt_upd_1)); atomic_set(&temp_ptr_upd->in_busy, 1); diagfwd_data_process_done(fwd_info, temp_ptr_upd, len_upd_1); + } else { + if (flag_buf_1) + driver->upd_len_1_a[peripheral] = 0; + if (flag_buf_2) + driver->upd_len_1_b[peripheral] = 0; } if (len_cpd) { - if (flag_buf_1) { - driver->cpd_len_1 = len_cpd; - temp_ptr_cpd = fwd_info->buf_1; - } else { - driver->cpd_len_2 = len_cpd; - temp_ptr_cpd = fwd_info->buf_2; - } + if (flag_buf_1) + driver->cpd_len_1[peripheral] = len_cpd; + else + driver->cpd_len_2[peripheral] = len_cpd; temp_ptr_cpd->ctxt &= 0x00FFFFFF; temp_ptr_cpd->ctxt |= (SET_PD_CTXT(ctxt_cpd)); @@ -422,14 +515,24 @@ static void diagfwd_data_read_untag_done(struct diagfwd_info *fwd_info, temp_ptr_cpd, len_cpd); } else { if (flag_buf_1) - driver->cpd_len_1 = 0; + driver->cpd_len_1[peripheral] = 0; if (flag_buf_2) - driver->cpd_len_2 = 0; + driver->cpd_len_2[peripheral] = 0; } mutex_unlock(&driver->diagfwd_untag_mutex); + return; } else { diagfwd_data_read_done(fwd_info, buf, len); + return; + } +end: + diag_ws_release(); + mutex_unlock(&driver->diagfwd_untag_mutex); + if (temp_ptr_cpd) { + diagfwd_write_done(fwd_info->peripheral, fwd_info->type, + GET_BUF_NUM(temp_ptr_cpd->ctxt)); } + diagfwd_queue_read(fwd_info); } static void diagfwd_data_read_done(struct diagfwd_info *fwd_info, @@ -991,6 +1094,21 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info) if (!fwd_info->inited) return; + /* + * Logging mode here is reflecting previous mode + * status and will be updated to new mode later. + * + * Keeping the buffers busy for Memory Device Mode. + */ + + if ((driver->logging_mode != DIAG_USB_MODE) || + driver->usb_connected) { + if (fwd_info->buf_1) + atomic_set(&fwd_info->buf_1->in_busy, 0); + if (fwd_info->buf_2) + atomic_set(&fwd_info->buf_2->in_busy, 0); + } + if (fwd_info->p_ops && fwd_info->p_ops->open) fwd_info->p_ops->open(fwd_info->ctxt); @@ -1151,18 +1269,78 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int ctxt) return; fwd_info = &peripheral_info[type][peripheral]; - if (ctxt == 1 && fwd_info->buf_1) + + if (ctxt == 1 && fwd_info->buf_1) { + /* Buffer 1 for core PD is freed */ atomic_set(&fwd_info->buf_1->in_busy, 0); - else if (ctxt == 2 && fwd_info->buf_2) + driver->cpd_len_1[peripheral] = 0; + } else if (ctxt == 2 && fwd_info->buf_2) { + /* Buffer 2 for core PD is freed */ atomic_set(&fwd_info->buf_2->in_busy, 0); - else if (ctxt == 3 && fwd_info->buf_upd_1_a) { + driver->cpd_len_2[peripheral] = 0; + } else if (ctxt == 3 && fwd_info->buf_upd_1_a) { + /* Buffer 1 for user pd 1 is freed */ atomic_set(&fwd_info->buf_upd_1_a->in_busy, 0); - if (driver->cpd_len_1 == 0) - atomic_set(&fwd_info->buf_1->in_busy, 0); + + if (peripheral == PERIPHERAL_LPASS) { + /* if not data in cpd and other user pd + * free the core pd buffer for LPASS + */ + if (!driver->cpd_len_1[PERIPHERAL_LPASS] && + !driver->upd_len_2_a) + atomic_set(&fwd_info->buf_1->in_busy, 0); + } else { + /* if not data in cpd + * free the core pd buffer for MPSS + */ + if (!driver->cpd_len_1[PERIPHERAL_MODEM]) + atomic_set(&fwd_info->buf_1->in_busy, 0); + } + driver->upd_len_1_a[peripheral] = 0; + } else if (ctxt == 4 && fwd_info->buf_upd_1_b) { + /* Buffer 2 for user pd 1 is freed */ atomic_set(&fwd_info->buf_upd_1_b->in_busy, 0); - if (driver->cpd_len_2 == 0) + if (peripheral == PERIPHERAL_LPASS) { + /* if not data in cpd and other user pd + * free the core pd buffer for LPASS + */ + if (!driver->cpd_len_2[peripheral] && + !driver->upd_len_2_b) + atomic_set(&fwd_info->buf_2->in_busy, 0); + } else { + /* if not data in cpd + * free the core pd buffer for MPSS + */ + if (!driver->cpd_len_2[PERIPHERAL_MODEM]) + atomic_set(&fwd_info->buf_2->in_busy, 0); + } + driver->upd_len_1_b[peripheral] = 0; + + } else if (ctxt == 5 && fwd_info->buf_upd_2_a) { + /* Buffer 1 for user pd 2 is freed */ + atomic_set(&fwd_info->buf_upd_2_a->in_busy, 0); + /* if not data in cpd and other user pd + * free the core pd buffer for LPASS + */ + if (!driver->cpd_len_1[PERIPHERAL_LPASS] && + !driver->upd_len_1_a[PERIPHERAL_LPASS]) + atomic_set(&fwd_info->buf_1->in_busy, 0); + + driver->upd_len_2_a = 0; + + } else if (ctxt == 6 && fwd_info->buf_upd_2_b) { + /* Buffer 2 for user pd 2 is freed */ + atomic_set(&fwd_info->buf_upd_2_b->in_busy, 0); + /* if not data in cpd and other user pd + * free the core pd buffer for LPASS + */ + if (!driver->cpd_len_2[PERIPHERAL_LPASS] && + !driver->upd_len_1_b[PERIPHERAL_LPASS]) atomic_set(&fwd_info->buf_2->in_busy, 0); + + driver->upd_len_2_b = 0; + } else pr_err("diag: In %s, invalid ctxt %d\n", __func__, ctxt); @@ -1295,7 +1473,8 @@ static void diagfwd_queue_read(struct diagfwd_info *fwd_info) void diagfwd_buffers_init(struct diagfwd_info *fwd_info) { - unsigned char *temp_buf = NULL; + struct diagfwd_buf_t *temp_fwd_buf; + unsigned char *temp_char_buf; if (!fwd_info) return; @@ -1366,11 +1545,11 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = fwd_info->buf_upd_1_a->data; - if (ZERO_OR_NULL_PTR(temp_buf)) + temp_char_buf = fwd_info->buf_upd_1_a->data; + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_upd_1_a->len = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); fwd_info->buf_upd_1_a->ctxt = SET_BUF_CTXT( fwd_info->peripheral, fwd_info->type, 3); @@ -1391,16 +1570,76 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = fwd_info->buf_upd_1_b->data; - if (ZERO_OR_NULL_PTR(temp_buf)) + temp_char_buf = + fwd_info->buf_upd_1_b->data; + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_upd_1_b->len = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); fwd_info->buf_upd_1_b->ctxt = SET_BUF_CTXT( fwd_info->peripheral, fwd_info->type, 4); } + if (fwd_info->peripheral == + PERIPHERAL_LPASS) { + if (!fwd_info->buf_upd_2_a) { + fwd_info->buf_upd_2_a = + kzalloc(sizeof(struct diagfwd_buf_t), + GFP_KERNEL); + temp_fwd_buf = + fwd_info->buf_upd_2_a; + if (ZERO_OR_NULL_PTR(temp_fwd_buf)) + goto err; + kmemleak_not_leak(temp_fwd_buf); + } + + if (!fwd_info->buf_upd_2_a->data) { + fwd_info->buf_upd_2_a->data = + kzalloc(PERIPHERAL_BUF_SZ + + APF_DIAG_PADDING, + GFP_KERNEL); + temp_char_buf = + fwd_info->buf_upd_2_a->data; + if (ZERO_OR_NULL_PTR(temp_char_buf)) + goto err; + fwd_info->buf_upd_2_a->len = + PERIPHERAL_BUF_SZ; + kmemleak_not_leak(temp_char_buf); + fwd_info->buf_upd_2_a->ctxt = + SET_BUF_CTXT( + fwd_info->peripheral, + fwd_info->type, 5); + } + if (!fwd_info->buf_upd_2_b) { + fwd_info->buf_upd_2_b = + kzalloc(sizeof(struct diagfwd_buf_t), + GFP_KERNEL); + temp_fwd_buf = + fwd_info->buf_upd_2_b; + if (ZERO_OR_NULL_PTR(temp_fwd_buf)) + goto err; + kmemleak_not_leak(temp_fwd_buf); + } + + if (!fwd_info->buf_upd_2_b->data) { + fwd_info->buf_upd_2_b->data = + kzalloc(PERIPHERAL_BUF_SZ + + APF_DIAG_PADDING, + GFP_KERNEL); + temp_char_buf = + fwd_info->buf_upd_2_b->data; + if (ZERO_OR_NULL_PTR(temp_char_buf)) + goto err; + fwd_info->buf_upd_2_b->len = + PERIPHERAL_BUF_SZ; + kmemleak_not_leak(temp_char_buf); + fwd_info->buf_upd_2_b->ctxt = + SET_BUF_CTXT( + fwd_info->peripheral, + fwd_info->type, 6); + } + } } if (driver->supports_apps_hdlc_encoding) { @@ -1410,12 +1649,13 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = fwd_info->buf_1->data_raw; - if (ZERO_OR_NULL_PTR(temp_buf)) + temp_char_buf = + fwd_info->buf_1->data_raw; + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); } if (!fwd_info->buf_2->data_raw) { @@ -1423,12 +1663,13 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = fwd_info->buf_2->data_raw; - if (ZERO_OR_NULL_PTR(temp_buf)) + temp_char_buf = + fwd_info->buf_2->data_raw; + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_2->len_raw = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); } if (driver->feature[fwd_info->peripheral]. @@ -1439,13 +1680,13 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = + temp_char_buf = fwd_info->buf_upd_1_a->data_raw; - if (ZERO_OR_NULL_PTR(temp_buf)) + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_upd_1_a->len_raw = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); } if (fwd_info->buf_upd_1_b && @@ -1454,13 +1695,41 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - temp_buf = + temp_char_buf = fwd_info->buf_upd_1_b->data_raw; - if (ZERO_OR_NULL_PTR(temp_buf)) + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_upd_1_b->len_raw = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(temp_buf); + kmemleak_not_leak(temp_char_buf); + } + if (fwd_info->peripheral == PERIPHERAL_LPASS + && !fwd_info->buf_upd_2_a->data_raw) { + fwd_info->buf_upd_2_a->data_raw = + kzalloc(PERIPHERAL_BUF_SZ + + APF_DIAG_PADDING, + GFP_KERNEL); + temp_char_buf = + fwd_info->buf_upd_2_a->data_raw; + if (ZERO_OR_NULL_PTR(temp_char_buf)) + goto err; + fwd_info->buf_upd_2_a->len_raw = + PERIPHERAL_BUF_SZ; + kmemleak_not_leak(temp_char_buf); + } + if (fwd_info->peripheral == PERIPHERAL_LPASS + && !fwd_info->buf_upd_2_b->data_raw) { + fwd_info->buf_upd_2_b->data_raw = + kzalloc(PERIPHERAL_BUF_SZ + + APF_DIAG_PADDING, + GFP_KERNEL); + temp_char_buf = + fwd_info->buf_upd_2_b->data_raw; + if (ZERO_OR_NULL_PTR(temp_char_buf)) + goto err; + fwd_info->buf_upd_2_b->len_raw = + PERIPHERAL_BUF_SZ; + kmemleak_not_leak(temp_char_buf); } } } @@ -1473,10 +1742,12 @@ void diagfwd_buffers_init(struct diagfwd_info *fwd_info) fwd_info->buf_1->data_raw = kzalloc(PERIPHERAL_BUF_SZ + APF_DIAG_PADDING, GFP_KERNEL); - if (!fwd_info->buf_1->data_raw) + temp_char_buf = + fwd_info->buf_1->data_raw; + if (ZERO_OR_NULL_PTR(temp_char_buf)) goto err; fwd_info->buf_1->len_raw = PERIPHERAL_BUF_SZ; - kmemleak_not_leak(fwd_info->buf_1->data_raw); + kmemleak_not_leak(temp_char_buf); } } @@ -1513,6 +1784,38 @@ static void diagfwd_buffers_exit(struct diagfwd_info *fwd_info) kfree(fwd_info->buf_2); fwd_info->buf_2 = NULL; } + if (fwd_info->buf_upd_1_a) { + kfree(fwd_info->buf_upd_1_a->data); + fwd_info->buf_upd_1_a->data = NULL; + kfree(fwd_info->buf_upd_1_a->data_raw); + fwd_info->buf_upd_1_a->data_raw = NULL; + kfree(fwd_info->buf_upd_1_a); + fwd_info->buf_upd_1_a = NULL; + } + if (fwd_info->buf_upd_1_b) { + kfree(fwd_info->buf_upd_1_b->data); + fwd_info->buf_upd_1_b->data = NULL; + kfree(fwd_info->buf_upd_1_b->data_raw); + fwd_info->buf_upd_1_b->data_raw = NULL; + kfree(fwd_info->buf_upd_1_b); + fwd_info->buf_upd_1_b = NULL; + } + if (fwd_info->buf_upd_2_a) { + kfree(fwd_info->buf_upd_2_a->data); + fwd_info->buf_upd_2_a->data = NULL; + kfree(fwd_info->buf_upd_2_a->data_raw); + fwd_info->buf_upd_2_a->data_raw = NULL; + kfree(fwd_info->buf_upd_2_a); + fwd_info->buf_upd_2_a = NULL; + } + if (fwd_info->buf_upd_2_b) { + kfree(fwd_info->buf_upd_2_b->data); + fwd_info->buf_upd_2_b->data = NULL; + kfree(fwd_info->buf_upd_2_b->data_raw); + fwd_info->buf_upd_2_b->data_raw = NULL; + kfree(fwd_info->buf_upd_2_b); + fwd_info->buf_upd_2_b = NULL; + } mutex_unlock(&fwd_info->buf_mutex); } diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h index f483da81cc9679c9c770ea6bbb0a7533c59acbc6..760f139ff428ef47b4f2300029c3541f9401d972 100644 --- a/drivers/char/diag/diagfwd_peripheral.h +++ b/drivers/char/diag/diagfwd_peripheral.h @@ -80,6 +80,8 @@ struct diagfwd_info { struct diagfwd_buf_t *buf_2; struct diagfwd_buf_t *buf_upd_1_a; struct diagfwd_buf_t *buf_upd_1_b; + struct diagfwd_buf_t *buf_upd_2_a; + struct diagfwd_buf_t *buf_upd_2_b; struct diagfwd_buf_t *buf_ptr[NUM_WRITE_BUFFERS]; struct diag_peripheral_ops *p_ops; struct diag_channel_ops *c_ops; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6b1721f978c2945f4af716636c8373fe8807dca0..e901463d4972af3d9639ae23184ca234a47ffd4b 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -59,6 +59,10 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) #endif #ifdef CONFIG_STRICT_DEVMEM +static inline int page_is_allowed(unsigned long pfn) +{ + return devmem_is_allowed(pfn); +} static inline int range_is_allowed(unsigned long pfn, unsigned long size) { u64 from = ((u64)pfn) << PAGE_SHIFT; @@ -78,6 +82,10 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) return 1; } #else +static inline int page_is_allowed(unsigned long pfn) +{ + return 1; +} static inline int range_is_allowed(unsigned long pfn, unsigned long size) { return 1; @@ -125,23 +133,31 @@ static ssize_t read_mem(struct file *file, char __user *buf, while (count > 0) { unsigned long remaining; + int allowed; sz = size_inside_page(p, count); - if (!range_is_allowed(p >> PAGE_SHIFT, count)) + allowed = page_is_allowed(p >> PAGE_SHIFT); + if (!allowed) return -EPERM; + if (allowed == 2) { + /* Show zeros for restricted memory. */ + remaining = clear_user(buf, sz); + } else { + /* + * On ia64 if a page has been mapped somewhere as + * uncached, then it must also be accessed uncached + * by the kernel or data corruption may occur. + */ + ptr = xlate_dev_mem_ptr(p); + if (!ptr) + return -EFAULT; - /* - * On ia64 if a page has been mapped somewhere as uncached, then - * it must also be accessed uncached by the kernel or data - * corruption may occur. - */ - ptr = xlate_dev_mem_ptr(p); - if (!ptr) - return -EFAULT; + remaining = copy_to_user(buf, ptr, sz); + + unxlate_dev_mem_ptr(p, ptr); + } - remaining = copy_to_user(buf, ptr, sz); - unxlate_dev_mem_ptr(p, ptr); if (remaining) return -EFAULT; @@ -184,30 +200,36 @@ static ssize_t write_mem(struct file *file, const char __user *buf, #endif while (count > 0) { + int allowed; + sz = size_inside_page(p, count); - if (!range_is_allowed(p >> PAGE_SHIFT, sz)) + allowed = page_is_allowed(p >> PAGE_SHIFT); + if (!allowed) return -EPERM; - /* - * On ia64 if a page has been mapped somewhere as uncached, then - * it must also be accessed uncached by the kernel or data - * corruption may occur. - */ - ptr = xlate_dev_mem_ptr(p); - if (!ptr) { - if (written) - break; - return -EFAULT; - } + /* Skip actual writing when a page is marked as restricted. */ + if (allowed == 1) { + /* + * On ia64 if a page has been mapped somewhere as + * uncached, then it must also be accessed uncached + * by the kernel or data corruption may occur. + */ + ptr = xlate_dev_mem_ptr(p); + if (!ptr) { + if (written) + break; + return -EFAULT; + } - copied = copy_from_user(ptr, buf, sz); - unxlate_dev_mem_ptr(p, ptr); - if (copied) { - written += sz - copied; - if (written) - break; - return -EFAULT; + copied = copy_from_user(ptr, buf, sz); + unxlate_dev_mem_ptr(p, ptr); + if (copied) { + written += sz - copied; + if (written) + break; + return -EFAULT; + } } buf += sz; diff --git a/drivers/char/msm_smd_pkt.c b/drivers/char/msm_smd_pkt.c new file mode 100644 index 0000000000000000000000000000000000000000..a61d273bfb6514c28f03aa400a18bc49854f032e --- /dev/null +++ b/drivers/char/msm_smd_pkt.c @@ -0,0 +1,1397 @@ +/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +/* + * SMD Packet Driver -- Provides a binary SMD non-muxed packet port + * interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_NAME "msm_smdpkt" +#define DEVICE_NAME "smdpkt" +#define WAKEUPSOURCE_TIMEOUT (2000) /* two seconds */ + +struct smd_pkt_dev { + struct list_head dev_list; + char dev_name[SMD_MAX_CH_NAME_LEN]; + char ch_name[SMD_MAX_CH_NAME_LEN]; + uint32_t edge; + + struct cdev cdev; + struct device *devicep; + void *pil; + + struct smd_channel *ch; + struct mutex ch_lock; + struct mutex rx_lock; + struct mutex tx_lock; + wait_queue_head_t ch_read_wait_queue; + wait_queue_head_t ch_write_wait_queue; + wait_queue_head_t ch_opened_wait_queue; + + int i; + int ref_cnt; + + int blocking_write; + int is_open; + int poll_mode; + unsigned ch_size; + uint open_modem_wait; + + int has_reset; + int do_reset_notification; + struct completion ch_allocated; + struct wakeup_source pa_ws; /* Packet Arrival Wakeup Source */ + struct work_struct packet_arrival_work; + spinlock_t pa_spinlock; + int ws_locked; +}; + + +struct smd_pkt_driver { + struct list_head list; + int ref_cnt; + char pdriver_name[SMD_MAX_CH_NAME_LEN]; + struct platform_driver driver; +}; + +static DEFINE_MUTEX(smd_pkt_driver_lock_lha1); +static LIST_HEAD(smd_pkt_driver_list); + +struct class *smd_pkt_classp; +static dev_t smd_pkt_number; +static struct delayed_work loopback_work; +static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp); +static void check_and_wakeup_writer(struct smd_pkt_dev *smd_pkt_devp); +static uint32_t is_modem_smsm_inited(void); + +static DEFINE_MUTEX(smd_pkt_dev_lock_lha1); +static LIST_HEAD(smd_pkt_dev_list); +static int num_smd_pkt_ports; + +#define SMD_PKT_IPC_LOG_PAGE_CNT 2 +static void *smd_pkt_ilctxt; + +static int msm_smd_pkt_debug_mask; +module_param_named(debug_mask, msm_smd_pkt_debug_mask, + int, S_IRUGO | S_IWUSR | S_IWGRP); + +enum { + SMD_PKT_STATUS = 1U << 0, + SMD_PKT_READ = 1U << 1, + SMD_PKT_WRITE = 1U << 2, + SMD_PKT_POLL = 1U << 5, +}; + +#define DEBUG + +#ifdef DEBUG + +#define SMD_PKT_LOG_STRING(x...) \ +do { \ + if (smd_pkt_ilctxt) \ + ipc_log_string(smd_pkt_ilctxt, ": "x); \ +} while (0) + +#define D_STATUS(x...) \ +do { \ + if (msm_smd_pkt_debug_mask & SMD_PKT_STATUS) \ + pr_info("Status: "x); \ + SMD_PKT_LOG_STRING(x); \ +} while (0) + +#define D_READ(x...) \ +do { \ + if (msm_smd_pkt_debug_mask & SMD_PKT_READ) \ + pr_info("Read: "x); \ + SMD_PKT_LOG_STRING(x); \ +} while (0) + +#define D_WRITE(x...) \ +do { \ + if (msm_smd_pkt_debug_mask & SMD_PKT_WRITE) \ + pr_info("Write: "x); \ + SMD_PKT_LOG_STRING(x); \ +} while (0) + +#define D_POLL(x...) \ +do { \ + if (msm_smd_pkt_debug_mask & SMD_PKT_POLL) \ + pr_info("Poll: "x); \ + SMD_PKT_LOG_STRING(x); \ +} while (0) + +#define E_SMD_PKT_SSR(x) \ +do { \ + if (x->do_reset_notification) \ + pr_err("%s notifying reset for smd_pkt_dev id:%d\n", \ + __func__, x->i); \ +} while (0) +#else +#define D_STATUS(x...) do {} while (0) +#define D_READ(x...) do {} while (0) +#define D_WRITE(x...) do {} while (0) +#define D_POLL(x...) do {} while (0) +#define E_SMD_PKT_SSR(x) do {} while (0) +#endif + +static ssize_t open_timeout_store(struct device *d, + struct device_attribute *attr, + const char *buf, + size_t n) +{ + struct smd_pkt_dev *smd_pkt_devp; + unsigned long tmp; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) { + if (smd_pkt_devp->devicep == d) { + if (!kstrtoul(buf, 10, &tmp)) { + smd_pkt_devp->open_modem_wait = tmp; + mutex_unlock(&smd_pkt_dev_lock_lha1); + return n; + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + pr_err("%s: unable to convert: %s to an int\n", + __func__, buf); + return -EINVAL; + } + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + + pr_err("%s: unable to match device to valid smd_pkt port\n", __func__); + return -EINVAL; +} + +static ssize_t open_timeout_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct smd_pkt_dev *smd_pkt_devp; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) { + if (smd_pkt_devp->devicep == d) { + mutex_unlock(&smd_pkt_dev_lock_lha1); + return snprintf(buf, PAGE_SIZE, "%d\n", + smd_pkt_devp->open_modem_wait); + } + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + pr_err("%s: unable to match device to valid smd_pkt port\n", __func__); + return -EINVAL; + +} + +static DEVICE_ATTR(open_timeout, 0664, open_timeout_show, open_timeout_store); + +/** + * loopback_edge_store() - Set the edge type for loopback device + * @d: Linux device structure + * @attr: Device attribute structure + * @buf: Input string + * @n: Length of the input string + * + * This function is used to set the loopback device edge runtime + * by writing to the loopback_edge node. + */ +static ssize_t loopback_edge_store(struct device *d, + struct device_attribute *attr, + const char *buf, + size_t n) +{ + struct smd_pkt_dev *smd_pkt_devp; + unsigned long tmp; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) { + if (smd_pkt_devp->devicep == d) { + if (!kstrtoul(buf, 10, &tmp)) { + smd_pkt_devp->edge = tmp; + mutex_unlock(&smd_pkt_dev_lock_lha1); + return n; + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + pr_err("%s: unable to convert: %s to an int\n", + __func__, buf); + return -EINVAL; + } + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + pr_err("%s: unable to match device to valid smd_pkt port\n", __func__); + return -EINVAL; +} + +/** + * loopback_edge_show() - Get the edge type for loopback device + * @d: Linux device structure + * @attr: Device attribute structure + * @buf: Output buffer + * + * This function is used to get the loopback device edge runtime + * by reading the loopback_edge node. + */ +static ssize_t loopback_edge_show(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct smd_pkt_dev *smd_pkt_devp; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) { + if (smd_pkt_devp->devicep == d) { + mutex_unlock(&smd_pkt_dev_lock_lha1); + return snprintf(buf, PAGE_SIZE, "%d\n", + smd_pkt_devp->edge); + } + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + pr_err("%s: unable to match device to valid smd_pkt port\n", __func__); + return -EINVAL; + +} + +static DEVICE_ATTR(loopback_edge, 0664, loopback_edge_show, + loopback_edge_store); + +static int notify_reset(struct smd_pkt_dev *smd_pkt_devp) +{ + smd_pkt_devp->do_reset_notification = 0; + + return -ENETRESET; +} + +static void clean_and_signal(struct smd_pkt_dev *smd_pkt_devp) +{ + smd_pkt_devp->do_reset_notification = 1; + smd_pkt_devp->has_reset = 1; + + smd_pkt_devp->is_open = 0; + + wake_up(&smd_pkt_devp->ch_read_wait_queue); + wake_up(&smd_pkt_devp->ch_write_wait_queue); + wake_up_interruptible(&smd_pkt_devp->ch_opened_wait_queue); + D_STATUS("%s smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); +} + +static void loopback_probe_worker(struct work_struct *work) +{ + + /* Wait for the modem SMSM to be inited for the SMD + ** Loopback channel to be allocated at the modem. Since + ** the wait need to be done atmost once, using msleep + ** doesn't degrade the performance. + */ + if (!is_modem_smsm_inited()) + schedule_delayed_work(&loopback_work, msecs_to_jiffies(1000)); + else + smsm_change_state(SMSM_APPS_STATE, + 0, SMSM_SMD_LOOPBACK); + +} + +static void packet_arrival_worker(struct work_struct *work) +{ + struct smd_pkt_dev *smd_pkt_devp; + unsigned long flags; + + smd_pkt_devp = container_of(work, struct smd_pkt_dev, + packet_arrival_work); + mutex_lock(&smd_pkt_devp->ch_lock); + spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags); + if (smd_pkt_devp->ch && smd_pkt_devp->ws_locked) { + D_READ("%s locking smd_pkt_dev id:%d wakeup source\n", + __func__, smd_pkt_devp->i); + /* + * Keep system awake long enough to allow userspace client + * to process the packet. + */ + __pm_wakeup_event(&smd_pkt_devp->pa_ws, WAKEUPSOURCE_TIMEOUT); + } + spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); + mutex_unlock(&smd_pkt_devp->ch_lock); +} + +static long smd_pkt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + struct smd_pkt_dev *smd_pkt_devp; + uint32_t val; + + smd_pkt_devp = file->private_data; + if (!smd_pkt_devp) + return -EINVAL; + + mutex_lock(&smd_pkt_devp->ch_lock); + switch (cmd) { + case TIOCMGET: + D_STATUS("%s TIOCMGET command on smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + ret = smd_tiocmget(smd_pkt_devp->ch); + break; + case TIOCMSET: + ret = get_user(val, (uint32_t *)arg); + if (ret) { + pr_err("Error getting TIOCMSET value\n"); + mutex_unlock(&smd_pkt_devp->ch_lock); + return ret; + } + D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d arg[0x%x]\n", + __func__, smd_pkt_devp->i, val); + ret = smd_tiocmset(smd_pkt_devp->ch, val, ~val); + break; + case SMD_PKT_IOCTL_BLOCKING_WRITE: + ret = get_user(smd_pkt_devp->blocking_write, (int *)arg); + break; + default: + pr_err_ratelimited("%s: Unrecognized ioctl command %d\n", + __func__, cmd); + ret = -ENOIOCTLCMD; + } + mutex_unlock(&smd_pkt_devp->ch_lock); + + return ret; +} + +ssize_t smd_pkt_read(struct file *file, + char __user *_buf, + size_t count, + loff_t *ppos) +{ + int r; + int bytes_read; + int pkt_size; + struct smd_pkt_dev *smd_pkt_devp; + unsigned long flags; + void *buf; + + smd_pkt_devp = file->private_data; + + if (!smd_pkt_devp) { + pr_err_ratelimited("%s on NULL smd_pkt_dev\n", __func__); + return -EINVAL; + } + + if (!smd_pkt_devp->ch) { + pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return -EINVAL; + } + + if (smd_pkt_devp->do_reset_notification) { + /* notify client that a reset occurred */ + E_SMD_PKT_SSR(smd_pkt_devp); + return notify_reset(smd_pkt_devp); + } + D_READ("Begin %s on smd_pkt_dev id:%d buffer_size %zu\n", + __func__, smd_pkt_devp->i, count); + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + +wait_for_packet: + r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue, + !smd_pkt_devp->ch || + (smd_cur_packet_size(smd_pkt_devp->ch) > 0 + && smd_read_avail(smd_pkt_devp->ch)) || + smd_pkt_devp->has_reset); + + mutex_lock(&smd_pkt_devp->rx_lock); + if (smd_pkt_devp->has_reset) { + mutex_unlock(&smd_pkt_devp->rx_lock); + E_SMD_PKT_SSR(smd_pkt_devp); + kfree(buf); + return notify_reset(smd_pkt_devp); + } + + if (!smd_pkt_devp->ch) { + mutex_unlock(&smd_pkt_devp->rx_lock); + pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + kfree(buf); + return -EINVAL; + } + + if (r < 0) { + mutex_unlock(&smd_pkt_devp->rx_lock); + /* qualify error message */ + if (r != -ERESTARTSYS) { + /* we get this anytime a signal comes in */ + pr_err_ratelimited("%s: wait_event_interruptible on smd_pkt_dev id:%d ret %i\n", + __func__, smd_pkt_devp->i, r); + } + kfree(buf); + return r; + } + + /* Here we have a whole packet waiting for us */ + pkt_size = smd_cur_packet_size(smd_pkt_devp->ch); + + if (!pkt_size) { + pr_err_ratelimited("%s: No data on smd_pkt_dev id:%d, False wakeup\n", + __func__, smd_pkt_devp->i); + mutex_unlock(&smd_pkt_devp->rx_lock); + goto wait_for_packet; + } + + if (pkt_size < 0) { + pr_err_ratelimited("%s: Error %d obtaining packet size for Channel %s", + __func__, pkt_size, smd_pkt_devp->ch_name); + kfree(buf); + return pkt_size; + } + + if ((uint32_t)pkt_size > count) { + pr_err_ratelimited("%s: failure on smd_pkt_dev id: %d - packet size %d > buffer size %zu,", + __func__, smd_pkt_devp->i, + pkt_size, count); + mutex_unlock(&smd_pkt_devp->rx_lock); + kfree(buf); + return -ETOOSMALL; + } + + bytes_read = 0; + do { + r = smd_read(smd_pkt_devp->ch, + (buf + bytes_read), + (pkt_size - bytes_read)); + if (r < 0) { + mutex_unlock(&smd_pkt_devp->rx_lock); + if (smd_pkt_devp->has_reset) { + E_SMD_PKT_SSR(smd_pkt_devp); + return notify_reset(smd_pkt_devp); + } + pr_err_ratelimited("%s Error while reading %d\n", + __func__, r); + kfree(buf); + return r; + } + bytes_read += r; + if (pkt_size != bytes_read) + wait_event(smd_pkt_devp->ch_read_wait_queue, + smd_read_avail(smd_pkt_devp->ch) || + smd_pkt_devp->has_reset); + if (smd_pkt_devp->has_reset) { + mutex_unlock(&smd_pkt_devp->rx_lock); + E_SMD_PKT_SSR(smd_pkt_devp); + kfree(buf); + return notify_reset(smd_pkt_devp); + } + } while (pkt_size != bytes_read); + mutex_unlock(&smd_pkt_devp->rx_lock); + + mutex_lock(&smd_pkt_devp->ch_lock); + spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags); + if (smd_pkt_devp->poll_mode && + !smd_cur_packet_size(smd_pkt_devp->ch)) { + __pm_relax(&smd_pkt_devp->pa_ws); + smd_pkt_devp->ws_locked = 0; + smd_pkt_devp->poll_mode = 0; + D_READ("%s unlocked smd_pkt_dev id:%d wakeup_source\n", + __func__, smd_pkt_devp->i); + } + spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); + mutex_unlock(&smd_pkt_devp->ch_lock); + + r = copy_to_user(_buf, buf, bytes_read); + if (r) { + kfree(buf); + return -EFAULT; + } + D_READ("Finished %s on smd_pkt_dev id:%d %d bytes\n", + __func__, smd_pkt_devp->i, bytes_read); + kfree(buf); + + /* check and wakeup read threads waiting on this device */ + check_and_wakeup_reader(smd_pkt_devp); + + return bytes_read; +} + +ssize_t smd_pkt_write(struct file *file, + const char __user *_buf, + size_t count, + loff_t *ppos) +{ + int r = 0, bytes_written; + struct smd_pkt_dev *smd_pkt_devp; + DEFINE_WAIT(write_wait); + void *buf; + + smd_pkt_devp = file->private_data; + + if (!smd_pkt_devp) { + pr_err_ratelimited("%s on NULL smd_pkt_dev\n", __func__); + return -EINVAL; + } + + if (!smd_pkt_devp->ch) { + pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return -EINVAL; + } + + if (smd_pkt_devp->do_reset_notification || smd_pkt_devp->has_reset) { + E_SMD_PKT_SSR(smd_pkt_devp); + /* notify client that a reset occurred */ + return notify_reset(smd_pkt_devp); + } + D_WRITE("Begin %s on smd_pkt_dev id:%d data_size %zu\n", + __func__, smd_pkt_devp->i, count); + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + r = copy_from_user(buf, _buf, count); + if (r) { + kfree(buf); + return -EFAULT; + } + + mutex_lock(&smd_pkt_devp->tx_lock); + if (!smd_pkt_devp->blocking_write) { + if (smd_write_avail(smd_pkt_devp->ch) < count) { + pr_err_ratelimited("%s: Not enough space in smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + mutex_unlock(&smd_pkt_devp->tx_lock); + kfree(buf); + return -ENOMEM; + } + } + + r = smd_write_start(smd_pkt_devp->ch, count); + if (r < 0) { + mutex_unlock(&smd_pkt_devp->tx_lock); + pr_err_ratelimited("%s: Error:%d in smd_pkt_dev id:%d @ smd_write_start\n", + __func__, r, smd_pkt_devp->i); + kfree(buf); + return r; + } + + bytes_written = 0; + do { + prepare_to_wait(&smd_pkt_devp->ch_write_wait_queue, + &write_wait, TASK_UNINTERRUPTIBLE); + if (!smd_write_segment_avail(smd_pkt_devp->ch) && + !smd_pkt_devp->has_reset) { + smd_enable_read_intr(smd_pkt_devp->ch); + schedule(); + } + finish_wait(&smd_pkt_devp->ch_write_wait_queue, &write_wait); + smd_disable_read_intr(smd_pkt_devp->ch); + + if (smd_pkt_devp->has_reset) { + mutex_unlock(&smd_pkt_devp->tx_lock); + E_SMD_PKT_SSR(smd_pkt_devp); + kfree(buf); + return notify_reset(smd_pkt_devp); + } + r = smd_write_segment(smd_pkt_devp->ch, + (void *)(buf + bytes_written), + (count - bytes_written)); + if (r < 0) { + mutex_unlock(&smd_pkt_devp->tx_lock); + if (smd_pkt_devp->has_reset) { + E_SMD_PKT_SSR(smd_pkt_devp); + return notify_reset(smd_pkt_devp); + } + pr_err_ratelimited("%s on smd_pkt_dev id:%d failed r:%d\n", + __func__, smd_pkt_devp->i, r); + kfree(buf); + return r; + } + bytes_written += r; + } while (bytes_written != count); + smd_write_end(smd_pkt_devp->ch); + mutex_unlock(&smd_pkt_devp->tx_lock); + D_WRITE("Finished %s on smd_pkt_dev id:%d %zu bytes\n", + __func__, smd_pkt_devp->i, count); + + kfree(buf); + return count; +} + +static unsigned int smd_pkt_poll(struct file *file, poll_table *wait) +{ + struct smd_pkt_dev *smd_pkt_devp; + unsigned int mask = 0; + + smd_pkt_devp = file->private_data; + if (!smd_pkt_devp) { + pr_err_ratelimited("%s on a NULL device\n", __func__); + return POLLERR; + } + + smd_pkt_devp->poll_mode = 1; + poll_wait(file, &smd_pkt_devp->ch_read_wait_queue, wait); + mutex_lock(&smd_pkt_devp->ch_lock); + if (smd_pkt_devp->has_reset || !smd_pkt_devp->ch) { + mutex_unlock(&smd_pkt_devp->ch_lock); + return POLLERR; + } + + if (smd_read_avail(smd_pkt_devp->ch)) { + mask |= POLLIN | POLLRDNORM; + D_POLL("%s sets POLLIN for smd_pkt_dev id: %d\n", + __func__, smd_pkt_devp->i); + } + mutex_unlock(&smd_pkt_devp->ch_lock); + + return mask; +} + +static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp) +{ + int sz; + unsigned long flags; + + if (!smd_pkt_devp) { + pr_err("%s on a NULL device\n", __func__); + return; + } + + if (!smd_pkt_devp->ch) { + pr_err("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return; + } + + sz = smd_cur_packet_size(smd_pkt_devp->ch); + if (sz == 0) { + D_READ("%s: No packet in smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return; + } + if (!smd_read_avail(smd_pkt_devp->ch)) { + D_READ( + "%s: packet size is %d in smd_pkt_dev id:%d - but the data isn't here\n", + __func__, sz, smd_pkt_devp->i); + return; + } + + /* here we have a packet of size sz ready */ + spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags); + __pm_stay_awake(&smd_pkt_devp->pa_ws); + smd_pkt_devp->ws_locked = 1; + spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); + wake_up(&smd_pkt_devp->ch_read_wait_queue); + schedule_work(&smd_pkt_devp->packet_arrival_work); + D_READ("%s: wake_up smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); +} + +static void check_and_wakeup_writer(struct smd_pkt_dev *smd_pkt_devp) +{ + int sz; + + if (!smd_pkt_devp) { + pr_err("%s on a NULL device\n", __func__); + return; + } + + if (!smd_pkt_devp->ch) { + pr_err("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return; + } + + sz = smd_write_segment_avail(smd_pkt_devp->ch); + if (sz) { + D_WRITE("%s: %d bytes write space in smd_pkt_dev id:%d\n", + __func__, sz, smd_pkt_devp->i); + smd_disable_read_intr(smd_pkt_devp->ch); + wake_up(&smd_pkt_devp->ch_write_wait_queue); + } +} + +static void ch_notify(void *priv, unsigned event) +{ + struct smd_pkt_dev *smd_pkt_devp = priv; + + if (smd_pkt_devp->ch == 0) { + if (event != SMD_EVENT_CLOSE) + pr_err("%s on a closed smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + return; + } + + switch (event) { + case SMD_EVENT_DATA: { + D_STATUS("%s: DATA event in smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + check_and_wakeup_reader(smd_pkt_devp); + if (smd_pkt_devp->blocking_write) + check_and_wakeup_writer(smd_pkt_devp); + break; + } + case SMD_EVENT_OPEN: + D_STATUS("%s: OPEN event in smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + smd_pkt_devp->has_reset = 0; + smd_pkt_devp->is_open = 1; + wake_up_interruptible(&smd_pkt_devp->ch_opened_wait_queue); + break; + case SMD_EVENT_CLOSE: + D_STATUS("%s: CLOSE event in smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + smd_pkt_devp->is_open = 0; + /* put port into reset state */ + clean_and_signal(smd_pkt_devp); + if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK")) + schedule_delayed_work(&loopback_work, + msecs_to_jiffies(1000)); + break; + } +} + +static int smd_pkt_dummy_probe(struct platform_device *pdev) +{ + struct smd_pkt_dev *smd_pkt_devp; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) { + if (smd_pkt_devp->edge == pdev->id + && !strcmp(pdev->name, smd_pkt_devp->ch_name)) { + complete_all(&smd_pkt_devp->ch_allocated); + D_STATUS("%s allocated SMD ch for smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + break; + } + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + return 0; +} + +static uint32_t is_modem_smsm_inited(void) +{ + uint32_t modem_state; + uint32_t ready_state = (SMSM_INIT | SMSM_SMDINIT); + + modem_state = smsm_get_state(SMSM_MODEM_STATE); + return (modem_state & ready_state) == ready_state; +} + +/** + * smd_pkt_add_driver() - Add platform drivers for smd pkt device + * + * @smd_pkt_devp: pointer to the smd pkt device structure + * + * @returns: 0 for success, standard Linux error code otherwise + * + * This function is used to register platform driver once for all + * smd pkt devices which have same names and increment the reference + * count for 2nd to nth devices. + */ +static int smd_pkt_add_driver(struct smd_pkt_dev *smd_pkt_devp) +{ + int r = 0; + struct smd_pkt_driver *smd_pkt_driverp; + struct smd_pkt_driver *item; + + if (!smd_pkt_devp) { + pr_err("%s on a NULL device\n", __func__); + return -EINVAL; + } + D_STATUS("Begin %s on smd_pkt_ch[%s]\n", __func__, + smd_pkt_devp->ch_name); + + mutex_lock(&smd_pkt_driver_lock_lha1); + list_for_each_entry(item, &smd_pkt_driver_list, list) { + if (!strcmp(item->pdriver_name, smd_pkt_devp->ch_name)) { + D_STATUS("%s:%s Already Platform driver reg. cnt:%d\n", + __func__, smd_pkt_devp->ch_name, item->ref_cnt); + ++item->ref_cnt; + goto exit; + } + } + + smd_pkt_driverp = kzalloc(sizeof(*smd_pkt_driverp), GFP_KERNEL); + if (IS_ERR_OR_NULL(smd_pkt_driverp)) { + pr_err("%s: kzalloc() failed for smd_pkt_driver[%s]\n", + __func__, smd_pkt_devp->ch_name); + r = -ENOMEM; + goto exit; + } + + smd_pkt_driverp->driver.probe = smd_pkt_dummy_probe; + scnprintf(smd_pkt_driverp->pdriver_name, SMD_MAX_CH_NAME_LEN, + "%s", smd_pkt_devp->ch_name); + smd_pkt_driverp->driver.driver.name = smd_pkt_driverp->pdriver_name; + smd_pkt_driverp->driver.driver.owner = THIS_MODULE; + r = platform_driver_register(&smd_pkt_driverp->driver); + if (r) { + pr_err("%s: %s Platform driver reg. failed\n", + __func__, smd_pkt_devp->ch_name); + kfree(smd_pkt_driverp); + goto exit; + } + ++smd_pkt_driverp->ref_cnt; + list_add(&smd_pkt_driverp->list, &smd_pkt_driver_list); + +exit: + D_STATUS("End %s on smd_pkt_ch[%s]\n", __func__, smd_pkt_devp->ch_name); + mutex_unlock(&smd_pkt_driver_lock_lha1); + return r; +} + +/** + * smd_pkt_remove_driver() - Remove the platform drivers for smd pkt device + * + * @smd_pkt_devp: pointer to the smd pkt device structure + * + * This function is used to decrement the reference count on + * platform drivers for smd pkt devices and removes the drivers + * when the reference count becomes zero. + */ +static void smd_pkt_remove_driver(struct smd_pkt_dev *smd_pkt_devp) +{ + struct smd_pkt_driver *smd_pkt_driverp; + bool found_item = false; + + if (!smd_pkt_devp) { + pr_err("%s on a NULL device\n", __func__); + return; + } + + D_STATUS("Begin %s on smd_pkt_ch[%s]\n", __func__, + smd_pkt_devp->ch_name); + mutex_lock(&smd_pkt_driver_lock_lha1); + list_for_each_entry(smd_pkt_driverp, &smd_pkt_driver_list, list) { + if (!strcmp(smd_pkt_driverp->pdriver_name, + smd_pkt_devp->ch_name)) { + found_item = true; + D_STATUS("%s:%s Platform driver cnt:%d\n", + __func__, smd_pkt_devp->ch_name, + smd_pkt_driverp->ref_cnt); + if (smd_pkt_driverp->ref_cnt > 0) + --smd_pkt_driverp->ref_cnt; + else + pr_warn("%s reference count <= 0\n", __func__); + break; + } + } + if (!found_item) + pr_err("%s:%s No item found in list.\n", + __func__, smd_pkt_devp->ch_name); + + if (found_item && smd_pkt_driverp->ref_cnt == 0) { + platform_driver_unregister(&smd_pkt_driverp->driver); + smd_pkt_driverp->driver.probe = NULL; + list_del(&smd_pkt_driverp->list); + kfree(smd_pkt_driverp); + } + mutex_unlock(&smd_pkt_driver_lock_lha1); + D_STATUS("End %s on smd_pkt_ch[%s]\n", __func__, smd_pkt_devp->ch_name); +} + +int smd_pkt_open(struct inode *inode, struct file *file) +{ + int r = 0; + struct smd_pkt_dev *smd_pkt_devp; + const char *peripheral = NULL; + + smd_pkt_devp = container_of(inode->i_cdev, struct smd_pkt_dev, cdev); + + if (!smd_pkt_devp) { + pr_err_ratelimited("%s on a NULL device\n", __func__); + return -EINVAL; + } + D_STATUS("Begin %s on smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); + + file->private_data = smd_pkt_devp; + + mutex_lock(&smd_pkt_devp->ch_lock); + if (smd_pkt_devp->ch == 0) { + unsigned open_wait_rem = smd_pkt_devp->open_modem_wait * 1000; + + reinit_completion(&smd_pkt_devp->ch_allocated); + + r = smd_pkt_add_driver(smd_pkt_devp); + if (r) { + pr_err_ratelimited("%s: %s Platform driver reg. failed\n", + __func__, smd_pkt_devp->ch_name); + goto out; + } + + peripheral = smd_edge_to_pil_str(smd_pkt_devp->edge); + if (!IS_ERR_OR_NULL(peripheral)) { + smd_pkt_devp->pil = subsystem_get(peripheral); + if (IS_ERR(smd_pkt_devp->pil)) { + r = PTR_ERR(smd_pkt_devp->pil); + pr_err_ratelimited("%s failed on smd_pkt_dev id:%d - subsystem_get failed for %s\n", + __func__, smd_pkt_devp->i, peripheral); + /* + * Sleep inorder to reduce the frequency of + * retry by user-space modules and to avoid + * possible watchdog bite. + */ + msleep(open_wait_rem); + goto release_pd; + } + } + + /* Wait for the modem SMSM to be inited for the SMD + ** Loopback channel to be allocated at the modem. Since + ** the wait need to be done atmost once, using msleep + ** doesn't degrade the performance. + */ + if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK")) { + if (!is_modem_smsm_inited()) + msleep(5000); + smsm_change_state(SMSM_APPS_STATE, + 0, SMSM_SMD_LOOPBACK); + msleep(100); + } + + /* + * Wait for a packet channel to be allocated so we know + * the modem is ready enough. + */ + if (open_wait_rem) { + r = wait_for_completion_interruptible_timeout( + &smd_pkt_devp->ch_allocated, + msecs_to_jiffies(open_wait_rem)); + if (r >= 0) + open_wait_rem = jiffies_to_msecs(r); + if (r == 0) + r = -ETIMEDOUT; + if (r == -ERESTARTSYS) { + pr_info_ratelimited("%s: wait on smd_pkt_dev id:%d allocation interrupted\n", + __func__, smd_pkt_devp->i); + goto release_pil; + } + if (r < 0) { + pr_err_ratelimited("%s: wait on smd_pkt_dev id:%d allocation failed rc:%d\n", + __func__, smd_pkt_devp->i, r); + goto release_pil; + } + } + + r = smd_named_open_on_edge(smd_pkt_devp->ch_name, + smd_pkt_devp->edge, + &smd_pkt_devp->ch, + smd_pkt_devp, + ch_notify); + if (r < 0) { + pr_err_ratelimited("%s: %s open failed %d\n", __func__, + smd_pkt_devp->ch_name, r); + goto release_pil; + } + + open_wait_rem = max_t(unsigned, 2000, open_wait_rem); + r = wait_event_interruptible_timeout( + smd_pkt_devp->ch_opened_wait_queue, + smd_pkt_devp->is_open, + msecs_to_jiffies(open_wait_rem)); + if (r == 0) + r = -ETIMEDOUT; + + if (r < 0) { + /* close the ch to sync smd's state with smd_pkt */ + smd_close(smd_pkt_devp->ch); + smd_pkt_devp->ch = NULL; + } + + if (r == -ERESTARTSYS) { + pr_info_ratelimited("%s: wait on smd_pkt_dev id:%d OPEN interrupted\n", + __func__, smd_pkt_devp->i); + } else if (r < 0) { + pr_err_ratelimited("%s: wait on smd_pkt_dev id:%d OPEN event failed rc:%d\n", + __func__, smd_pkt_devp->i, r); + } else if (!smd_pkt_devp->is_open) { + pr_err_ratelimited("%s: Invalid OPEN event on smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + r = -ENODEV; + } else { + smd_disable_read_intr(smd_pkt_devp->ch); + smd_pkt_devp->ch_size = + smd_write_avail(smd_pkt_devp->ch); + r = 0; + smd_pkt_devp->ref_cnt++; + D_STATUS("Finished %s on smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + } + } else { + smd_pkt_devp->ref_cnt++; + } +release_pil: + if (peripheral && (r < 0)) { + subsystem_put(smd_pkt_devp->pil); + smd_pkt_devp->pil = NULL; + } + +release_pd: + if (r < 0) + smd_pkt_remove_driver(smd_pkt_devp); +out: + mutex_unlock(&smd_pkt_devp->ch_lock); + + + return r; +} + +int smd_pkt_release(struct inode *inode, struct file *file) +{ + int r = 0; + struct smd_pkt_dev *smd_pkt_devp = file->private_data; + unsigned long flags; + + if (!smd_pkt_devp) { + pr_err_ratelimited("%s on a NULL device\n", __func__); + return -EINVAL; + } + D_STATUS("Begin %s on smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + + mutex_lock(&smd_pkt_devp->ch_lock); + mutex_lock(&smd_pkt_devp->rx_lock); + mutex_lock(&smd_pkt_devp->tx_lock); + if (smd_pkt_devp->ref_cnt > 0) + smd_pkt_devp->ref_cnt--; + + if (smd_pkt_devp->ch != 0 && smd_pkt_devp->ref_cnt == 0) { + clean_and_signal(smd_pkt_devp); + r = smd_close(smd_pkt_devp->ch); + smd_pkt_devp->ch = 0; + smd_pkt_devp->blocking_write = 0; + smd_pkt_devp->poll_mode = 0; + smd_pkt_remove_driver(smd_pkt_devp); + if (smd_pkt_devp->pil) + subsystem_put(smd_pkt_devp->pil); + smd_pkt_devp->has_reset = 0; + smd_pkt_devp->do_reset_notification = 0; + spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags); + if (smd_pkt_devp->ws_locked) { + __pm_relax(&smd_pkt_devp->pa_ws); + smd_pkt_devp->ws_locked = 0; + } + spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); + } + mutex_unlock(&smd_pkt_devp->tx_lock); + mutex_unlock(&smd_pkt_devp->rx_lock); + mutex_unlock(&smd_pkt_devp->ch_lock); + + if (flush_work(&smd_pkt_devp->packet_arrival_work)) + D_STATUS("%s: Flushed work for smd_pkt_dev id:%d\n", __func__, + smd_pkt_devp->i); + + D_STATUS("Finished %s on smd_pkt_dev id:%d\n", + __func__, smd_pkt_devp->i); + + return r; +} + +static const struct file_operations smd_pkt_fops = { + .owner = THIS_MODULE, + .open = smd_pkt_open, + .release = smd_pkt_release, + .read = smd_pkt_read, + .write = smd_pkt_write, + .poll = smd_pkt_poll, + .unlocked_ioctl = smd_pkt_ioctl, + .compat_ioctl = smd_pkt_ioctl, +}; + +static int smd_pkt_init_add_device(struct smd_pkt_dev *smd_pkt_devp, int i) +{ + int r = 0; + + smd_pkt_devp->i = i; + + init_waitqueue_head(&smd_pkt_devp->ch_read_wait_queue); + init_waitqueue_head(&smd_pkt_devp->ch_write_wait_queue); + smd_pkt_devp->is_open = 0; + smd_pkt_devp->poll_mode = 0; + smd_pkt_devp->ws_locked = 0; + init_waitqueue_head(&smd_pkt_devp->ch_opened_wait_queue); + + spin_lock_init(&smd_pkt_devp->pa_spinlock); + mutex_init(&smd_pkt_devp->ch_lock); + mutex_init(&smd_pkt_devp->rx_lock); + mutex_init(&smd_pkt_devp->tx_lock); + wakeup_source_init(&smd_pkt_devp->pa_ws, smd_pkt_devp->dev_name); + INIT_WORK(&smd_pkt_devp->packet_arrival_work, packet_arrival_worker); + init_completion(&smd_pkt_devp->ch_allocated); + + cdev_init(&smd_pkt_devp->cdev, &smd_pkt_fops); + smd_pkt_devp->cdev.owner = THIS_MODULE; + + r = cdev_add(&smd_pkt_devp->cdev, (smd_pkt_number + i), 1); + if (IS_ERR_VALUE(r)) { + pr_err("%s: cdev_add() failed for smd_pkt_dev id:%d ret:%i\n", + __func__, i, r); + return r; + } + + smd_pkt_devp->devicep = + device_create(smd_pkt_classp, + NULL, + (smd_pkt_number + i), + NULL, + smd_pkt_devp->dev_name); + + if (IS_ERR_OR_NULL(smd_pkt_devp->devicep)) { + pr_err("%s: device_create() failed for smd_pkt_dev id:%d\n", + __func__, i); + r = -ENOMEM; + cdev_del(&smd_pkt_devp->cdev); + wakeup_source_trash(&smd_pkt_devp->pa_ws); + return r; + } + if (device_create_file(smd_pkt_devp->devicep, + &dev_attr_open_timeout)) + pr_err("%s: unable to create device attr for smd_pkt_dev id:%d\n", + __func__, i); + + if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK")) { + if (device_create_file(smd_pkt_devp->devicep, + &dev_attr_loopback_edge)) + pr_err("%s: unable to create device attr for smd_pkt_dev id:%d\n", + __func__, i); + } + mutex_lock(&smd_pkt_dev_lock_lha1); + list_add(&smd_pkt_devp->dev_list, &smd_pkt_dev_list); + mutex_unlock(&smd_pkt_dev_lock_lha1); + + return r; +} + +static void smd_pkt_core_deinit(void) +{ + struct smd_pkt_dev *smd_pkt_devp; + struct smd_pkt_dev *index; + + mutex_lock(&smd_pkt_dev_lock_lha1); + list_for_each_entry_safe(smd_pkt_devp, index, &smd_pkt_dev_list, + dev_list) { + cdev_del(&smd_pkt_devp->cdev); + list_del(&smd_pkt_devp->dev_list); + device_destroy(smd_pkt_classp, + MKDEV(MAJOR(smd_pkt_number), smd_pkt_devp->i)); + kfree(smd_pkt_devp); + } + mutex_unlock(&smd_pkt_dev_lock_lha1); + + if (!IS_ERR_OR_NULL(smd_pkt_classp)) + class_destroy(smd_pkt_classp); + + unregister_chrdev_region(MAJOR(smd_pkt_number), num_smd_pkt_ports); +} + +static int smd_pkt_alloc_chrdev_region(void) +{ + int r = alloc_chrdev_region(&smd_pkt_number, + 0, + num_smd_pkt_ports, + DEVICE_NAME); + + if (IS_ERR_VALUE(r)) { + pr_err("%s: alloc_chrdev_region() failed ret:%i\n", + __func__, r); + return r; + } + + smd_pkt_classp = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(smd_pkt_classp)) { + pr_err("%s: class_create() failed ENOMEM\n", __func__); + r = -ENOMEM; + unregister_chrdev_region(MAJOR(smd_pkt_number), + num_smd_pkt_ports); + return r; + } + + return 0; +} + +static int parse_smdpkt_devicetree(struct device_node *node, + struct smd_pkt_dev *smd_pkt_devp) +{ + int edge; + char *key; + const char *ch_name; + const char *dev_name; + const char *remote_ss; + + key = "qcom,smdpkt-remote"; + remote_ss = of_get_property(node, key, NULL); + if (!remote_ss) + goto error; + + edge = smd_remote_ss_to_edge(remote_ss); + if (edge < 0) + goto error; + + smd_pkt_devp->edge = edge; + D_STATUS("%s: %s = %d", __func__, key, edge); + + key = "qcom,smdpkt-port-name"; + ch_name = of_get_property(node, key, NULL); + if (!ch_name) + goto error; + + strlcpy(smd_pkt_devp->ch_name, ch_name, SMD_MAX_CH_NAME_LEN); + D_STATUS("%s ch_name = %s\n", __func__, ch_name); + + key = "qcom,smdpkt-dev-name"; + dev_name = of_get_property(node, key, NULL); + if (!dev_name) + goto error; + + strlcpy(smd_pkt_devp->dev_name, dev_name, SMD_MAX_CH_NAME_LEN); + D_STATUS("%s dev_name = %s\n", __func__, dev_name); + + return 0; + +error: + pr_err("%s: missing key: %s\n", __func__, key); + return -ENODEV; + +} + +static int smd_pkt_devicetree_init(struct platform_device *pdev) +{ + int ret; + int i = 0; + struct device_node *node; + struct smd_pkt_dev *smd_pkt_devp; + int subnode_num = 0; + + for_each_child_of_node(pdev->dev.of_node, node) + ++subnode_num; + + num_smd_pkt_ports = subnode_num; + + ret = smd_pkt_alloc_chrdev_region(); + if (ret) { + pr_err("%s: smd_pkt_alloc_chrdev_region() failed ret:%i\n", + __func__, ret); + return ret; + } + + for_each_child_of_node(pdev->dev.of_node, node) { + smd_pkt_devp = kzalloc(sizeof(struct smd_pkt_dev), GFP_KERNEL); + if (IS_ERR_OR_NULL(smd_pkt_devp)) { + pr_err("%s: kzalloc() failed for smd_pkt_dev id:%d\n", + __func__, i); + ret = -ENOMEM; + goto error_destroy; + } + + ret = parse_smdpkt_devicetree(node, smd_pkt_devp); + if (ret) { + pr_err(" failed to parse_smdpkt_devicetree %d\n", i); + kfree(smd_pkt_devp); + goto error_destroy; + } + + ret = smd_pkt_init_add_device(smd_pkt_devp, i); + if (ret < 0) { + pr_err("add device failed for idx:%d ret=%d\n", i, ret); + kfree(smd_pkt_devp); + goto error_destroy; + } + i++; + } + + INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); + + D_STATUS("SMD Packet Port Driver Initialized.\n"); + return 0; + +error_destroy: + smd_pkt_core_deinit(); + return ret; +} + +static int msm_smd_pkt_probe(struct platform_device *pdev) +{ + int ret; + + if (pdev) { + if (pdev->dev.of_node) { + D_STATUS("%s device tree implementation\n", __func__); + ret = smd_pkt_devicetree_init(pdev); + if (ret) + pr_err("%s: device tree init failed\n", + __func__); + } + } + + return 0; +} + +static const struct of_device_id msm_smd_pkt_match_table[] = { + { .compatible = "qcom,smdpkt" }, + {}, +}; + +static struct platform_driver msm_smd_pkt_driver = { + .probe = msm_smd_pkt_probe, + .driver = { + .name = MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = msm_smd_pkt_match_table, + }, +}; + +static int __init smd_pkt_init(void) +{ + int rc; + + INIT_LIST_HEAD(&smd_pkt_dev_list); + INIT_LIST_HEAD(&smd_pkt_driver_list); + rc = platform_driver_register(&msm_smd_pkt_driver); + if (rc) { + pr_err("%s: msm_smd_driver register failed %d\n", + __func__, rc); + return rc; + } + + smd_pkt_ilctxt = ipc_log_context_create(SMD_PKT_IPC_LOG_PAGE_CNT, + "smd_pkt", 0); + return 0; +} + +static void __exit smd_pkt_cleanup(void) +{ + smd_pkt_core_deinit(); +} + +module_init(smd_pkt_init); +module_exit(smd_pkt_cleanup); + +MODULE_DESCRIPTION("MSM Shared Memory Packet Port"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 65f7eecc45b01c489e2381b2311a95f2898527df..f10a107614b47dab06df4ad2166fa3f321fda822 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -401,7 +401,7 @@ static void disable_interrupts(struct tpm_chip *chip) iowrite32(intmask, chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); - free_irq(chip->vendor.irq, chip); + devm_free_irq(chip->pdev, chip->vendor.irq, chip); chip->vendor.irq = 0; } diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 090183f812beb18dee9b88bbeff7da41801dcf40..31e8ae916ba0d8ec4425d33aca2ab7b08eb6e50a 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1130,6 +1130,8 @@ static int put_chars(u32 vtermno, const char *buf, int count) { struct port *port; struct scatterlist sg[1]; + void *data; + int ret; if (unlikely(early_put_chars)) return early_put_chars(vtermno, buf, count); @@ -1138,8 +1140,14 @@ static int put_chars(u32 vtermno, const char *buf, int count) if (!port) return -EPIPE; - sg_init_one(sg, buf, count); - return __send_to_port(port, sg, 1, count, (void *)buf, false); + data = kmemdup(buf, count, GFP_ATOMIC); + if (!data) + return -ENOMEM; + + sg_init_one(sg, data, count); + ret = __send_to_port(port, sg, 1, count, data, false); + kfree(data); + return ret; } /* diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4a9e034f939fb3609a6348f6018329bac5672fe5..73d65813de8b18a260d0d872477612e48ff54185 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1751,6 +1751,15 @@ static int clk_change_rate(struct clk_core *core) else if (core->parent) best_parent_rate = core->parent->rate; + trace_clk_set_rate(core, core->new_rate); + + /* Enforce vdd requirements for new frequency. */ + if (core->prepare_count) { + rc = clk_vote_rate_vdd(core, core->new_rate); + if (rc) + goto out; + } + if (core->new_parent && core->new_parent != core->parent) { old_parent = __clk_set_parent_before(core, core->new_parent); trace_clk_set_parent(core, core->new_parent); @@ -1768,15 +1777,6 @@ static int clk_change_rate(struct clk_core *core) __clk_set_parent_after(core, core->new_parent, old_parent); } - trace_clk_set_rate(core, core->new_rate); - - /* Enforce vdd requirements for new frequency. */ - if (core->prepare_count) { - rc = clk_vote_rate_vdd(core, core->new_rate); - if (rc) - goto out; - } - if (!skip_set_rate && core->ops->set_rate) { rc = core->ops->set_rate(core->hw, core->new_rate, best_parent_rate); @@ -2326,6 +2326,56 @@ static struct hlist_head *orphan_list[] = { NULL, }; +static void clk_state_subtree(struct clk_core *c) +{ + int vdd_level = 0; + struct clk_core *child; + + if (!c) + return; + + if (c->vdd_class) { + vdd_level = clk_find_vdd_level(c, c->rate); + if (vdd_level < 0) + vdd_level = 0; + } + + trace_clk_state(c->name, c->prepare_count, c->enable_count, + c->rate, vdd_level); + + hlist_for_each_entry(child, &c->children, child_node) + clk_state_subtree(child); +} + +static int clk_state_show(struct seq_file *s, void *data) +{ + struct clk_core *c; + struct hlist_head **lists = (struct hlist_head **)s->private; + + clk_prepare_lock(); + + for (; *lists; lists++) + hlist_for_each_entry(c, *lists, child_node) + clk_state_subtree(c); + + clk_prepare_unlock(); + + return 0; +} + + +static int clk_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, clk_state_show, inode->i_private); +} + +static const struct file_operations clk_state_fops = { + .open = clk_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level) { @@ -3002,6 +3052,11 @@ static int __init clk_debug_init(void) if (!d) return -ENOMEM; + d = debugfs_create_file("trace_clocks", S_IRUGO, rootdir, &all_lists, + &clk_state_fops); + if (!d) + return -ENOMEM; + mutex_lock(&clk_debug_lock); hlist_for_each_entry(core, &clk_debug_list, debug_node) clk_debug_create_one(core, rootdir); diff --git a/drivers/clk/msm/clock-cpu-8996.c b/drivers/clk/msm/clock-cpu-8996.c index bcda6f31d6f56bb155a7394f3f4a1b76178d9af7..bca8ada97f7dd1bef85824e0812fe19fcd4cb58f 100644 --- a/drivers/clk/msm/clock-cpu-8996.c +++ b/drivers/clk/msm/clock-cpu-8996.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1308,6 +1308,7 @@ static int cpu_clock_8996_driver_probe(struct platform_device *pdev) unsigned long pwrclrate, perfclrate, cbfrate; int pvs_ver = 0; u32 pte_efuse; + u32 clk_rate; char perfclspeedbinstr[] = "qcom,perfcl-speedbinXX-vXX"; char pwrclspeedbinstr[] = "qcom,pwrcl-speedbinXX-vXX"; char cbfspeedbinstr[] = "qcom,cbf-speedbinXX-vXX"; @@ -1435,6 +1436,18 @@ static int cpu_clock_8996_driver_probe(struct platform_device *pdev) clk_prepare_enable(&pwrcl_alt_pll.c); clk_prepare_enable(&cbf_pll.c); + /* Override the existing ealry boot frequency for power cluster */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,pwrcl-early-boot-freq", &clk_rate); + if (!ret) + pwrcl_early_boot_rate = clk_rate; + + /* Override the existing ealry boot frequency for perf cluster */ + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,perfcl-early-boot-freq", &clk_rate); + if (!ret) + perfcl_early_boot_rate = clk_rate; + /* Set the early boot rate. This may also switch us to the ACD leg */ clk_set_rate(&pwrcl_clk.c, pwrcl_early_boot_rate); clk_set_rate(&perfcl_clk.c, perfcl_early_boot_rate); @@ -1450,6 +1463,7 @@ static struct of_device_id match_table[] = { { .compatible = "qcom,cpu-clock-8996" }, { .compatible = "qcom,cpu-clock-8996-v3" }, { .compatible = "qcom,cpu-clock-8996-pro" }, + { .compatible = "qcom,cpu-clock-8996-auto" }, {} }; @@ -1499,6 +1513,9 @@ module_exit(cpu_clock_8996_exit); #define HF_MUX_SEL_LF_MUX 0x1 #define LF_MUX_SEL_ALT_PLL 0x1 +#define PWRCL_EARLY_BOOT_RATE 1286400000 +#define PERFCL_EARLY_BOOT_RATE 1363200000 + static int use_alt_pll; module_param(use_alt_pll, int, 0444); @@ -1536,6 +1553,12 @@ int __init cpu_clock_8996_early_init(void) "qcom,cpu-clock-8996-pro")) { cpu_clocks_v3 = true; cpu_clocks_pro = true; + } else if (of_find_compatible_node(NULL, NULL, + "qcom,cpu-clock-8996-auto")) { + cpu_clocks_v3 = true; + cpu_clocks_pro = true; + pwrcl_early_boot_rate = PWRCL_EARLY_BOOT_RATE; + perfcl_early_boot_rate = PERFCL_EARLY_BOOT_RATE; } else if (of_find_compatible_node(NULL, NULL, "qcom,cpu-clock-8996-v3")) { cpu_clocks_v3 = true; diff --git a/drivers/clk/msm/clock-gcc-8996.c b/drivers/clk/msm/clock-gcc-8996.c index e93e9c494023d68ce3ff59cf4bf4e94211b491b0..6dd2cf879c497c14be420e3dab0a59a33f38b943 100644 --- a/drivers/clk/msm/clock-gcc-8996.c +++ b/drivers/clk/msm/clock-gcc-8996.c @@ -3670,14 +3670,6 @@ static int msm_gcc_8996_probe(struct platform_device *pdev) regval |= BIT(21); writel_relaxed(regval, virt_base + GCC_APCS_CLOCK_BRANCH_ENA_VOTE); - /* - * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be - * turned off by hardware during certain apps low power modes. - */ - regval = readl_relaxed(virt_base + GCC_APCS_CLOCK_SLEEP_ENA_VOTE); - regval |= BIT(21); - writel_relaxed(regval, virt_base + GCC_APCS_CLOCK_SLEEP_ENA_VOTE); - vdd_dig.vdd_uv[1] = RPM_REGULATOR_CORNER_SVS_KRAIT; vdd_dig.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_dig"); if (IS_ERR(vdd_dig.regulator[0])) { diff --git a/drivers/clk/msm/clock-local2.c b/drivers/clk/msm/clock-local2.c index 19956f030ae9bf7a9b2cd39ea1f98bcec7e3864d..adb07cdb7e8d22bc7ad3f26c2fdf47e32b900750 100644 --- a/drivers/clk/msm/clock-local2.c +++ b/drivers/clk/msm/clock-local2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -928,7 +928,8 @@ static unsigned long branch_clk_get_rate(struct clk *c) { struct branch_clk *branch = to_branch_clk(c); - if (branch->max_div) + if (branch->max_div || + (branch->aggr_sibling_rates && !branch->is_prepared)) return branch->c.rate; return clk_get_rate(c->parent); diff --git a/drivers/clk/msm/clock-mmss-8998.c b/drivers/clk/msm/clock-mmss-8998.c index 6ebb3ed6ed9199ab968d72fdba8f76feec81f20d..fdaaa723accd83949c2a9104b008aa5212bb7949 100644 --- a/drivers/clk/msm/clock-mmss-8998.c +++ b/drivers/clk/msm/clock-mmss-8998.c @@ -359,6 +359,7 @@ static struct rcg_clk mdp_clk_src = { .set_rate = set_rate_hid, .freq_tbl = ftbl_mdp_clk_src, .current_freq = &rcg_dummy_freq, + .non_local_children = true, .base = &virt_base, .c = { .dbg_name = "mdp_clk_src", diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index f82ddc3b008b38f849db91cf96a2d4115cb276e1..8bf45f572c5e5c2d1530beee9eeb70bf34e82062 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -84,12 +84,14 @@ enum clk_osm_trace_packet_id { #define VERSION_REG 0x0 #define OSM_TABLE_SIZE 40 +#define MAX_VIRTUAL_CORNER (OSM_TABLE_SIZE - 1) #define MAX_CLUSTER_CNT 2 #define LLM_SW_OVERRIDE_CNT 3 #define CORE_COUNT_VAL(val) ((val & GENMASK(18, 16)) >> 16) #define SINGLE_CORE 1 #define MAX_CORE_COUNT 4 #define DEBUG_REG_NUM 3 +#define OSM_SEQ_MINUS_ONE 0xff #define ENABLE_REG 0x1004 #define INDEX_REG 0x1150 @@ -353,8 +355,10 @@ struct clk_osm { u32 cluster_num; u32 irq; u32 apm_crossover_vc; + u32 apm_threshold_pre_vc; u32 apm_threshold_vc; u32 mem_acc_crossover_vc; + u32 mem_acc_threshold_pre_vc; u32 mem_acc_threshold_vc; u32 cycle_counter_reads; u32 cycle_counter_delay; @@ -772,7 +776,7 @@ static const char * const gcc_parent_names_1[] = { }; static struct freq_tbl ftbl_osm_clk_src[] = { - F(200000000, LMH_LITE_CLK_SRC, 3, 0, 0), + F(200000000, LMH_LITE_CLK_SRC, 1.5, 0, 0), { } }; @@ -1622,10 +1626,26 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c, if (corner_volt >= apm_threshold) { c->apm_threshold_vc = c->osm_table[i].virtual_corner; + /* + * Handle case where VC 0 has open-loop + * greater than or equal to APM threshold voltage. + */ + c->apm_threshold_pre_vc = c->apm_threshold_vc ? + c->apm_threshold_vc - 1 : OSM_SEQ_MINUS_ONE; break; } } + /* + * This assumes the OSM table uses corners + * 0 to MAX_VIRTUAL_CORNER - 1. + */ + if (!c->apm_threshold_vc && + c->apm_threshold_pre_vc != OSM_SEQ_MINUS_ONE) { + c->apm_threshold_vc = MAX_VIRTUAL_CORNER; + c->apm_threshold_pre_vc = c->apm_threshold_vc - 1; + } + /* Determine MEM ACC threshold virtual corner */ if (mem_acc_threshold) { for (i = 0; i < OSM_TABLE_SIZE; i++) { @@ -1636,9 +1656,30 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c, if (corner_volt >= mem_acc_threshold) { c->mem_acc_threshold_vc = c->osm_table[i].virtual_corner; + /* + * Handle case where VC 0 has open-loop + * greater than or equal to MEM-ACC threshold + * voltage. + */ + c->mem_acc_threshold_pre_vc = + c->mem_acc_threshold_vc ? + c->mem_acc_threshold_vc - 1 : + OSM_SEQ_MINUS_ONE; break; } } + + /* + * This assumes the OSM table uses corners + * 0 to MAX_VIRTUAL_CORNER - 1. + */ + if (!c->mem_acc_threshold_vc && c->mem_acc_threshold_pre_vc + != OSM_SEQ_MINUS_ONE) { + c->mem_acc_threshold_vc = + MAX_VIRTUAL_CORNER; + c->mem_acc_threshold_pre_vc = + c->mem_acc_threshold_vc - 1; + } } return 0; @@ -1989,13 +2030,20 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) * highest MEM ACC threshold if it is specified instead of the * fixed mapping in the LUT. */ - if (c->mem_acc_threshold_vc) { - threshold_vc[2] = c->mem_acc_threshold_vc - 1; + if (c->mem_acc_threshold_vc || c->mem_acc_threshold_pre_vc + == OSM_SEQ_MINUS_ONE) { + threshold_vc[2] = c->mem_acc_threshold_pre_vc; threshold_vc[3] = c->mem_acc_threshold_vc; - if (threshold_vc[1] >= threshold_vc[2]) - threshold_vc[1] = threshold_vc[2] - 1; - if (threshold_vc[0] >= threshold_vc[1]) - threshold_vc[0] = threshold_vc[1] - 1; + + if (c->mem_acc_threshold_pre_vc == OSM_SEQ_MINUS_ONE) { + threshold_vc[1] = threshold_vc[0] = + c->mem_acc_threshold_pre_vc; + } else { + if (threshold_vc[1] >= threshold_vc[2]) + threshold_vc[1] = threshold_vc[2] - 1; + if (threshold_vc[0] >= threshold_vc[1]) + threshold_vc[0] = threshold_vc[1] - 1; + } } scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55), @@ -2249,8 +2297,7 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c) clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(1), SEQ_REG(8)); clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(15)); - clk_osm_write_reg(c, c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff, + clk_osm_write_reg(c, c->apm_threshold_pre_vc, SEQ_REG(31)); clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6, SEQ_REG(73)); @@ -2268,8 +2315,7 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c) scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(15), c->apm_threshold_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31), - c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff); + c->apm_threshold_pre_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76), 0x39 | c->apm_threshold_vc << 6); } diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index b55310e091afdde2a9f6b06d07e59efcf561c7dc..251acafca19622342f807a8c111f5dcde20448c2 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -732,6 +732,7 @@ static struct clk_rcg2 gp3_clk_src = { }; static const struct freq_tbl ftbl_hmss_gpll0_clk_src[] = { + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), F(600000000, P_GPLL0_OUT_MAIN, 1, 0, 0), { } }; @@ -2755,6 +2756,9 @@ static int gcc_660_probe(struct platform_device *pdev) /* Keep bimc gfx clock port on all the time */ clk_prepare_enable(gcc_bimc_gfx_clk.clkr.hw.clk); + /* Set the HMSS_GPLL0_SRC for 300MHz to CPU subsystem */ + clk_set_rate(hmss_gpll0_clk_src.clkr.hw.clk, 300000000); + dev_info(&pdev->dev, "Registered GCC clocks\n"); return ret; @@ -2954,6 +2958,9 @@ static const char *const debug_mux_parent_names[] = { "mmss_video_axi_clk", "mmss_video_core_clk", "mmss_video_subcore0_clk", + "mmss_throttle_camss_axi_clk", + "mmss_throttle_mdss_axi_clk", + "mmss_throttle_video_axi_clk", "gpucc_gfx3d_clk", "gpucc_rbbmtimer_clk", "gpucc_rbcpr_clk", @@ -3219,6 +3226,12 @@ static struct clk_debug_mux gcc_debug_mux = { 0x00E, 0, 0, 0x1000, BM(14, 13) }, { "mmss_video_subcore0_clk", 0x22, MMCC, 0x01A, 0, 0, 0x1000, BM(14, 13) }, + { "mmss_throttle_camss_axi_clk", 0x22, MMCC, + 0x0AA, 0, 0, 0x1000, BM(14, 13) }, + { "mmss_throttle_mdss_axi_clk", 0x22, MMCC, + 0x0AB, 0, 0, 0x1000, BM(14, 13) }, + { "mmss_throttle_video_axi_clk", 0x22, MMCC, + 0x0AC, 0, 0, 0x1000, BM(14, 13) }, { "gpucc_gfx3d_clk", 0x13d, GPU, 0x008, 0, 0, 0, BM(18, 17) }, { "gpucc_rbbmtimer_clk", 0x13d, GPU, diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 910c36c65b6a73fdd0508494c2320494cbd63d78..542737e4d2043a1586ecc1e1d75406025b493892 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2053,6 +2053,19 @@ static struct clk_branch mmss_camss_jpeg_axi_clk = { }, }; +static struct clk_branch mmss_throttle_camss_axi_clk = { + .halt_reg = 0x3c3c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3c3c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_throttle_camss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch mmss_camss_mclk0_clk = { .halt_reg = 0x3384, .halt_check = BRANCH_HALT, @@ -2341,6 +2354,19 @@ static struct clk_branch mmss_mdss_axi_clk = { }, }; +static struct clk_branch mmss_throttle_mdss_axi_clk = { + .halt_reg = 0x246c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x246c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_throttle_mdss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch mmss_mdss_byte0_clk = { .halt_reg = 0x233c, .halt_check = BRANCH_HALT, @@ -2801,6 +2827,19 @@ static struct clk_branch mmss_video_axi_clk = { }, }; +static struct clk_branch mmss_throttle_video_axi_clk = { + .halt_reg = 0x118c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x118c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_throttle_video_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch mmss_video_core_clk = { .halt_reg = 0x1028, .halt_check = BRANCH_HALT, @@ -2962,6 +3001,9 @@ static struct clk_regmap *mmcc_660_clocks[] = { [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr, [MMSS_MNOC_AHB_CLK] = &mmss_mnoc_ahb_clk.clkr, [MMSS_SNOC_DVM_AXI_CLK] = &mmss_snoc_dvm_axi_clk.clkr, + [MMSS_THROTTLE_CAMSS_AXI_CLK] = &mmss_throttle_camss_axi_clk.clkr, + [MMSS_THROTTLE_MDSS_AXI_CLK] = &mmss_throttle_mdss_axi_clk.clkr, + [MMSS_THROTTLE_VIDEO_AXI_CLK] = &mmss_throttle_video_axi_clk.clkr, [MMSS_VIDEO_AHB_CLK] = &mmss_video_ahb_clk.clkr, [MMSS_VIDEO_AXI_CLK] = &mmss_video_axi_clk.clkr, [MMSS_VIDEO_CORE_CLK] = &mmss_video_core_clk.clkr, diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index 0214c6548afd19da86fb114db63f75c7d64a9c37..97cb4221de25d2ba1b228757d2d5020b064eb649 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -98,6 +98,8 @@ static void __init sunxi_simple_gates_init(struct device_node *node) sunxi_simple_gates_setup(node, NULL, 0); } +CLK_OF_DECLARE(sun4i_a10_gates, "allwinner,sun4i-a10-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb0, "allwinner,sun4i-a10-apb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb1, "allwinner,sun4i-a10-apb1-gates-clk", diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e4d9aef1dda46b8047a9183eef54223704160bb3..a0dba9beac051f253d42d9ab2b884ad9951df986 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -698,9 +698,11 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, char *buf) { unsigned int cur_freq = __cpufreq_get(policy); - if (!cur_freq) - return sprintf(buf, ""); - return sprintf(buf, "%u\n", cur_freq); + + if (cur_freq) + return sprintf(buf, "%u\n", cur_freq); + + return sprintf(buf, "\n"); } /** diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 24ac49019b29e134256ee98214d8bd58121b3647..b91e115462ae3891b6c908557b1d2d507f7c634c 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -419,13 +419,13 @@ static u64 update_load(int cpu) ppol->policy->governor_data; u64 now; u64 now_idle; - unsigned int delta_idle; - unsigned int delta_time; + u64 delta_idle; + u64 delta_time; u64 active_time; now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy); - delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle); - delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp); + delta_idle = (now_idle - pcpu->time_in_idle); + delta_time = (now - pcpu->time_in_idle_timestamp); if (delta_time <= delta_idle) active_time = 0; diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index ce67145bb142305d57a3c429a127ece15bc831c1..4224b594f1b896f5a2144cb398ba75072f0566f4 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,8 @@ enum debug_event { CLUSTER_ENTER, CLUSTER_EXIT, PRE_PC_CB, + CPU_HP_STARTING, + CPU_HP_DYING, }; struct lpm_debug { @@ -341,10 +344,16 @@ static int lpm_cpu_callback(struct notifier_block *cpu_nb, switch (action & ~CPU_TASKS_FROZEN) { case CPU_DYING: + update_debug_pc_event(CPU_HP_DYING, cpu, + cluster->num_children_in_sync.bits[0], + cluster->child_cpus.bits[0], false); cluster_prepare(cluster, get_cpu_mask((unsigned int) cpu), NR_LPM_LEVELS, false, 0); break; case CPU_STARTING: + update_debug_pc_event(CPU_HP_STARTING, cpu, + cluster->num_children_in_sync.bits[0], + cluster->child_cpus.bits[0], false); cluster_unprepare(cluster, get_cpu_mask((unsigned int) cpu), NR_LPM_LEVELS, false, 0); break; @@ -682,7 +691,7 @@ static int cpu_power_select(struct cpuidle_device *dev, if (!cpu) return -EINVAL; - if (sleep_disabled) + if (sleep_disabled && !cpu_isolated(dev->cpu)) return 0; idx_restrict = cpu->nlevels + 1; @@ -1846,6 +1855,7 @@ static int lpm_probe(struct platform_device *pdev) int ret; int size; struct kobject *module_kobj = NULL; + struct md_region md_entry; get_online_cpus(); lpm_root_node = lpm_of_parse_cluster(pdev); @@ -1906,6 +1916,14 @@ static int lpm_probe(struct platform_device *pdev) goto failed; } + /* Add lpm_debug to Minidump*/ + strlcpy(md_entry.name, "KLPMDEBUG", sizeof(md_entry.name)); + md_entry.virt_addr = (uintptr_t)lpm_debug; + md_entry.phys_addr = lpm_debug_phys; + md_entry.size = size; + if (msm_minidump_add_region(&md_entry)) + pr_info("Failed to add lpm_debug in Minidump\n"); + return 0; failed: free_cluster_node(lpm_root_node); diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 69d4a1326feefa6ff4c404d7e093a658728f6f4a..53e61459c69f4c81caa33004663bcbc84d32ddb9 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -278,7 +278,8 @@ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) /* Try to run it through DECO0 */ ret = run_descriptor_deco0(ctrldev, desc, &status); - if (ret || status) { + if (ret || + (status && status != JRSTA_SSRC_JUMP_HALT_CC)) { dev_err(ctrldev, "Failed to deinstantiate RNG4 SH%d\n", sh_idx); diff --git a/drivers/crypto/msm/ota_crypto.c b/drivers/crypto/msm/ota_crypto.c index 674913cb20bfe729ab56506df2c4ea138cf7b689..a568bf46f09fe6c640982747f0c72ea353459eaf 100644 --- a/drivers/crypto/msm/ota_crypto.c +++ b/drivers/crypto/msm/ota_crypto.c @@ -239,6 +239,9 @@ static void req_done(unsigned long data) if (!list_empty(&podev->ready_commands)) { new_req = container_of(podev->ready_commands.next, struct ota_async_req, rlist); + if (!new_req) + break; + list_del(&new_req->rlist); pqce->active_command = new_req; spin_unlock_irqrestore(&podev->lock, flags); diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index 7459401979fe94f40099b5093cf28da109b3127d..d04ca6f28f90be4bc67377cf8a5104ff92fb769c 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -56,6 +56,7 @@ static uint8_t _std_init_vector_sha256_uint8[] = { static DEFINE_MUTEX(send_cmd_lock); static DEFINE_MUTEX(qcedev_sent_bw_req); +static DEFINE_MUTEX(hash_access_lock); static void qcedev_ce_high_bw_req(struct qcedev_control *podev, bool high_bw_req) @@ -1648,12 +1649,18 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; - if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) + mutex_lock(&hash_access_lock); + if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) { + mutex_unlock(&hash_access_lock); return -EINVAL; + } qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA; err = qcedev_hash_init(&qcedev_areq, handle, &sg_src); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } + mutex_unlock(&hash_access_lock); if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1671,32 +1678,42 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; - if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) + mutex_lock(&hash_access_lock); + if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) { + mutex_unlock(&hash_access_lock); return -EINVAL; + } qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA; if (qcedev_areq.sha_op_req.alg == QCEDEV_ALG_AES_CMAC) { err = qcedev_hash_cmac(&qcedev_areq, handle, &sg_src); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } } else { if (handle->sha_ctxt.init_done == false) { pr_err("%s Init was not called\n", __func__); + mutex_unlock(&hash_access_lock); return -EINVAL; } err = qcedev_hash_update(&qcedev_areq, handle, &sg_src); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } } if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) { pr_err("Invalid sha_ctxt.diglen %d\n", handle->sha_ctxt.diglen); + mutex_unlock(&hash_access_lock); return -EINVAL; } memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); + mutex_unlock(&hash_access_lock); if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1713,16 +1730,22 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; - if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) + mutex_lock(&hash_access_lock); + if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) { + mutex_unlock(&hash_access_lock); return -EINVAL; + } qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA; err = qcedev_hash_final(&qcedev_areq, handle); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } qcedev_areq.sha_op_req.diglen = handle->sha_ctxt.diglen; memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); + mutex_unlock(&hash_access_lock); if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1737,20 +1760,28 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; - if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) + mutex_lock(&hash_access_lock); + if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev)) { + mutex_unlock(&hash_access_lock); return -EINVAL; + } qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA; qcedev_hash_init(&qcedev_areq, handle, &sg_src); err = qcedev_hash_update(&qcedev_areq, handle, &sg_src); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } err = qcedev_hash_final(&qcedev_areq, handle); - if (err) + if (err) { + mutex_unlock(&hash_access_lock); return err; + } qcedev_areq.sha_op_req.diglen = handle->sha_ctxt.diglen; memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); + mutex_unlock(&hash_access_lock); if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c index b997e79e3d732e8bf61df45f5a1d6bd0fc63fb58..972de02ca5493c25c7308eea2add3565e2cd15e8 100644 --- a/drivers/devfreq/governor_bw_hwmon.c +++ b/drivers/devfreq/governor_bw_hwmon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -86,6 +86,8 @@ static DEFINE_SPINLOCK(irq_lock); static LIST_HEAD(hwmon_list); static DEFINE_MUTEX(list_lock); +static DEFINE_MUTEX(sync_lock); + static int use_cnt; static DEFINE_MUTEX(state_lock); @@ -846,6 +848,7 @@ static int devfreq_bw_hwmon_ev_handler(struct devfreq *df, break; case DEVFREQ_GOV_INTERVAL: + mutex_lock(&sync_lock); sample_ms = *(unsigned int *)data; sample_ms = max(MIN_MS, sample_ms); sample_ms = min(MAX_MS, sample_ms); @@ -865,6 +868,7 @@ static int devfreq_bw_hwmon_ev_handler(struct devfreq *df, "Unable to resume HW monitor (%d)\n", ret); return ret; } + mutex_unlock(&sync_lock); break; case DEVFREQ_GOV_SUSPEND: diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c index 1e5f35d8422ddb9f1508d1e0003f483c0da10f25..26f69fa61ba12cd575fe8555fe3daf8dcb36e313 100644 --- a/drivers/esoc/esoc-mdm-4x.c +++ b/drivers/esoc/esoc-mdm-4x.c @@ -179,26 +179,48 @@ static int mdm_cmd_exe(enum esoc_cmd cmd, struct esoc_clink *esoc) struct device *dev = mdm->dev; int ret; bool graceful_shutdown = false; + u32 status, err_fatal; switch (cmd) { case ESOC_PWR_ON: + if (esoc->auto_boot) { + /* + * If esoc has already booted, we would have missed + * status change interrupt. Read status and err_fatal + * signals to arrive at the state of esoc. + */ + esoc->clink_ops->get_status(&status, esoc); + esoc->clink_ops->get_err_fatal(&err_fatal, esoc); + if (err_fatal) + return -EIO; + if (status && !mdm->ready) { + mdm->ready = true; + esoc->clink_ops->notify(ESOC_BOOT_DONE, esoc); + } + } gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0); - mdm_enable_irqs(mdm); mdm->init = 1; mdm_do_first_power_on(mdm); + mdm_enable_irqs(mdm); break; case ESOC_PWR_OFF: mdm_disable_irqs(mdm); mdm->debug = 0; mdm->ready = false; mdm->trig_cnt = 0; + if (esoc->primary) + break; graceful_shutdown = true; - ret = sysmon_send_shutdown(&esoc->subsys); - if (ret) { - dev_err(mdm->dev, "sysmon shutdown fail, ret = %d\n", - ret); - graceful_shutdown = false; - goto force_poff; + if (!esoc->userspace_handle_shutdown) { + ret = sysmon_send_shutdown(&esoc->subsys); + if (ret) { + dev_err(mdm->dev, + "sysmon shutdown fail, ret = %d\n", ret); + graceful_shutdown = false; + goto force_poff; + } + } else { + esoc_clink_queue_request(ESOC_REQ_SEND_SHUTDOWN, esoc); } dev_dbg(mdm->dev, "Waiting for status gpio go low\n"); status_down = false; @@ -228,12 +250,17 @@ force_poff: esoc->subsys.sysmon_shutdown_ret); } + if (esoc->primary) + break; /* * Force a shutdown of the mdm. This is required in order * to prevent the mdm from immediately powering back on - * after the shutdown + * after the shutdown. Avoid setting status to 0, if line is + * monitored by multiple mdms(might be wrongly interpreted as + * a primary crash). */ - gpio_set_value(MDM_GPIO(mdm, AP2MDM_STATUS), 0); + if (esoc->statusline_not_a_powersource == false) + gpio_set_value(MDM_GPIO(mdm, AP2MDM_STATUS), 0); esoc_clink_queue_request(ESOC_REQ_SHUTDOWN, esoc); mdm_power_down(mdm); mdm_update_gpio_configs(mdm, GPIO_UPDATE_BOOTING_CONFIG); @@ -249,9 +276,12 @@ force_poff: */ mdm->ready = false; cancel_delayed_work(&mdm->mdm2ap_status_check_work); - gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1); - dev_dbg(mdm->dev, "set ap2mdm errfatal to force reset\n"); - msleep(mdm->ramdump_delay_ms); + if (!mdm->esoc->auto_boot) { + gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1); + dev_dbg(mdm->dev, + "set ap2mdm errfatal to force reset\n"); + msleep(mdm->ramdump_delay_ms); + } break; case ESOC_EXE_DEBUG: mdm->debug = 1; @@ -378,6 +408,8 @@ static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc) status_down = false; dev_dbg(dev, "signal apq err fatal for graceful restart\n"); gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1); + if (esoc->primary) + break; timeout = local_clock(); do_div(timeout, NSEC_PER_MSEC); timeout += MDM_MODEM_TIMEOUT; @@ -420,7 +452,8 @@ static irqreturn_t mdm_errfatal(int irq, void *dev_id) goto mdm_pwroff_irq; esoc = mdm->esoc; dev_err(dev, "%s: mdm sent errfatal interrupt\n", - __func__); + __func__); + subsys_set_crash_status(esoc->subsys_dev, true); /* disable irq ?*/ esoc_clink_evt_notify(ESOC_ERR_FATAL, esoc); return IRQ_HANDLED; @@ -441,11 +474,26 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) return IRQ_HANDLED; dev = mdm->dev; esoc = mdm->esoc; + /* + * On auto boot devices, there is a possibility of receiving + * status change interrupt before esoc_clink structure is + * initialized. Ignore them. + */ + if (!esoc) + return IRQ_HANDLED; value = gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)); if (value == 0 && mdm->ready) { dev_err(dev, "unexpected reset external modem\n"); + subsys_set_crash_status(esoc->subsys_dev, true); esoc_clink_evt_notify(ESOC_UNEXPECTED_RESET, esoc); } else if (value == 1) { + /* + * In auto_boot cases, bailout early if mdm + * is up already. + */ + if (esoc->auto_boot && mdm->ready) + return IRQ_HANDLED; + cancel_delayed_work(&mdm->mdm2ap_status_check_work); dev_dbg(dev, "status = 1: mdm is now ready\n"); mdm->ready = true; @@ -453,6 +501,8 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) queue_work(mdm->mdm_queue, &mdm->mdm_status_work); if (mdm->get_restart_reason) queue_work(mdm->mdm_queue, &mdm->restart_reason_work); + if (esoc->auto_boot) + esoc->clink_ops->notify(ESOC_BOOT_DONE, esoc); } return IRQ_HANDLED; } @@ -481,7 +531,7 @@ static irqreturn_t mdm_pblrdy_change(int irq, void *dev_id) return IRQ_HANDLED; } -static int mdm_get_status(u32 *status, struct esoc_clink *esoc) +static void mdm_get_status(u32 *status, struct esoc_clink *esoc) { struct mdm_ctrl *mdm = get_esoc_clink_data(esoc); @@ -489,7 +539,16 @@ static int mdm_get_status(u32 *status, struct esoc_clink *esoc) *status = 0; else *status = 1; - return 0; +} + +static void mdm_get_err_fatal(u32 *status, struct esoc_clink *esoc) +{ + struct mdm_ctrl *mdm = get_esoc_clink_data(esoc); + + if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_ERRFATAL)) == 0) + *status = 0; + else + *status = 1; } static void mdm_configure_debug(struct mdm_ctrl *mdm) @@ -573,13 +632,21 @@ static int mdm_configure_ipc(struct mdm_ctrl *mdm, struct platform_device *pdev) &mdm->ramdump_delay_ms); if (ret) mdm->ramdump_delay_ms = DEF_RAMDUMP_DELAY; - /* Multilple gpio_request calls are allowed */ + /* + * In certain scenarios, multiple esoc devices are monitoring + * same AP2MDM_STATUS line. But only one of them will have a + * successful gpio_request call. Initialize gpio only if request + * succeeds. + */ if (gpio_request(MDM_GPIO(mdm, AP2MDM_STATUS), "AP2MDM_STATUS")) dev_err(dev, "Failed to configure AP2MDM_STATUS gpio\n"); - /* Multilple gpio_request calls are allowed */ + else + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 0); if (gpio_request(MDM_GPIO(mdm, AP2MDM_ERRFATAL), "AP2MDM_ERRFATAL")) dev_err(dev, "%s Failed to configure AP2MDM_ERRFATAL gpio\n", __func__); + else + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0); if (gpio_request(MDM_GPIO(mdm, MDM2AP_STATUS), "MDM2AP_STATUS")) { dev_err(dev, "%s Failed to configure MDM2AP_STATUS gpio\n", __func__); @@ -612,9 +679,6 @@ static int mdm_configure_ipc(struct mdm_ctrl *mdm, struct platform_device *pdev) } } - gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 0); - gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0); - if (gpio_is_valid(MDM_GPIO(mdm, AP2MDM_CHNLRDY))) gpio_direction_output(MDM_GPIO(mdm, AP2MDM_CHNLRDY), 0); @@ -748,6 +812,7 @@ static int mdm9x25_setup_hw(struct mdm_ctrl *mdm, dev_err(mdm->dev, "cannot allocate esoc device\n"); return PTR_ERR(esoc); } + esoc->pdev = pdev; mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0); if (!mdm->mdm_queue) { dev_err(mdm->dev, "could not create mdm_queue\n"); @@ -818,6 +883,7 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm, dev_err(mdm->dev, "cannot allocate esoc device\n"); return PTR_ERR(esoc); } + esoc->pdev = pdev; mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0); if (!mdm->mdm_queue) { dev_err(mdm->dev, "could not create mdm_queue\n"); @@ -888,6 +954,84 @@ static int mdm9x35_setup_hw(struct mdm_ctrl *mdm, return 0; } +static int mdm9x45_setup_hw(struct mdm_ctrl *mdm, + const struct mdm_ops *ops, + struct platform_device *pdev) +{ + int ret; + struct esoc_clink *esoc; + const struct esoc_clink_ops *const clink_ops = ops->clink_ops; + const struct mdm_pon_ops *pon_ops = ops->pon_ops; + + mdm->dev = &pdev->dev; + mdm->pon_ops = pon_ops; + esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL); + if (IS_ERR_OR_NULL(esoc)) { + dev_err(mdm->dev, "cannot allocate esoc device\n"); + return PTR_ERR(esoc); + } + esoc->pdev = pdev; + mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0); + if (!mdm->mdm_queue) { + dev_err(mdm->dev, "could not create mdm_queue\n"); + return -ENOMEM; + } + mdm->irq_mask = 0; + mdm->ready = false; + ret = mdm_dt_parse_gpios(mdm); + if (ret) + return ret; + dev_err(mdm->dev, "parsing gpio done\n"); + ret = mdm_pon_dt_init(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "pon dt init done\n"); + ret = mdm_pinctrl_init(mdm); + if (ret) + return ret; + dev_err(mdm->dev, "pinctrl init done\n"); + ret = mdm_pon_setup(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "pon setup done\n"); + ret = mdm_configure_ipc(mdm, pdev); + if (ret) + return ret; + mdm_configure_debug(mdm); + dev_err(mdm->dev, "ipc configure done\n"); + esoc->name = MDM9x45_LABEL; + esoc->link_name = MDM9x45_PCIE; + esoc->clink_ops = clink_ops; + esoc->parent = mdm->dev; + esoc->owner = THIS_MODULE; + esoc->np = pdev->dev.of_node; + + esoc->auto_boot = of_property_read_bool(esoc->np, + "qcom,mdm-auto-boot"); + esoc->statusline_not_a_powersource = of_property_read_bool(esoc->np, + "qcom,mdm-statusline-not-a-powersource"); + esoc->userspace_handle_shutdown = of_property_read_bool(esoc->np, + "qcom,mdm-userspace-handle-shutdown"); + set_esoc_clink_data(esoc, mdm); + ret = esoc_clink_register(esoc); + if (ret) { + dev_err(mdm->dev, "esoc registration failed\n"); + return ret; + } + dev_dbg(mdm->dev, "esoc registration done\n"); + init_completion(&mdm->debug_done); + INIT_WORK(&mdm->mdm_status_work, mdm_status_fn); + INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason); + INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check); + mdm->get_restart_reason = false; + mdm->debug_fail = false; + mdm->esoc = esoc; + mdm->init = 0; + if (esoc->auto_boot) + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1); + return 0; +} + static int mdm9x55_setup_hw(struct mdm_ctrl *mdm, const struct mdm_ops *ops, struct platform_device *pdev) @@ -906,6 +1050,7 @@ static int mdm9x55_setup_hw(struct mdm_ctrl *mdm, dev_err(mdm->dev, "cannot allocate esoc device\n"); return PTR_ERR(esoc); } + esoc->pdev = pdev; mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0); if (!mdm->mdm_queue) { dev_err(mdm->dev, "could not create mdm_queue\n"); @@ -963,9 +1108,86 @@ static int mdm9x55_setup_hw(struct mdm_ctrl *mdm, return 0; } +static int apq8096_setup_hw(struct mdm_ctrl *mdm, + const struct mdm_ops *ops, + struct platform_device *pdev) +{ + int ret; + struct device_node *node; + struct esoc_clink *esoc; + const struct esoc_clink_ops *const clink_ops = ops->clink_ops; + const struct mdm_pon_ops *pon_ops = ops->pon_ops; + + mdm->dev = &pdev->dev; + mdm->pon_ops = pon_ops; + node = pdev->dev.of_node; + esoc = devm_kzalloc(mdm->dev, sizeof(*esoc), GFP_KERNEL); + if (IS_ERR_OR_NULL(esoc)) { + dev_err(mdm->dev, "cannot allocate esoc device\n"); + return PTR_ERR(esoc); + } + esoc->pdev = pdev; + mdm->mdm_queue = alloc_workqueue("mdm_queue", 0, 0); + if (!mdm->mdm_queue) { + dev_err(mdm->dev, "could not create mdm_queue\n"); + return -ENOMEM; + } + mdm->irq_mask = 0; + mdm->ready = false; + ret = mdm_dt_parse_gpios(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "parsing gpio done\n"); + ret = mdm_pon_dt_init(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "pon dt init done\n"); + ret = mdm_pinctrl_init(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "pinctrl init done\n"); + ret = mdm_pon_setup(mdm); + if (ret) + return ret; + dev_dbg(mdm->dev, "pon setup done\n"); + ret = mdm_configure_ipc(mdm, pdev); + if (ret) + return ret; + dev_dbg(mdm->dev, "ipc configure done\n"); + esoc->name = APQ8096_LABEL; + esoc->link_name = APQ8096_PCIE; + esoc->clink_ops = clink_ops; + esoc->parent = mdm->dev; + esoc->owner = THIS_MODULE; + esoc->np = pdev->dev.of_node; + esoc->auto_boot = of_property_read_bool(esoc->np, + "qcom,mdm-auto-boot"); + esoc->primary = of_property_read_bool(esoc->np, + "qcom,mdm-primary"); + set_esoc_clink_data(esoc, mdm); + ret = esoc_clink_register(esoc); + if (ret) { + dev_err(mdm->dev, "esoc registration failed\n"); + return ret; + } + dev_dbg(mdm->dev, "esoc registration done\n"); + init_completion(&mdm->debug_done); + INIT_WORK(&mdm->mdm_status_work, mdm_status_fn); + INIT_WORK(&mdm->restart_reason_work, mdm_get_restart_reason); + INIT_DELAYED_WORK(&mdm->mdm2ap_status_check_work, mdm2ap_status_check); + mdm->get_restart_reason = false; + mdm->debug_fail = false; + mdm->esoc = esoc; + mdm->init = 0; + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1); + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 0); + return 0; +} + static struct esoc_clink_ops mdm_cops = { .cmd_exe = mdm_cmd_exe, .get_status = mdm_get_status, + .get_err_fatal = mdm_get_err_fatal, .notify = mdm_notify, }; @@ -981,6 +1203,18 @@ static struct mdm_ops mdm9x35_ops = { .pon_ops = &mdm9x35_pon_ops, }; +static struct mdm_ops mdm9x45_ops = { + .clink_ops = &mdm_cops, + .config_hw = mdm9x45_setup_hw, + .pon_ops = &mdm9x45_pon_ops, +}; + +static struct mdm_ops apq8096_ops = { + .clink_ops = &mdm_cops, + .config_hw = apq8096_setup_hw, + .pon_ops = &apq8096_pon_ops, +}; + static struct mdm_ops mdm9x55_ops = { .clink_ops = &mdm_cops, .config_hw = mdm9x55_setup_hw, @@ -992,8 +1226,12 @@ static const struct of_device_id mdm_dt_match[] = { .data = &mdm9x25_ops, }, { .compatible = "qcom,ext-mdm9x35", .data = &mdm9x35_ops, }, + { .compatible = "qcom,ext-mdm9x45", + .data = &mdm9x45_ops, }, { .compatible = "qcom,ext-mdm9x55", .data = &mdm9x55_ops, }, + { .compatible = "qcom,ext-apq8096", + .data = &apq8096_ops, }, {}, }; MODULE_DEVICE_TABLE(of, mdm_dt_match); diff --git a/drivers/esoc/esoc-mdm-drv.c b/drivers/esoc/esoc-mdm-drv.c index 8697428eceb26b05c9280139b042d10b3a8516c0..9c2c68dfef65d54866e07667511d3e1de37a1aaf 100644 --- a/drivers/esoc/esoc-mdm-drv.c +++ b/drivers/esoc/esoc-mdm-drv.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "esoc.h" #include "mdm-dbg.h" @@ -72,7 +73,14 @@ static void mdm_handle_clink_evt(enum esoc_evt evt, break; case ESOC_UNEXPECTED_RESET: case ESOC_ERR_FATAL: - if (mdm_drv->mode == CRASH) + /* + * Modem can crash while we are waiting for boot_done during + * a subsystem_get(). Setting mode to CRASH will prevent a + * subsequent subsystem_get() from entering poweron ops. Avoid + * this by seting mode to CRASH only if device was up and + * running. + */ + if (mdm_drv->mode == CRASH || mdm_drv->mode != RUN) return; mdm_drv->mode = CRASH; queue_work(mdm_drv->mdm_queue, &mdm_drv->ssr_work); @@ -161,8 +169,9 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys) subsys); struct mdm_drv *mdm_drv = esoc_get_drv_data(esoc_clink); const struct esoc_clink_ops const *clink_ops = esoc_clink->clink_ops; + int timeout = INT_MAX; - if (!esoc_req_eng_enabled(esoc_clink)) { + if (!esoc_clink->auto_boot && !esoc_req_eng_enabled(esoc_clink)) { dev_dbg(&esoc_clink->dev, "Wait for req eng registration\n"); wait_for_completion(&mdm_drv->req_eng_wait); } @@ -187,8 +196,17 @@ static int mdm_subsys_powerup(const struct subsys_desc *crashed_subsys) return ret; } } - wait_for_completion(&mdm_drv->boot_done); - if (mdm_drv->boot_fail) { + + /* + * In autoboot case, it is possible that we can forever wait for + * boot completion, when esoc fails to boot. This is because there + * is no helper application which can alert esoc driver about boot + * failure. Prevent going to wait forever in such case. + */ + if (esoc_clink->auto_boot) + timeout = 10 * HZ; + ret = wait_for_completion_timeout(&mdm_drv->boot_done, timeout); + if (mdm_drv->boot_fail || ret <= 0) { dev_err(&esoc_clink->dev, "booting failed\n"); return -EIO; } @@ -216,10 +234,12 @@ static int mdm_subsys_ramdumps(int want_dumps, static int mdm_register_ssr(struct esoc_clink *esoc_clink) { - esoc_clink->subsys.shutdown = mdm_subsys_shutdown; - esoc_clink->subsys.ramdump = mdm_subsys_ramdumps; - esoc_clink->subsys.powerup = mdm_subsys_powerup; - esoc_clink->subsys.crash_shutdown = mdm_crash_shutdown; + struct subsys_desc *subsys = &esoc_clink->subsys; + + subsys->shutdown = mdm_subsys_shutdown; + subsys->ramdump = mdm_subsys_ramdumps; + subsys->powerup = mdm_subsys_powerup; + subsys->crash_shutdown = mdm_crash_shutdown; return esoc_clink_register_ssr(esoc_clink); } @@ -286,6 +306,14 @@ static struct esoc_compat compat_table[] = { .name = "MDM9x55", .data = NULL, }, + { + .name = "MDM9x45", + .data = NULL, + }, + { + .name = "APQ8096", + .data = NULL, + }, }; static struct esoc_drv esoc_ssr_drv = { diff --git a/drivers/esoc/esoc-mdm-pon.c b/drivers/esoc/esoc-mdm-pon.c index acda0648536407b73d8da86f800263fd657a3bca..4ae3b7520f777656b6dd8d78648efba91b1e9526 100644 --- a/drivers/esoc/esoc-mdm-pon.c +++ b/drivers/esoc/esoc-mdm-pon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,6 +60,29 @@ static int mdm9x55_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic) return 0; } +/* This function can be called from atomic context. */ +static int mdm9x45_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic) +{ + int soft_reset_direction_assert = 0, + soft_reset_direction_de_assert = 1; + + if (mdm->soft_reset_inverted) { + soft_reset_direction_assert = 1; + soft_reset_direction_de_assert = 0; + } + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET), + soft_reset_direction_assert); + /* + * Allow PS hold assert to be detected + */ + if (!atomic) + usleep_range(1000000, 1005000); + else + mdelay(1000); + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET), + soft_reset_direction_de_assert); + return 0; +} static int mdm4x_do_first_power_on(struct mdm_ctrl *mdm) { @@ -68,6 +91,9 @@ static int mdm4x_do_first_power_on(struct mdm_ctrl *mdm) struct device *dev = mdm->dev; dev_dbg(dev, "Powering on modem for the first time\n"); + if (mdm->esoc->auto_boot) + return 0; + mdm_toggle_soft_reset(mdm, false); /* Add a delay to allow PON sequence to complete*/ msleep(50); @@ -132,8 +158,31 @@ static int mdm9x55_power_down(struct mdm_ctrl *mdm) return 0; } +static int mdm9x45_power_down(struct mdm_ctrl *mdm) +{ + int soft_reset_direction_assert = 0, + soft_reset_direction_de_assert = 1; + + if (mdm->soft_reset_inverted) { + soft_reset_direction_assert = 1; + soft_reset_direction_de_assert = 0; + } + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET), + soft_reset_direction_assert); + /* + * Allow PS hold assert to be detected + */ + msleep(3003); + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET), + soft_reset_direction_de_assert); + return 0; +} + static void mdm4x_cold_reset(struct mdm_ctrl *mdm) { + if (!gpio_is_valid(MDM_GPIO(mdm, AP2MDM_SOFT_RESET))) + return; + dev_dbg(mdm->dev, "Triggering mdm cold reset"); gpio_direction_output(MDM_GPIO(mdm, AP2MDM_SOFT_RESET), !!mdm->soft_reset_inverted); @@ -152,6 +201,11 @@ static void mdm9x55_cold_reset(struct mdm_ctrl *mdm) !mdm->soft_reset_inverted); } +static int apq8096_pon_dt_init(struct mdm_ctrl *mdm) +{ + return 0; +} + static int mdm4x_pon_dt_init(struct mdm_ctrl *mdm) { int val; @@ -183,6 +237,21 @@ static int mdm4x_pon_setup(struct mdm_ctrl *mdm) return 0; } +/* This function can be called from atomic context. */ +static int apq8096_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic) +{ + return 0; +} + +static int apq8096_power_down(struct mdm_ctrl *mdm) +{ + return 0; +} + +static void apq8096_cold_reset(struct mdm_ctrl *mdm) +{ +} + struct mdm_pon_ops mdm9x25_pon_ops = { .pon = mdm4x_do_first_power_on, .soft_reset = mdm4x_toggle_soft_reset, @@ -203,8 +272,8 @@ struct mdm_pon_ops mdm9x35_pon_ops = { struct mdm_pon_ops mdm9x45_pon_ops = { .pon = mdm4x_do_first_power_on, - .soft_reset = mdm4x_toggle_soft_reset, - .poff_force = mdm4x_power_down, + .soft_reset = mdm9x45_toggle_soft_reset, + .poff_force = mdm9x45_power_down, .cold_reset = mdm4x_cold_reset, .dt_init = mdm4x_pon_dt_init, .setup = mdm4x_pon_setup, @@ -218,3 +287,12 @@ struct mdm_pon_ops mdm9x55_pon_ops = { .dt_init = mdm4x_pon_dt_init, .setup = mdm4x_pon_setup, }; + +struct mdm_pon_ops apq8096_pon_ops = { + .pon = mdm4x_do_first_power_on, + .soft_reset = apq8096_toggle_soft_reset, + .poff_force = apq8096_power_down, + .cold_reset = apq8096_cold_reset, + .dt_init = apq8096_pon_dt_init, + .setup = mdm4x_pon_setup, +}; diff --git a/drivers/esoc/esoc-mdm.h b/drivers/esoc/esoc-mdm.h index ac811720b035a05524fb7f3feaca08e22b514a97..9343e49559f245b2bf01f61251d8163d385f3f93 100644 --- a/drivers/esoc/esoc-mdm.h +++ b/drivers/esoc/esoc-mdm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,8 @@ #define MDM9x45_PCIE "PCIe" #define MDM9x55_LABEL "MDM9x55" #define MDM9x55_PCIE "PCIe" +#define APQ8096_LABEL "APQ8096" +#define APQ8096_PCIE "PCIe" #define MDM2AP_STATUS_TIMEOUT_MS 120000L #define MDM_MODEM_TIMEOUT 3000 #define DEF_RAMDUMP_TIMEOUT 120000 @@ -153,4 +155,5 @@ extern struct mdm_pon_ops mdm9x25_pon_ops; extern struct mdm_pon_ops mdm9x35_pon_ops; extern struct mdm_pon_ops mdm9x45_pon_ops; extern struct mdm_pon_ops mdm9x55_pon_ops; +extern struct mdm_pon_ops apq8096_pon_ops; #endif diff --git a/drivers/esoc/esoc.h b/drivers/esoc/esoc.h index 755fb24bd60afe4336e415274d10ceeaa8b4d2b2..ee54908ce486705036bbf5f89591277739e4c5f8 100644 --- a/drivers/esoc/esoc.h +++ b/drivers/esoc/esoc.h @@ -49,6 +49,7 @@ struct esoc_eng { * @link_info: additional info about the physical link. * @parent: parent device. * @dev: device for userspace interface. + * @pdev: platform device to interface with SSR driver. * @id: id of the external device. * @owner: owner of the device. * @clink_ops: control operations for the control link @@ -59,6 +60,12 @@ struct esoc_eng { * @subsys_desc: descriptor for subsystem restart * @subsys_dev: ssr device handle. * @np: device tree node for esoc_clink. + * @auto_boot: boots independently. + * @primary: primary esoc controls(reset/poweroff) all secondary + * esocs, but not otherway around. + * @statusline_not_a_powersource: True if status line to esoc is not a + * power source. + * @userspace_handle_shutdown: True if user space handles shutdown requests. */ struct esoc_clink { const char *name; @@ -66,6 +73,7 @@ struct esoc_clink { const char *link_info; struct device *parent; struct device dev; + struct platform_device *pdev; unsigned int id; struct module *owner; const struct esoc_clink_ops const *clink_ops; @@ -77,17 +85,23 @@ struct esoc_clink { struct subsys_desc subsys; struct subsys_device *subsys_dev; struct device_node *np; + bool auto_boot; + bool primary; + bool statusline_not_a_powersource; + bool userspace_handle_shutdown; }; /** * struct esoc_clink_ops: Operations to control external soc * @cmd_exe: Execute control command * @get_status: Get current status, or response to previous command + * @get_err_fatal: Get status of err fatal signal * @notify_esoc: notify external soc of events */ struct esoc_clink_ops { int (*cmd_exe)(enum esoc_cmd cmd, struct esoc_clink *dev); - int (*get_status)(u32 *status, struct esoc_clink *dev); + void (*get_status)(u32 *status, struct esoc_clink *dev); + void (*get_err_fatal)(u32 *status, struct esoc_clink *dev); void (*notify)(enum esoc_notify notify, struct esoc_clink *dev); }; diff --git a/drivers/esoc/esoc_bus.c b/drivers/esoc/esoc_bus.c index f925607511ba4b8119a474b148b8b8072a41f051..94f52764c8c34ef1e0cac39bf2b7bb86a2057aa1 100644 --- a/drivers/esoc/esoc_bus.c +++ b/drivers/esoc/esoc_bus.c @@ -189,7 +189,7 @@ int esoc_clink_register_ssr(struct esoc_clink *esoc_clink) snprintf(subsys_name, len, "esoc%d", esoc_clink->id); esoc_clink->subsys.name = subsys_name; esoc_clink->dev.of_node = esoc_clink->np; - esoc_clink->subsys.dev = &esoc_clink->dev; + esoc_clink->subsys.dev = &esoc_clink->pdev->dev; esoc_clink->subsys_dev = subsys_register(&esoc_clink->subsys); if (IS_ERR_OR_NULL(esoc_clink->subsys_dev)) { dev_err(&esoc_clink->dev, "failed to register ssr node\n"); diff --git a/drivers/esoc/esoc_dev.c b/drivers/esoc/esoc_dev.c index ffb2237da5faaba20c0a7cd661f69c13d3608ca5..a1e7a52a8c2657577f149b8c019583e603a7ab79 100644 --- a/drivers/esoc/esoc_dev.c +++ b/drivers/esoc/esoc_dev.c @@ -224,9 +224,11 @@ static long esoc_dev_ioctl(struct file *file, unsigned int cmd, clink_ops->notify(esoc_cmd, esoc_clink); break; case ESOC_GET_STATUS: - err = clink_ops->get_status(&status, esoc_clink); - if (err) - return err; + clink_ops->get_status(&status, esoc_clink); + put_user(status, (unsigned int __user *)uarg); + break; + case ESOC_GET_ERR_FATAL: + clink_ops->get_err_fatal(&status, esoc_clink); put_user(status, (unsigned int __user *)uarg); break; case ESOC_WAIT_FOR_CRASH: @@ -338,7 +340,6 @@ int esoc_clink_del_device(struct device *dev, void *dummy) esoc_udev = esoc_udev_get_by_minor(esoc_clink->id); if (!esoc_udev) return 0; - return_esoc_udev(esoc_udev); device_destroy(esoc_class, MKDEV(esoc_major, esoc_clink->id)); return_esoc_udev(esoc_udev); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 7c42ff6700809e5783eb92d2de5c678c1e5c6681..a0924330d125da92de1b0e34e65c6485a1cc8789 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -25,6 +25,7 @@ * Alex Deucher * Jerome Glisse */ +#include #include #include #include diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 7e9154c7f1dbbb7f9d3eee6791c0e4fcc835ea8d..d1c9525d81eb7b87f9e3aec8d016059424081a33 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -2258,7 +2258,7 @@ static void kv_apply_state_adjust_rules(struct amdgpu_device *adev, if (pi->caps_stable_p_state) { stable_p_state_sclk = (max_limits->sclk * 75) / 100; - for (i = table->count - 1; i >= 0; i++) { + for (i = table->count - 1; i >= 0; i--) { if (stable_p_state_sclk >= table->entries[i].clk) { stable_p_state_sclk = table->entries[i].clk; break; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fb9f647bb5cd6fde9454ae9de9395bdc94b06b10..5044f2257e89f5fa10672e432753cb402e74ce70 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1159,7 +1159,7 @@ struct intel_gen6_power_mgmt { struct intel_rps_client semaphores, mmioflips; /* manual wa residency calculations */ - struct intel_rps_ei up_ei, down_ei; + struct intel_rps_ei ei; /* * Protects RPS/RC6 register access and PCU communication. diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0f42a2782afc31aabc2ed6d333fba457caa69705..b7b0a38acd67f7925c6734c215daab68a2c13c53 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -994,68 +994,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); } -static bool vlv_c0_above(struct drm_i915_private *dev_priv, - const struct intel_rps_ei *old, - const struct intel_rps_ei *now, - int threshold) -{ - u64 time, c0; - unsigned int mul = 100; - - if (old->cz_clock == 0) - return false; - - if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) - mul <<= 8; - - time = now->cz_clock - old->cz_clock; - time *= threshold * dev_priv->czclk_freq; - - /* Workload can be split between render + media, e.g. SwapBuffers - * being blitted in X after being rendered in mesa. To account for - * this we need to combine both engines into our activity counter. - */ - c0 = now->render_c0 - old->render_c0; - c0 += now->media_c0 - old->media_c0; - c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC; - - return c0 >= time; -} - void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) { - vlv_c0_read(dev_priv, &dev_priv->rps.down_ei); - dev_priv->rps.up_ei = dev_priv->rps.down_ei; + memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); } static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) { + const struct intel_rps_ei *prev = &dev_priv->rps.ei; struct intel_rps_ei now; u32 events = 0; - if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0) + if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0) return 0; vlv_c0_read(dev_priv, &now); if (now.cz_clock == 0) return 0; - if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) { - if (!vlv_c0_above(dev_priv, - &dev_priv->rps.down_ei, &now, - dev_priv->rps.down_threshold)) - events |= GEN6_PM_RP_DOWN_THRESHOLD; - dev_priv->rps.down_ei = now; - } + if (prev->cz_clock) { + u64 time, c0; + unsigned int mul; - if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { - if (vlv_c0_above(dev_priv, - &dev_priv->rps.up_ei, &now, - dev_priv->rps.up_threshold)) - events |= GEN6_PM_RP_UP_THRESHOLD; - dev_priv->rps.up_ei = now; + mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */ + if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) + mul <<= 8; + + time = now.cz_clock - prev->cz_clock; + time *= dev_priv->czclk_freq; + + /* Workload can be split between render + media, + * e.g. SwapBuffers being blitted in X after being rendered in + * mesa. To account for this we need to combine both engines + * into our activity counter. + */ + c0 = now.render_c0 - prev->render_c0; + c0 += now.media_c0 - prev->media_c0; + c0 *= mul; + + if (c0 > time * dev_priv->rps.up_threshold) + events = GEN6_PM_RP_UP_THRESHOLD; + else if (c0 < time * dev_priv->rps.down_threshold) + events = GEN6_PM_RP_DOWN_THRESHOLD; } + dev_priv->rps.ei = now; return events; } @@ -4390,7 +4373,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) /* Let's track the enabled rps events */ if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) /* WaGsvRC0ResidencyMethod:vlv */ - dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; + dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; else dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e7c18519274a7a59e2d037c82ef85ca6aeac66cd..fd4690ed93c011709457c270c26a4b2f529eddfd 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4376,6 +4376,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) break; } + /* When byt can survive without system hang with dynamic + * sw freq adjustments, this restriction can be lifted. + */ + if (IS_VALLEYVIEW(dev_priv)) + goto skip_hw_write; + I915_WRITE(GEN6_RP_UP_EI, GT_INTERVAL_FROM_US(dev_priv, ei_up)); I915_WRITE(GEN6_RP_UP_THRESHOLD, @@ -4394,6 +4400,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG); +skip_hw_write: dev_priv->rps.power = new_power; dev_priv->rps.up_threshold = threshold_up; dev_priv->rps.down_threshold = threshold_down; @@ -4404,8 +4411,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) { u32 mask = 0; + /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ if (val > dev_priv->rps.min_freq_softlimit) - mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; + mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; if (val < dev_priv->rps.max_freq_softlimit) mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; @@ -4509,7 +4517,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) { mutex_lock(&dev_priv->rps.hw_lock); if (dev_priv->rps.enabled) { - if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) + if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) gen6_rps_reset_ei(dev_priv); I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 3d0617dbc5146da0eff5c58d52529889fcf7200a..f3a8a8416c7ad938f900c0651a7ed639d7227e27 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -49,6 +49,7 @@ msm_drm-y := \ sde/sde_vbif.o \ sde_dbg_evtlog.o \ sde_io_util.o \ + dba_bridge.o \ sde_edid_parser.o # use drm gpu driver only if qcom_kgsl driver not available diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index c4f886fd603730f04609fb01e5485c173d1d97c2..a417e42944fce761c7f4fae4e31c716da8ccfd42 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -466,6 +466,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct msm_gpu_config a3xx_config = { 0 }; int ret; if (!pdev) { @@ -491,7 +492,13 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a3xx_registers; adreno_gpu->reg_offsets = a3xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + a3xx_config.ioname = MSM_GPU_DEFAULT_IONAME; + a3xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME; + a3xx_config.nr_rings = 1; + a3xx_config.va_start = 0x300000; + a3xx_config.va_end = 0xffffffff; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a3xx_config); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 534a7c3fbdca0c0ef383cb833e5586d1693a664b..069823f054f7979aefe1ed670d555a74b84cc2c0 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -543,6 +543,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct msm_gpu_config a4xx_config = { 0 }; int ret; if (!pdev) { @@ -568,7 +569,13 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a4xx_registers; adreno_gpu->reg_offsets = a4xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + a4xx_config.ioname = MSM_GPU_DEFAULT_IONAME; + a4xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME; + a4xx_config.nr_rings = 1; + a4xx_config.va_start = 0x300000; + a4xx_config.va_end = 0xffffffff; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a4xx_config); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 32b2c7fab8396701d413bad142412b69f8fede8b..ac6c47bd33aec886991d6cd417339c7499583a49 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -15,6 +15,9 @@ #include "msm_iommu.h" #include "a5xx_gpu.h" +#define SECURE_VA_START 0xc0000000 +#define SECURE_VA_SIZE SZ_256M + static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -100,7 +103,7 @@ static void a5xx_set_pagetable(struct msm_gpu *gpu, struct msm_ringbuffer *ring, OUT_RING(ring, 1); } -static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) +static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); @@ -133,10 +136,36 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_PKT7(ring, CP_YIELD_ENABLE, 1); OUT_RING(ring, 0x02); + /* Turn on secure mode if the submission is secure */ + if (submit->secure) { + OUT_PKT7(ring, CP_SET_SECURE_MODE, 1); + OUT_RING(ring, 1); + } + + /* Record the always on counter before command execution */ + if (submit->profile_buf_iova) { + uint64_t gpuaddr = submit->profile_buf_iova + + offsetof(struct drm_msm_gem_submit_profile_buffer, + ticks_submitted); + + /* + * Set bit[30] to make this command a 64 bit write operation. + * bits[18-29] is to specify number of consecutive registers + * to copy, so set this space with 2, since we want to copy + * data from REG_A5XX_RBBM_ALWAYSON_COUNTER_LO and [HI]. + */ + OUT_PKT7(ring, CP_REG_TO_MEM, 3); + OUT_RING(ring, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO | + (1 << 30) | (2 << 18)); + OUT_RING(ring, lower_32_bits(gpuaddr)); + OUT_RING(ring, upper_32_bits(gpuaddr)); + } + /* Submit the commands */ for (i = 0; i < submit->nr_cmds; i++) { switch (submit->cmd[i].type) { case MSM_SUBMIT_CMD_IB_TARGET_BUF: + case MSM_SUBMIT_CMD_PROFILE_BUF: break; case MSM_SUBMIT_CMD_BUF: OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3); @@ -164,6 +193,19 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_PKT7(ring, CP_YIELD_ENABLE, 1); OUT_RING(ring, 0x01); + /* Record the always on counter after command execution */ + if (submit->profile_buf_iova) { + uint64_t gpuaddr = submit->profile_buf_iova + + offsetof(struct drm_msm_gem_submit_profile_buffer, + ticks_retired); + + OUT_PKT7(ring, CP_REG_TO_MEM, 3); + OUT_RING(ring, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO | + (1 << 30) | (2 << 18)); + OUT_RING(ring, lower_32_bits(gpuaddr)); + OUT_RING(ring, upper_32_bits(gpuaddr)); + } + /* Write the fence to the scratch register */ OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1); OUT_RING(ring, submit->fence); @@ -179,6 +221,11 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, ring->id, fence))); OUT_RING(ring, submit->fence); + if (submit->secure) { + OUT_PKT7(ring, CP_SET_SECURE_MODE, 1); + OUT_RING(ring, 0); + } + /* Yield the floor on command completion */ OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4); /* @@ -193,12 +240,39 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) /* Set bit 0 to trigger an interrupt on preempt complete */ OUT_RING(ring, 0x01); + if (submit->profile_buf_iova) { + unsigned long flags; + uint64_t ktime; + struct drm_msm_gem_submit_profile_buffer *profile_buf = + submit->profile_buf_vaddr; + + /* + * With this profiling, we are trying to create closest + * possible mapping between the CPU time domain(monotonic clock) + * and the GPU time domain(ticks). In order to make this + * happen, we need to briefly turn off interrupts to make sure + * interrupts do not run between collecting these two samples. + */ + local_irq_save(flags); + + profile_buf->ticks_queued = gpu_read64(gpu, + REG_A5XX_RBBM_ALWAYSON_COUNTER_LO, + REG_A5XX_RBBM_ALWAYSON_COUNTER_HI); + + ktime = ktime_get_raw_ns(); + + local_irq_restore(flags); + + do_div(ktime, NSEC_PER_SEC); + + profile_buf->queue_time = ktime; + profile_buf->submit_time = ktime; + } + a5xx_flush(gpu, ring); /* Check to see if we need to start preemption */ a5xx_preempt_trigger(gpu); - - return 0; } static const struct { @@ -700,14 +774,10 @@ static int a5xx_hw_init(struct msm_gpu *gpu) ADRENO_PROTECT_RW(0x10000, 0x8000)); gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0); - /* - * Disable the trusted memory range - we don't actually supported secure - * memory rendering at this point in time and we don't want to block off - * part of the virtual memory space. - */ + gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO, - REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000); - gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000); + REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, SECURE_VA_START); + gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, SECURE_VA_SIZE); /* Put the GPU into 64 bit by default */ gpu_write(gpu, REG_A5XX_CP_ADDR_MODE_CNTL, 0x1); @@ -1101,7 +1171,7 @@ static const u32 a5xx_registers[] = { 0xe9c0, 0xe9c7, 0xe9d0, 0xe9d1, 0xea00, 0xea01, 0xea10, 0xea1c, 0xea40, 0xea68, 0xea80, 0xea80, 0xea82, 0xeaa3, 0xeaa5, 0xeac2, 0xeb80, 0xeb8f, 0xebb0, 0xebb0, 0xec00, 0xec05, 0xec08, 0xece9, - 0xecf0, 0xecf0, 0xf400, 0xf400, 0xf800, 0xf807, + 0xecf0, 0xecf0, 0xf800, 0xf807, ~0 }; @@ -1306,6 +1376,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; + struct msm_gpu_config a5xx_config = { 0 }; int ret; if (!pdev) { @@ -1329,7 +1400,23 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) /* Check the efuses for some configuration */ a5xx_efuses_read(pdev, adreno_gpu); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); + a5xx_config.ioname = MSM_GPU_DEFAULT_IONAME; + a5xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME; + + /* Set the number of rings to 4 - yay preemption */ + a5xx_config.nr_rings = 4; + + /* + * Set the user domain range to fall into the TTBR1 region for global + * objects + */ + a5xx_config.va_start = 0x800000000; + a5xx_config.va_end = 0x8ffffffff; + + a5xx_config.secure_va_start = SECURE_VA_START; + a5xx_config.secure_va_end = SECURE_VA_START + SECURE_VA_SIZE - 1; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a5xx_config); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_snapshot.c b/drivers/gpu/drm/msm/adreno/a5xx_snapshot.c index 5a2edb0ea518b942179eb1e9ffe2eaa0afa76bcb..690e6f546e60e2b13b6326ff10878957ec5d4c86 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_snapshot.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_snapshot.c @@ -733,6 +733,35 @@ static void a5xx_snapshot_indexed_registers(struct msm_gpu *gpu, } } +static void a5xx_snapshot_preemption(struct msm_gpu *gpu, struct msm_snapshot + *snapshot) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct msm_snapshot_gpu_object header = { + .type = SNAPSHOT_GPU_OBJECT_GLOBAL, + .size = A5XX_PREEMPT_RECORD_SIZE >> 2, + .pt_base = 0, + }; + int index; + + if (gpu->nr_rings <= 1) + return; + + for (index = 0; index < gpu->nr_rings; index++) { + + header.gpuaddr = a5xx_gpu->preempt_iova[index]; + + if (!SNAPSHOT_HEADER(snapshot, header, + SNAPSHOT_SECTION_GPU_OBJECT_V2, + A5XX_PREEMPT_RECORD_SIZE >> 2)) + return; + + SNAPSHOT_MEMCPY(snapshot, a5xx_gpu->preempt[index], + A5XX_PREEMPT_RECORD_SIZE); + } +} + int a5xx_snapshot(struct msm_gpu *gpu, struct msm_snapshot *snapshot) { struct crashdump crashdump = { 0 }; @@ -787,6 +816,9 @@ int a5xx_snapshot(struct msm_gpu *gpu, struct msm_snapshot *snapshot) /* CP MERCIU */ a5xx_snapshot_cp_merciu(gpu, snapshot); + /* Preemption records*/ + a5xx_snapshot_preemption(gpu, snapshot); + crashdump_destroy(gpu, &crashdump); snapshot->priv = NULL; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 969ed810ce9de2d25299c9f065c68660e90bd0a9..a66c7e80d2af3cbafe28a1f26f131e1f3da02c9b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -172,7 +172,7 @@ void adreno_recover(struct msm_gpu *gpu) enable_irq(gpu->irq); } -int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) +void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct msm_ringbuffer *ring = gpu->rb[submit->ring]; @@ -183,6 +183,7 @@ int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) case MSM_SUBMIT_CMD_IB_TARGET_BUF: /* ignore IB-targets */ break; + case MSM_SUBMIT_CMD_PROFILE_BUF: case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: break; case MSM_SUBMIT_CMD_BUF: @@ -247,8 +248,6 @@ int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) #endif gpu->funcs->flush(gpu, ring); - - return 0; } void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) @@ -404,10 +403,6 @@ void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords) ring->gpu->name, ring->id); } -static const char *iommu_ports[] = { - "gfx3d_user", -}; - /* Read the set of powerlevels */ static int _adreno_get_pwrlevels(struct msm_gpu *gpu, struct device_node *node) { @@ -523,10 +518,10 @@ static int adreno_of_parse(struct platform_device *pdev, struct msm_gpu *gpu) int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, - const struct adreno_gpu_funcs *funcs, int nr_rings) + const struct adreno_gpu_funcs *funcs, + struct msm_gpu_config *gpu_config) { struct adreno_platform_config *config = pdev->dev.platform_data; - struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; struct msm_mmu *mmu; int ret; @@ -540,26 +535,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, /* Get the rest of the target configuration from the device tree */ adreno_of_parse(pdev, gpu); - adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; - adreno_gpu_config.irqname = "kgsl_3d0_irq"; - adreno_gpu_config.nr_rings = nr_rings; - - adreno_gpu_config.va_start = SZ_16M; - adreno_gpu_config.va_end = 0xffffffff; - - if (adreno_gpu->revn >= 500) { - /* 5XX targets use a 64 bit region */ - adreno_gpu_config.va_start = 0x800000000; - adreno_gpu_config.va_end = 0x8ffffffff; - } else { - adreno_gpu_config.va_start = 0x300000; - adreno_gpu_config.va_end = 0xffffffff; - } - - adreno_gpu_config.nr_rings = nr_rings; - ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, - adreno_gpu->info->name, &adreno_gpu_config); + adreno_gpu->info->name, gpu_config); if (ret) return ret; @@ -579,12 +556,20 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, mmu = gpu->aspace->mmu; if (mmu) { - ret = mmu->funcs->attach(mmu, iommu_ports, - ARRAY_SIZE(iommu_ports)); + ret = mmu->funcs->attach(mmu, NULL, 0); if (ret) return ret; } + if (gpu->secure_aspace) { + mmu = gpu->secure_aspace->mmu; + if (mmu) { + ret = mmu->funcs->attach(mmu, NULL, 0); + if (ret) + return ret; + } + } + mutex_lock(&drm->struct_mutex); adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED); @@ -630,6 +615,12 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) aspace->mmu->funcs->detach(aspace->mmu); msm_gem_address_space_put(aspace); } + + if (gpu->base.secure_aspace) { + aspace = gpu->base.secure_aspace; + aspace->mmu->funcs->detach(aspace->mmu); + msm_gem_address_space_put(aspace); + } } static void adreno_snapshot_os(struct msm_gpu *gpu, @@ -721,7 +712,7 @@ static struct adreno_counter_group *get_counter_group(struct msm_gpu *gpu, return ERR_PTR(-ENODEV); if (groupid >= adreno_gpu->nr_counter_groups) - return ERR_PTR(-EINVAL); + return ERR_PTR(-ENODEV); return (struct adreno_counter_group *) adreno_gpu->counter_groups[groupid]; @@ -744,7 +735,7 @@ u64 adreno_read_counter(struct msm_gpu *gpu, u32 groupid, int counterid) struct adreno_counter_group *group = get_counter_group(gpu, groupid); - if (!IS_ERR(group) && group->funcs.read) + if (!IS_ERR_OR_NULL(group) && group->funcs.read) return group->funcs.read(gpu, group, counterid); return 0; @@ -755,6 +746,6 @@ void adreno_put_counter(struct msm_gpu *gpu, u32 groupid, int counterid) struct adreno_counter_group *group = get_counter_group(gpu, groupid); - if (!IS_ERR(group) && group->funcs.put) + if (!IS_ERR_OR_NULL(group) && group->funcs.put) group->funcs.put(gpu, group, counterid); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 8e8f3e5182d6fd2a440b585fb5f0e363263615cd..9e622fa06ce4c615207be4027b445c55d83a25c7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -244,7 +244,7 @@ uint32_t adreno_last_fence(struct msm_gpu *gpu, struct msm_ringbuffer *ring); uint32_t adreno_submitted_fence(struct msm_gpu *gpu, struct msm_ringbuffer *ring); void adreno_recover(struct msm_gpu *gpu); -int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit); +void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit); void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring); bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring); #ifdef CONFIG_DEBUG_FS @@ -257,7 +257,7 @@ struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu); int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs, - int nr_rings); + struct msm_gpu_config *config); void adreno_gpu_cleanup(struct adreno_gpu *gpu); void adreno_snapshot(struct msm_gpu *gpu, struct msm_snapshot *snapshot); diff --git a/drivers/gpu/drm/msm/dba_bridge.c b/drivers/gpu/drm/msm/dba_bridge.c new file mode 100644 index 0000000000000000000000000000000000000000..f933a7f3dcfb420ed8e0697bac0f80b1b06eb4ca --- /dev/null +++ b/drivers/gpu/drm/msm/dba_bridge.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include