We want the tty/serial fixes in here as well.
Unified · Split
| @@ -22,6 +22,8 @@ Optional Properties: · 21 unmodified lines | ||
| 22 | 22 | - pclkN, clkN: Pairs of parent of input clock and input clock to the |
| 23 | 23 | devices in this power domain. Maximum of 4 pairs (N = 0 to 3) |
| 24 | 24 | are supported currently. |
| 25 | +- power-domains: phandle pointing to the parent power domain, for more details | |
| 26 | + see Documentation/devicetree/bindings/power/power_domain.txt | |
| 25 | 27 | |
| 26 | 28 | Node of a device using power domains must have a power-domains property |
| 27 | 29 | defined with a phandle to respective power domain. |
| @@ -13,6 +13,10 @@ Boards with the ST STiH407 SoC shall have the following properties: · 12 unmodified lines | ||
| 13 | 13 | Required root node property: |
| 14 | 14 | compatible = "st,stih407"; |
| 15 | 15 | |
| 16 | +Boards with the ST STiH410 SoC shall have the following properties: | |
| 17 | +Required root node property: | |
| 18 | +compatible = "st,stih410"; | |
| 19 | + | |
| 16 | 20 | Boards with the ST STiH418 SoC shall have the following properties: |
| 17 | 21 | Required root node property: |
| 18 | 22 | compatible = "st,stih418"; |
| @@ -4,7 +4,10 @@ Ethernet nodes are defined to describe on-chip ethernet interfaces in · 3 unmodified lines | ||
| 4 | 4 | APM X-Gene SoC. |
| 5 | 5 | |
| 6 | 6 | Required properties for all the ethernet interfaces: |
| 7 | −- compatible: Should be "apm,xgene-enet" | |
| 7 | +- compatible: Should state binding information from the following list, | |
| 8 | + - "apm,xgene-enet": RGMII based 1G interface | |
| 9 | + - "apm,xgene1-sgenet": SGMII based 1G interface | |
| 10 | + - "apm,xgene1-xgenet": XFI based 10G interface | |
| 8 | 11 | - reg: Address and length of the register set for the device. It contains the |
| 9 | 12 | information of registers in the same order as described by reg-names |
| 10 | 13 | - reg-names: Should contain the register set names |
| @@ -19,6 +19,16 @@ Required properties: · 18 unmodified lines | ||
| 19 | 19 | providing multiple PM domains (e.g. power controllers), but can be any value |
| 20 | 20 | as specified by device tree binding documentation of particular provider. |
| 21 | 21 | |
| 22 | +Optional properties: | |
| 23 | + - power-domains : A phandle and PM domain specifier as defined by bindings of | |
| 24 | + the power controller specified by phandle. | |
| 25 | + Some power domains might be powered from another power domain (or have | |
| 26 | + other hardware specific dependencies). For representing such dependency | |
| 27 | + a standard PM domain consumer binding is used. When provided, all domains | |
| 28 | + created by the given provider should be subdomains of the domain | |
| 29 | + specified by this binding. More details about power domain specifier are | |
| 30 | + available in the next section. | |
| 31 | + | |
| 22 | 32 | Example: |
| 23 | 33 | |
| 24 | 34 | power: power-controller@12340000 { |
| @@ -30,6 +40,25 @@ Example: · 5 unmodified lines | ||
| 30 | 40 | The node above defines a power controller that is a PM domain provider and |
| 31 | 41 | expects one cell as its phandle argument. |
| 32 | 42 | |
| 43 | +Example 2: | |
| 44 | + | |
| 45 | + parent: power-controller@12340000 { | |
| 46 | + compatible = "foo,power-controller"; | |
| 47 | + reg = <0x12340000 0x1000>; | |
| 48 | + #power-domain-cells = <1>; | |
| 49 | + }; | |
| 50 | + | |
| 51 | + child: power-controller@12340000 { | |
| 52 | + compatible = "foo,power-controller"; | |
| 53 | + reg = <0x12341000 0x1000>; | |
| 54 | + power-domains = <&parent 0>; | |
| 55 | + #power-domain-cells = <1>; | |
| 56 | + }; | |
| 57 | + | |
| 58 | +The nodes above define two power controllers: 'parent' and 'child'. | |
| 59 | +Domains created by the 'child' power controller are subdomains of '0' power | |
| 60 | +domain provided by the 'parent' power controller. | |
| 61 | + | |
| 33 | 62 | ==PM domain consumers== |
| 34 | 63 | |
| 35 | 64 | Required properties: |
File renamed without changes.
| @@ -0,0 +1,19 @@ | ||
| 1 | +ETRAX FS UART | |
| 2 | + | |
| 3 | +Required properties: | |
| 4 | +- compatible : "axis,etraxfs-uart" | |
| 5 | +- reg: offset and length of the register set for the device. | |
| 6 | +- interrupts: device interrupt | |
| 7 | + | |
| 8 | +Optional properties: | |
| 9 | +- {dtr,dsr,ri,cd}-gpios: specify a GPIO for DTR/DSR/RI/CD | |
| 10 | + line respectively. | |
| 11 | + | |
| 12 | +Example: | |
| 13 | + | |
| 14 | +serial@b00260000 { | |
| 15 | + compatible = "axis,etraxfs-uart"; | |
| 16 | + reg = <0xb0026000 0x1000>; | |
| 17 | + interrupts = <68>; | |
| 18 | + status = "disabled"; | |
| 19 | +}; | |
| @@ -12,6 +12,9 @@ I. For patch submitters · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | devicetree@vger.kernel.org |
| 14 | 14 | |
| 15 | + and Cc: the DT maintainers. Use scripts/get_maintainer.pl to identify | |
| 16 | + all of the DT maintainers. | |
| 17 | + | |
| 15 | 18 | 3) The Documentation/ portion of the patch should come in the series before |
| 16 | 19 | the code implementing the binding. |
| 17 | 20 | |
| @@ -20,6 +20,7 @@ amlogic Amlogic, Inc. · 19 unmodified lines | ||
| 20 | 20 | ams AMS AG |
| 21 | 21 | amstaos AMS-Taos Inc. |
| 22 | 22 | apm Applied Micro Circuits Corporation (APM) |
| 23 | +arasan Arasan Chip Systems | |
| 23 | 24 | arm ARM Ltd. |
| 24 | 25 | armadeus ARMadeus Systems SARL |
| 25 | 26 | asahi-kasei Asahi Kasei Corp. |
| @@ -27,6 +28,7 @@ atmel Atmel Corporation · 1 unmodified line | ||
| 27 | 28 | auo AU Optronics Corporation |
| 28 | 29 | avago Avago Technologies |
| 29 | 30 | avic Shanghai AVIC Optoelectronics Co., Ltd. |
| 31 | +axis Axis Communications AB | |
| 30 | 32 | bosch Bosch Sensortec GmbH |
| 31 | 33 | brcm Broadcom Corporation |
| 32 | 34 | buffalo Buffalo, Inc. |
| @@ -26,6 +26,11 @@ Optional properties: · 25 unmodified lines | ||
| 26 | 26 | - atmel,disable : Should be present if you want to disable the watchdog. |
| 27 | 27 | - atmel,idle-halt : Should be present if you want to stop the watchdog when |
| 28 | 28 | entering idle state. |
| 29 | + CAUTION: This property should be used with care, it actually makes the | |
| 30 | + watchdog not counting when the CPU is in idle state, therefore the | |
| 31 | + watchdog reset time depends on mean CPU usage and will not reset at all | |
| 32 | + if the CPU stop working while it is in idle state, which is probably | |
| 33 | + not what you want. | |
| 29 | 34 | - atmel,dbg-halt : Should be present if you want to stop the watchdog when |
| 30 | 35 | entering debug state. |
| 31 | 36 | |
| @@ -1030,6 +1030,16 @@ F: arch/arm/mach-mxs/ · 1029 unmodified lines | ||
| 1030 | 1030 | F: arch/arm/boot/dts/imx* |
| 1031 | 1031 | F: arch/arm/configs/imx*_defconfig |
| 1032 | 1032 | |
| 1033 | +ARM/FREESCALE VYBRID ARM ARCHITECTURE | |
| 1034 | +M: Shawn Guo <shawn.guo@linaro.org> | |
| 1035 | +M: Sascha Hauer <kernel@pengutronix.de> | |
| 1036 | +R: Stefan Agner <stefan@agner.ch> | |
| 1037 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 1038 | +S: Maintained | |
| 1039 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git | |
| 1040 | +F: arch/arm/mach-imx/*vf610* | |
| 1041 | +F: arch/arm/boot/dts/vf* | |
| 1042 | + | |
| 1033 | 1043 | ARM/GLOMATION GESBC9312SX MACHINE SUPPORT |
| 1034 | 1044 | M: Lennert Buytenhek <kernel@wantstofly.org> |
| 1035 | 1045 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1188,6 +1198,7 @@ ARM/Marvell Dove/MV78xx0/Orion SOC support · 152 unmodified lines | ||
| 1188 | 1198 | M: Jason Cooper <jason@lakedaemon.net> |
| 1189 | 1199 | M: Andrew Lunn <andrew@lunn.ch> |
| 1190 | 1200 | M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> |
| 1201 | +M: Gregory Clement <gregory.clement@free-electrons.com> | |
| 1191 | 1202 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1192 | 1203 | S: Maintained |
| 1193 | 1204 | F: arch/arm/mach-dove/ |
| @@ -1730,7 +1741,7 @@ S: Maintained · 536 unmodified lines | ||
| 1730 | 1741 | F: drivers/net/ethernet/atheros/ |
| 1731 | 1742 | |
| 1732 | 1743 | ATM |
| 1733 | −M: Chas Williams <chas@cmf.nrl.navy.mil> | |
| 1744 | +M: Chas Williams <3chas3@gmail.com> | |
| 1734 | 1745 | L: linux-atm-general@lists.sourceforge.net (moderated for non-subscribers) |
| 1735 | 1746 | L: netdev@vger.kernel.org |
| 1736 | 1747 | W: http://linux-atm.sourceforge.net |
| @@ -2107,7 +2118,6 @@ F: drivers/net/ethernet/broadcom/bnx2x/ · 370 unmodified lines | ||
| 2107 | 2118 | |
| 2108 | 2119 | BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE |
| 2109 | 2120 | M: Christian Daudt <bcm@fixthebug.org> |
| 2110 | −M: Matt Porter <mporter@linaro.org> | |
| 2111 | 2121 | M: Florian Fainelli <f.fainelli@gmail.com> |
| 2112 | 2122 | L: bcm-kernel-feedback-list@broadcom.com |
| 2113 | 2123 | T: git git://github.com/broadcom/mach-bcm |
| @@ -2369,8 +2379,9 @@ F: arch/x86/include/asm/tce.h · 255 unmodified lines | ||
| 2369 | 2379 | |
| 2370 | 2380 | CAN NETWORK LAYER |
| 2371 | 2381 | M: Oliver Hartkopp <socketcan@hartkopp.net> |
| 2382 | +M: Marc Kleine-Budde <mkl@pengutronix.de> | |
| 2372 | 2383 | L: linux-can@vger.kernel.org |
| 2373 | −W: http://gitorious.org/linux-can | |
| 2384 | +W: https://github.com/linux-can | |
| 2374 | 2385 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git |
| 2375 | 2386 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git |
| 2376 | 2387 | S: Maintained |
| @@ -2386,7 +2397,7 @@ CAN NETWORK DRIVERS · 9 unmodified lines | ||
| 2386 | 2397 | M: Wolfgang Grandegger <wg@grandegger.com> |
| 2387 | 2398 | M: Marc Kleine-Budde <mkl@pengutronix.de> |
| 2388 | 2399 | L: linux-can@vger.kernel.org |
| 2389 | −W: http://gitorious.org/linux-can | |
| 2400 | +W: https://github.com/linux-can | |
| 2390 | 2401 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git |
| 2391 | 2402 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git |
| 2392 | 2403 | S: Maintained |
| @@ -10196,6 +10207,13 @@ S: Maintained · 7803 unmodified lines | ||
| 10196 | 10207 | F: Documentation/usb/ohci.txt |
| 10197 | 10208 | F: drivers/usb/host/ohci* |
| 10198 | 10209 | |
| 10210 | +USB OTG FSM (Finite State Machine) | |
| 10211 | +M: Peter Chen <Peter.Chen@freescale.com> | |
| 10212 | +T: git git://github.com/hzpeterchen/linux-usb.git | |
| 10213 | +L: linux-usb@vger.kernel.org | |
| 10214 | +S: Maintained | |
| 10215 | +F: drivers/usb/common/usb-otg-fsm.c | |
| 10216 | + | |
| 10199 | 10217 | USB OVER IP DRIVER |
| 10200 | 10218 | M: Valentina Manea <valentina.manea.m@gmail.com> |
| 10201 | 10219 | M: Shuah Khan <shuah.kh@samsung.com> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 4 |
| 2 | 2 | PATCHLEVEL = 0 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc3 | |
| 4 | +EXTRAVERSION = -rc5 | |
| 5 | 5 | NAME = Hurr durr I'ma sheep |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -150,6 +150,7 @@ machine-$(CONFIG_ARCH_BERLIN) += berlin · 149 unmodified lines | ||
| 150 | 150 | machine-$(CONFIG_ARCH_CLPS711X) += clps711x |
| 151 | 151 | machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx |
| 152 | 152 | machine-$(CONFIG_ARCH_DAVINCI) += davinci |
| 153 | +machine-$(CONFIG_ARCH_DIGICOLOR) += digicolor | |
| 153 | 154 | machine-$(CONFIG_ARCH_DOVE) += dove |
| 154 | 155 | machine-$(CONFIG_ARCH_EBSA110) += ebsa110 |
| 155 | 156 | machine-$(CONFIG_ARCH_EFM32) += efm32 |
| @@ -301,3 +301,11 @@ · 300 unmodified lines | ||
| 301 | 301 | cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; |
| 302 | 302 | cd-inverted; |
| 303 | 303 | }; |
| 304 | + | |
| 305 | +&aes { | |
| 306 | + status = "okay"; | |
| 307 | +}; | |
| 308 | + | |
| 309 | +&sham { | |
| 310 | + status = "okay"; | |
| 311 | +}; | |
| @@ -24,11 +24,3 @@ · 23 unmodified lines | ||
| 24 | 24 | &mmc1 { |
| 25 | 25 | vmmc-supply = <&ldo3_reg>; |
| 26 | 26 | }; |
| 27 | − | |
| 28 | −&sham { | |
| 29 | − status = "okay"; | |
| 30 | −}; | |
| 31 | − | |
| 32 | −&aes { | |
| 33 | − status = "okay"; | |
| 34 | −}; | |
| @@ -328,6 +328,10 @@ · 327 unmodified lines | ||
| 328 | 328 | dual_emac_res_vlan = <3>; |
| 329 | 329 | }; |
| 330 | 330 | |
| 331 | +&phy_sel { | |
| 332 | + rmii-clock-ext; | |
| 333 | +}; | |
| 334 | + | |
| 331 | 335 | &mac { |
| 332 | 336 | pinctrl-names = "default", "sleep"; |
| 333 | 337 | pinctrl-0 = <&cpsw_default>; |
| @@ -99,7 +99,7 @@ · 98 unmodified lines | ||
| 99 | 99 | ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 { |
| 100 | 100 | #clock-cells = <0>; |
| 101 | 101 | compatible = "ti,gate-clock"; |
| 102 | − clocks = <&dpll_per_m2_ck>; | |
| 102 | + clocks = <&l4ls_gclk>; | |
| 103 | 103 | ti,bit-shift = <0>; |
| 104 | 104 | reg = <0x0664>; |
| 105 | 105 | }; |
| @@ -107,7 +107,7 @@ · 1 unmodified line | ||
| 107 | 107 | ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 { |
| 108 | 108 | #clock-cells = <0>; |
| 109 | 109 | compatible = "ti,gate-clock"; |
| 110 | − clocks = <&dpll_per_m2_ck>; | |
| 110 | + clocks = <&l4ls_gclk>; | |
| 111 | 111 | ti,bit-shift = <1>; |
| 112 | 112 | reg = <0x0664>; |
| 113 | 113 | }; |
| @@ -115,7 +115,7 @@ · 1 unmodified line | ||
| 115 | 115 | ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 { |
| 116 | 116 | #clock-cells = <0>; |
| 117 | 117 | compatible = "ti,gate-clock"; |
| 118 | − clocks = <&dpll_per_m2_ck>; | |
| 118 | + clocks = <&l4ls_gclk>; | |
| 119 | 119 | ti,bit-shift = <2>; |
| 120 | 120 | reg = <0x0664>; |
| 121 | 121 | }; |
| @@ -107,7 +107,7 @@ · 106 unmodified lines | ||
| 107 | 107 | ehrpwm0_tbclk: ehrpwm0_tbclk { |
| 108 | 108 | #clock-cells = <0>; |
| 109 | 109 | compatible = "ti,gate-clock"; |
| 110 | − clocks = <&dpll_per_m2_ck>; | |
| 110 | + clocks = <&l4ls_gclk>; | |
| 111 | 111 | ti,bit-shift = <0>; |
| 112 | 112 | reg = <0x0664>; |
| 113 | 113 | }; |
| @@ -115,7 +115,7 @@ · 1 unmodified line | ||
| 115 | 115 | ehrpwm1_tbclk: ehrpwm1_tbclk { |
| 116 | 116 | #clock-cells = <0>; |
| 117 | 117 | compatible = "ti,gate-clock"; |
| 118 | − clocks = <&dpll_per_m2_ck>; | |
| 118 | + clocks = <&l4ls_gclk>; | |
| 119 | 119 | ti,bit-shift = <1>; |
| 120 | 120 | reg = <0x0664>; |
| 121 | 121 | }; |
| @@ -123,7 +123,7 @@ · 1 unmodified line | ||
| 123 | 123 | ehrpwm2_tbclk: ehrpwm2_tbclk { |
| 124 | 124 | #clock-cells = <0>; |
| 125 | 125 | compatible = "ti,gate-clock"; |
| 126 | − clocks = <&dpll_per_m2_ck>; | |
| 126 | + clocks = <&l4ls_gclk>; | |
| 127 | 127 | ti,bit-shift = <2>; |
| 128 | 128 | reg = <0x0664>; |
| 129 | 129 | }; |
| @@ -131,7 +131,7 @@ · 1 unmodified line | ||
| 131 | 131 | ehrpwm3_tbclk: ehrpwm3_tbclk { |
| 132 | 132 | #clock-cells = <0>; |
| 133 | 133 | compatible = "ti,gate-clock"; |
| 134 | − clocks = <&dpll_per_m2_ck>; | |
| 134 | + clocks = <&l4ls_gclk>; | |
| 135 | 135 | ti,bit-shift = <4>; |
| 136 | 136 | reg = <0x0664>; |
| 137 | 137 | }; |
| @@ -139,7 +139,7 @@ · 1 unmodified line | ||
| 139 | 139 | ehrpwm4_tbclk: ehrpwm4_tbclk { |
| 140 | 140 | #clock-cells = <0>; |
| 141 | 141 | compatible = "ti,gate-clock"; |
| 142 | − clocks = <&dpll_per_m2_ck>; | |
| 142 | + clocks = <&l4ls_gclk>; | |
| 143 | 143 | ti,bit-shift = <5>; |
| 144 | 144 | reg = <0x0664>; |
| 145 | 145 | }; |
| @@ -147,7 +147,7 @@ · 1 unmodified line | ||
| 147 | 147 | ehrpwm5_tbclk: ehrpwm5_tbclk { |
| 148 | 148 | #clock-cells = <0>; |
| 149 | 149 | compatible = "ti,gate-clock"; |
| 150 | − clocks = <&dpll_per_m2_ck>; | |
| 150 | + clocks = <&l4ls_gclk>; | |
| 151 | 151 | ti,bit-shift = <6>; |
| 152 | 152 | reg = <0x0664>; |
| 153 | 153 | }; |
| @@ -494,12 +494,12 @@ · 493 unmodified lines | ||
| 494 | 494 | |
| 495 | 495 | pinctrl_usart3_rts: usart3_rts-0 { |
| 496 | 496 | atmel,pins = |
| 497 | − <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC8 periph B */ | |
| 497 | + <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE>; | |
| 498 | 498 | }; |
| 499 | 499 | |
| 500 | 500 | pinctrl_usart3_cts: usart3_cts-0 { |
| 501 | 501 | atmel,pins = |
| 502 | − <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC10 periph B */ | |
| 502 | + <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; | |
| 503 | 503 | }; |
| 504 | 504 | }; |
| 505 | 505 | |
| @@ -853,7 +853,7 @@ · 347 unmodified lines | ||
| 853 | 853 | }; |
| 854 | 854 | |
| 855 | 855 | usb1: gadget@fffa4000 { |
| 856 | − compatible = "atmel,at91rm9200-udc"; | |
| 856 | + compatible = "atmel,at91sam9260-udc"; | |
| 857 | 857 | reg = <0xfffa4000 0x4000>; |
| 858 | 858 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; |
| 859 | 859 | clocks = <&udc_clk>, <&udpck>; |
| @@ -976,7 +976,6 @@ · 116 unmodified lines | ||
| 976 | 976 | atmel,watchdog-type = "hardware"; |
| 977 | 977 | atmel,reset-type = "all"; |
| 978 | 978 | atmel,dbg-halt; |
| 979 | − atmel,idle-halt; | |
| 980 | 979 | status = "disabled"; |
| 981 | 980 | }; |
| 982 | 981 | |
| @@ -124,11 +124,12 @@ · 123 unmodified lines | ||
| 124 | 124 | }; |
| 125 | 125 | |
| 126 | 126 | usb1: gadget@fffa4000 { |
| 127 | − compatible = "atmel,at91rm9200-udc"; | |
| 127 | + compatible = "atmel,at91sam9261-udc"; | |
| 128 | 128 | reg = <0xfffa4000 0x4000>; |
| 129 | 129 | interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>; |
| 130 | − clocks = <&usb>, <&udc_clk>, <&udpck>; | |
| 131 | − clock-names = "usb_clk", "udc_clk", "udpck"; | |
| 130 | + clocks = <&udc_clk>, <&udpck>; | |
| 131 | + clock-names = "pclk", "hclk"; | |
| 132 | + atmel,matrix = <&matrix>; | |
| 132 | 133 | status = "disabled"; |
| 133 | 134 | }; |
| 134 | 135 | |
| @@ -262,7 +263,7 @@ · 127 unmodified lines | ||
| 262 | 263 | }; |
| 263 | 264 | |
| 264 | 265 | matrix: matrix@ffffee00 { |
| 265 | − compatible = "atmel,at91sam9260-bus-matrix"; | |
| 266 | + compatible = "atmel,at91sam9260-bus-matrix", "syscon"; | |
| 266 | 267 | reg = <0xffffee00 0x200>; |
| 267 | 268 | }; |
| 268 | 269 | |
| @@ -69,7 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | sram1: sram@00500000 { |
| 71 | 71 | compatible = "mmio-sram"; |
| 72 | − reg = <0x00300000 0x4000>; | |
| 72 | + reg = <0x00500000 0x4000>; | |
| 73 | 73 | }; |
| 74 | 74 | |
| 75 | 75 | ahb { |
| @@ -856,7 +856,7 @@ · 780 unmodified lines | ||
| 856 | 856 | }; |
| 857 | 857 | |
| 858 | 858 | usb1: gadget@fff78000 { |
| 859 | − compatible = "atmel,at91rm9200-udc"; | |
| 859 | + compatible = "atmel,at91sam9263-udc"; | |
| 860 | 860 | reg = <0xfff78000 0x4000>; |
| 861 | 861 | interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>; |
| 862 | 862 | clocks = <&udc_clk>, <&udpck>; |
| @@ -905,7 +905,6 @@ · 42 unmodified lines | ||
| 905 | 905 | atmel,watchdog-type = "hardware"; |
| 906 | 906 | atmel,reset-type = "all"; |
| 907 | 907 | atmel,dbg-halt; |
| 908 | − atmel,idle-halt; | |
| 909 | 908 | status = "disabled"; |
| 910 | 909 | }; |
| 911 | 910 | |
| @@ -1116,7 +1116,6 @@ · 1115 unmodified lines | ||
| 1116 | 1116 | atmel,watchdog-type = "hardware"; |
| 1117 | 1117 | atmel,reset-type = "all"; |
| 1118 | 1118 | atmel,dbg-halt; |
| 1119 | − atmel,idle-halt; | |
| 1120 | 1119 | status = "disabled"; |
| 1121 | 1120 | }; |
| 1122 | 1121 | |
| @@ -1301,7 +1300,7 @@ · 178 unmodified lines | ||
| 1301 | 1300 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
| 1302 | 1301 | reg = <0x00800000 0x100000>; |
| 1303 | 1302 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; |
| 1304 | − clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; | |
| 1303 | + clocks = <&utmi>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; | |
| 1305 | 1304 | clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck"; |
| 1306 | 1305 | status = "disabled"; |
| 1307 | 1306 | }; |
| @@ -894,7 +894,6 @@ · 893 unmodified lines | ||
| 894 | 894 | atmel,watchdog-type = "hardware"; |
| 895 | 895 | atmel,reset-type = "all"; |
| 896 | 896 | atmel,dbg-halt; |
| 897 | − atmel,idle-halt; | |
| 898 | 897 | status = "disabled"; |
| 899 | 898 | }; |
| 900 | 899 | |
| @@ -1066,7 +1066,7 @@ · 1065 unmodified lines | ||
| 1066 | 1066 | reg = <0x00500000 0x80000 |
| 1067 | 1067 | 0xf803c000 0x400>; |
| 1068 | 1068 | interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>; |
| 1069 | − clocks = <&usb>, <&udphs_clk>; | |
| 1069 | + clocks = <&utmi>, <&udphs_clk>; | |
| 1070 | 1070 | clock-names = "hclk", "pclk"; |
| 1071 | 1071 | status = "disabled"; |
| 1072 | 1072 | |
| @@ -1130,7 +1130,6 @@ · 57 unmodified lines | ||
| 1130 | 1130 | atmel,watchdog-type = "hardware"; |
| 1131 | 1131 | atmel,reset-type = "all"; |
| 1132 | 1132 | atmel,dbg-halt; |
| 1133 | − atmel,idle-halt; | |
| 1134 | 1133 | status = "disabled"; |
| 1135 | 1134 | }; |
| 1136 | 1135 | |
| @@ -1186,7 +1185,7 @@ · 49 unmodified lines | ||
| 1186 | 1185 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
| 1187 | 1186 | reg = <0x00700000 0x100000>; |
| 1188 | 1187 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>; |
| 1189 | − clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | |
| 1188 | + clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; | |
| 1190 | 1189 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
| 1191 | 1190 | status = "disabled"; |
| 1192 | 1191 | }; |
| @@ -263,17 +263,15 @@ · 262 unmodified lines | ||
| 263 | 263 | |
| 264 | 264 | dcan1_pins_default: dcan1_pins_default { |
| 265 | 265 | pinctrl-single,pins = < |
| 266 | − 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ | |
| 267 | − 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | |
| 268 | − 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ | |
| 266 | + 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ | |
| 267 | + 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ | |
| 269 | 268 | >; |
| 270 | 269 | }; |
| 271 | 270 | |
| 272 | 271 | dcan1_pins_sleep: dcan1_pins_sleep { |
| 273 | 272 | pinctrl-single,pins = < |
| 274 | − 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ | |
| 275 | − 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | |
| 276 | − 0x418 (MUX_MODE15) /* wakeup0.off */ | |
| 273 | + 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ | |
| 274 | + 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ | |
| 277 | 275 | >; |
| 278 | 276 | }; |
| 279 | 277 | }; |
| @@ -119,17 +119,15 @@ · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | dcan1_pins_default: dcan1_pins_default { |
| 121 | 121 | pinctrl-single,pins = < |
| 122 | − 0x3d0 (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */ | |
| 123 | − 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | |
| 124 | − 0x418 (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */ | |
| 122 | + 0x3d0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */ | |
| 123 | + 0x418 (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */ | |
| 125 | 124 | >; |
| 126 | 125 | }; |
| 127 | 126 | |
| 128 | 127 | dcan1_pins_sleep: dcan1_pins_sleep { |
| 129 | 128 | pinctrl-single,pins = < |
| 130 | − 0x3d0 (MUX_MODE15) /* dcan1_tx.off */ | |
| 131 | − 0x3d4 (MUX_MODE15) /* dcan1_rx.off */ | |
| 132 | − 0x418 (MUX_MODE15) /* wakeup0.off */ | |
| 129 | + 0x3d0 (MUX_MODE15 | PULL_UP) /* dcan1_tx.off */ | |
| 130 | + 0x418 (MUX_MODE15 | PULL_UP) /* wakeup0.off */ | |
| 133 | 131 | >; |
| 134 | 132 | }; |
| 135 | 133 | |
| @@ -243,10 +243,18 @@ · 242 unmodified lines | ||
| 243 | 243 | ti,invert-autoidle-bit; |
| 244 | 244 | }; |
| 245 | 245 | |
| 246 | + dpll_core_byp_mux: dpll_core_byp_mux { | |
| 247 | + #clock-cells = <0>; | |
| 248 | + compatible = "ti,mux-clock"; | |
| 249 | + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 250 | + ti,bit-shift = <23>; | |
| 251 | + reg = <0x012c>; | |
| 252 | + }; | |
| 253 | + | |
| 246 | 254 | dpll_core_ck: dpll_core_ck { |
| 247 | 255 | #clock-cells = <0>; |
| 248 | 256 | compatible = "ti,omap4-dpll-core-clock"; |
| 249 | − clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 257 | + clocks = <&sys_clkin1>, <&dpll_core_byp_mux>; | |
| 250 | 258 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; |
| 251 | 259 | }; |
| 252 | 260 | |
| @@ -309,10 +317,18 @@ · 56 unmodified lines | ||
| 309 | 317 | clock-div = <1>; |
| 310 | 318 | }; |
| 311 | 319 | |
| 320 | + dpll_dsp_byp_mux: dpll_dsp_byp_mux { | |
| 321 | + #clock-cells = <0>; | |
| 322 | + compatible = "ti,mux-clock"; | |
| 323 | + clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; | |
| 324 | + ti,bit-shift = <23>; | |
| 325 | + reg = <0x0240>; | |
| 326 | + }; | |
| 327 | + | |
| 312 | 328 | dpll_dsp_ck: dpll_dsp_ck { |
| 313 | 329 | #clock-cells = <0>; |
| 314 | 330 | compatible = "ti,omap4-dpll-clock"; |
| 315 | − clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; | |
| 331 | + clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>; | |
| 316 | 332 | reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; |
| 317 | 333 | }; |
| 318 | 334 | |
| @@ -335,10 +351,18 @@ · 16 unmodified lines | ||
| 335 | 351 | clock-div = <1>; |
| 336 | 352 | }; |
| 337 | 353 | |
| 354 | + dpll_iva_byp_mux: dpll_iva_byp_mux { | |
| 355 | + #clock-cells = <0>; | |
| 356 | + compatible = "ti,mux-clock"; | |
| 357 | + clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; | |
| 358 | + ti,bit-shift = <23>; | |
| 359 | + reg = <0x01ac>; | |
| 360 | + }; | |
| 361 | + | |
| 338 | 362 | dpll_iva_ck: dpll_iva_ck { |
| 339 | 363 | #clock-cells = <0>; |
| 340 | 364 | compatible = "ti,omap4-dpll-clock"; |
| 341 | − clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; | |
| 365 | + clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>; | |
| 342 | 366 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; |
| 343 | 367 | }; |
| 344 | 368 | |
| @@ -361,10 +385,18 @@ · 16 unmodified lines | ||
| 361 | 385 | clock-div = <1>; |
| 362 | 386 | }; |
| 363 | 387 | |
| 388 | + dpll_gpu_byp_mux: dpll_gpu_byp_mux { | |
| 389 | + #clock-cells = <0>; | |
| 390 | + compatible = "ti,mux-clock"; | |
| 391 | + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 392 | + ti,bit-shift = <23>; | |
| 393 | + reg = <0x02e4>; | |
| 394 | + }; | |
| 395 | + | |
| 364 | 396 | dpll_gpu_ck: dpll_gpu_ck { |
| 365 | 397 | #clock-cells = <0>; |
| 366 | 398 | compatible = "ti,omap4-dpll-clock"; |
| 367 | − clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 399 | + clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>; | |
| 368 | 400 | reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; |
| 369 | 401 | }; |
| 370 | 402 | |
| @@ -398,10 +430,18 @@ · 27 unmodified lines | ||
| 398 | 430 | clock-div = <1>; |
| 399 | 431 | }; |
| 400 | 432 | |
| 433 | + dpll_ddr_byp_mux: dpll_ddr_byp_mux { | |
| 434 | + #clock-cells = <0>; | |
| 435 | + compatible = "ti,mux-clock"; | |
| 436 | + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 437 | + ti,bit-shift = <23>; | |
| 438 | + reg = <0x021c>; | |
| 439 | + }; | |
| 440 | + | |
| 401 | 441 | dpll_ddr_ck: dpll_ddr_ck { |
| 402 | 442 | #clock-cells = <0>; |
| 403 | 443 | compatible = "ti,omap4-dpll-clock"; |
| 404 | − clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 444 | + clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>; | |
| 405 | 445 | reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>; |
| 406 | 446 | }; |
| 407 | 447 | |
| @@ -416,10 +456,18 @@ · 8 unmodified lines | ||
| 416 | 456 | ti,invert-autoidle-bit; |
| 417 | 457 | }; |
| 418 | 458 | |
| 459 | + dpll_gmac_byp_mux: dpll_gmac_byp_mux { | |
| 460 | + #clock-cells = <0>; | |
| 461 | + compatible = "ti,mux-clock"; | |
| 462 | + clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 463 | + ti,bit-shift = <23>; | |
| 464 | + reg = <0x02b4>; | |
| 465 | + }; | |
| 466 | + | |
| 419 | 467 | dpll_gmac_ck: dpll_gmac_ck { |
| 420 | 468 | #clock-cells = <0>; |
| 421 | 469 | compatible = "ti,omap4-dpll-clock"; |
| 422 | − clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; | |
| 470 | + clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>; | |
| 423 | 471 | reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>; |
| 424 | 472 | }; |
| 425 | 473 | |
| @@ -482,10 +530,18 @@ · 56 unmodified lines | ||
| 482 | 530 | clock-div = <1>; |
| 483 | 531 | }; |
| 484 | 532 | |
| 533 | + dpll_eve_byp_mux: dpll_eve_byp_mux { | |
| 534 | + #clock-cells = <0>; | |
| 535 | + compatible = "ti,mux-clock"; | |
| 536 | + clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; | |
| 537 | + ti,bit-shift = <23>; | |
| 538 | + reg = <0x0290>; | |
| 539 | + }; | |
| 540 | + | |
| 485 | 541 | dpll_eve_ck: dpll_eve_ck { |
| 486 | 542 | #clock-cells = <0>; |
| 487 | 543 | compatible = "ti,omap4-dpll-clock"; |
| 488 | − clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; | |
| 544 | + clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>; | |
| 489 | 545 | reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>; |
| 490 | 546 | }; |
| 491 | 547 | |
| @@ -1249,10 +1305,18 @@ · 757 unmodified lines | ||
| 1249 | 1305 | clock-div = <1>; |
| 1250 | 1306 | }; |
| 1251 | 1307 | |
| 1308 | + dpll_per_byp_mux: dpll_per_byp_mux { | |
| 1309 | + #clock-cells = <0>; | |
| 1310 | + compatible = "ti,mux-clock"; | |
| 1311 | + clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; | |
| 1312 | + ti,bit-shift = <23>; | |
| 1313 | + reg = <0x014c>; | |
| 1314 | + }; | |
| 1315 | + | |
| 1252 | 1316 | dpll_per_ck: dpll_per_ck { |
| 1253 | 1317 | #clock-cells = <0>; |
| 1254 | 1318 | compatible = "ti,omap4-dpll-clock"; |
| 1255 | − clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; | |
| 1319 | + clocks = <&sys_clkin1>, <&dpll_per_byp_mux>; | |
| 1256 | 1320 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; |
| 1257 | 1321 | }; |
| 1258 | 1322 | |
| @@ -1275,10 +1339,18 @@ · 16 unmodified lines | ||
| 1275 | 1339 | clock-div = <1>; |
| 1276 | 1340 | }; |
| 1277 | 1341 | |
| 1342 | + dpll_usb_byp_mux: dpll_usb_byp_mux { | |
| 1343 | + #clock-cells = <0>; | |
| 1344 | + compatible = "ti,mux-clock"; | |
| 1345 | + clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; | |
| 1346 | + ti,bit-shift = <23>; | |
| 1347 | + reg = <0x018c>; | |
| 1348 | + }; | |
| 1349 | + | |
| 1278 | 1350 | dpll_usb_ck: dpll_usb_ck { |
| 1279 | 1351 | #clock-cells = <0>; |
| 1280 | 1352 | compatible = "ti,omap4-dpll-j-type-clock"; |
| 1281 | − clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; | |
| 1353 | + clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>; | |
| 1282 | 1354 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; |
| 1283 | 1355 | }; |
| 1284 | 1356 | |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | 20 | #include "skeleton.dtsi" |
| 21 | +#include "exynos4-cpu-thermal.dtsi" | |
| 21 | 22 | #include <dt-bindings/clock/exynos3250.h> |
| 22 | 23 | |
| 23 | 24 | / { |
| @@ -193,6 +194,7 @@ · 169 unmodified lines | ||
| 193 | 194 | interrupts = <0 216 0>; |
| 194 | 195 | clocks = <&cmu CLK_TMU_APBIF>; |
| 195 | 196 | clock-names = "tmu_apbif"; |
| 197 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 196 | 198 | status = "disabled"; |
| 197 | 199 | }; |
| 198 | 200 | |
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * Device tree sources for Exynos4 thermal zone | |
| 3 | + * | |
| 4 | + * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License version 2 as | |
| 8 | + * published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <dt-bindings/thermal/thermal.h> | |
| 13 | + | |
| 14 | +/ { | |
| 15 | +thermal-zones { | |
| 16 | + cpu_thermal: cpu-thermal { | |
| 17 | + thermal-sensors = <&tmu 0>; | |
| 18 | + polling-delay-passive = <0>; | |
| 19 | + polling-delay = <0>; | |
| 20 | + trips { | |
| 21 | + cpu_alert0: cpu-alert-0 { | |
| 22 | + temperature = <70000>; /* millicelsius */ | |
| 23 | + hysteresis = <10000>; /* millicelsius */ | |
| 24 | + type = "active"; | |
| 25 | + }; | |
| 26 | + cpu_alert1: cpu-alert-1 { | |
| 27 | + temperature = <95000>; /* millicelsius */ | |
| 28 | + hysteresis = <10000>; /* millicelsius */ | |
| 29 | + type = "active"; | |
| 30 | + }; | |
| 31 | + cpu_alert2: cpu-alert-2 { | |
| 32 | + temperature = <110000>; /* millicelsius */ | |
| 33 | + hysteresis = <10000>; /* millicelsius */ | |
| 34 | + type = "active"; | |
| 35 | + }; | |
| 36 | + cpu_crit0: cpu-crit-0 { | |
| 37 | + temperature = <120000>; /* millicelsius */ | |
| 38 | + hysteresis = <0>; /* millicelsius */ | |
| 39 | + type = "critical"; | |
| 40 | + }; | |
| 41 | + }; | |
| 42 | + cooling-maps { | |
| 43 | + map0 { | |
| 44 | + trip = <&cpu_alert0>; | |
| 45 | + }; | |
| 46 | + map1 { | |
| 47 | + trip = <&cpu_alert1>; | |
| 48 | + }; | |
| 49 | + }; | |
| 50 | + }; | |
| 51 | +}; | |
| 52 | +}; | |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | i2c5 = &i2c_5; |
| 39 | 39 | i2c6 = &i2c_6; |
| 40 | 40 | i2c7 = &i2c_7; |
| 41 | + i2c8 = &i2c_8; | |
| 41 | 42 | csis0 = &csis_0; |
| 42 | 43 | csis1 = &csis_1; |
| 43 | 44 | fimc0 = &fimc_0; |
| @@ -104,6 +105,7 @@ · 60 unmodified lines | ||
| 104 | 105 | compatible = "samsung,exynos4210-pd"; |
| 105 | 106 | reg = <0x10023C20 0x20>; |
| 106 | 107 | #power-domain-cells = <0>; |
| 108 | + power-domains = <&pd_lcd0>; | |
| 107 | 109 | }; |
| 108 | 110 | |
| 109 | 111 | pd_cam: cam-power-domain@10023C00 { |
| @@ -554,6 +556,22 @@ · 444 unmodified lines | ||
| 554 | 556 | status = "disabled"; |
| 555 | 557 | }; |
| 556 | 558 | |
| 559 | + i2c_8: i2c@138E0000 { | |
| 560 | + #address-cells = <1>; | |
| 561 | + #size-cells = <0>; | |
| 562 | + compatible = "samsung,s3c2440-hdmiphy-i2c"; | |
| 563 | + reg = <0x138E0000 0x100>; | |
| 564 | + interrupts = <0 93 0>; | |
| 565 | + clocks = <&clock CLK_I2C_HDMI>; | |
| 566 | + clock-names = "i2c"; | |
| 567 | + status = "disabled"; | |
| 568 | + | |
| 569 | + hdmi_i2c_phy: hdmiphy@38 { | |
| 570 | + compatible = "exynos4210-hdmiphy"; | |
| 571 | + reg = <0x38>; | |
| 572 | + }; | |
| 573 | + }; | |
| 574 | + | |
| 557 | 575 | spi_0: spi@13920000 { |
| 558 | 576 | compatible = "samsung,exynos4210-spi"; |
| 559 | 577 | reg = <0x13920000 0x100>; |
| @@ -663,6 +681,33 @@ · 103 unmodified lines | ||
| 663 | 681 | status = "disabled"; |
| 664 | 682 | }; |
| 665 | 683 | |
| 684 | + tmu: tmu@100C0000 { | |
| 685 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 686 | + }; | |
| 687 | + | |
| 688 | + hdmi: hdmi@12D00000 { | |
| 689 | + compatible = "samsung,exynos4210-hdmi"; | |
| 690 | + reg = <0x12D00000 0x70000>; | |
| 691 | + interrupts = <0 92 0>; | |
| 692 | + clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy", | |
| 693 | + "mout_hdmi"; | |
| 694 | + clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, | |
| 695 | + <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, | |
| 696 | + <&clock CLK_MOUT_HDMI>; | |
| 697 | + phy = <&hdmi_i2c_phy>; | |
| 698 | + power-domains = <&pd_tv>; | |
| 699 | + samsung,syscon-phandle = <&pmu_system_controller>; | |
| 700 | + status = "disabled"; | |
| 701 | + }; | |
| 702 | + | |
| 703 | + mixer: mixer@12C10000 { | |
| 704 | + compatible = "samsung,exynos4210-mixer"; | |
| 705 | + interrupts = <0 91 0>; | |
| 706 | + reg = <0x12C10000 0x2100>, <0x12c00000 0x300>; | |
| 707 | + power-domains = <&pd_tv>; | |
| 708 | + status = "disabled"; | |
| 709 | + }; | |
| 710 | + | |
| 666 | 711 | ppmu_dmc0: ppmu_dmc0@106a0000 { |
| 667 | 712 | compatible = "samsung,exynos-ppmu"; |
| 668 | 713 | reg = <0x106a0000 0x2000>; |
| @@ -426,6 +426,25 @@ · 425 unmodified lines | ||
| 426 | 426 | status = "okay"; |
| 427 | 427 | }; |
| 428 | 428 | |
| 429 | + tmu@100C0000 { | |
| 430 | + status = "okay"; | |
| 431 | + }; | |
| 432 | + | |
| 433 | + thermal-zones { | |
| 434 | + cpu_thermal: cpu-thermal { | |
| 435 | + cooling-maps { | |
| 436 | + map0 { | |
| 437 | + /* Corresponds to 800MHz at freq_table */ | |
| 438 | + cooling-device = <&cpu0 2 2>; | |
| 439 | + }; | |
| 440 | + map1 { | |
| 441 | + /* Corresponds to 200MHz at freq_table */ | |
| 442 | + cooling-device = <&cpu0 4 4>; | |
| 443 | + }; | |
| 444 | + }; | |
| 445 | + }; | |
| 446 | + }; | |
| 447 | + | |
| 429 | 448 | camera { |
| 430 | 449 | pinctrl-names = "default"; |
| 431 | 450 | pinctrl-0 = <>; |
| @@ -505,6 +505,63 @@ · 504 unmodified lines | ||
| 505 | 505 | assigned-clock-rates = <0>, <160000000>; |
| 506 | 506 | }; |
| 507 | 507 | }; |
| 508 | + | |
| 509 | + hdmi_en: voltage-regulator-hdmi-5v { | |
| 510 | + compatible = "regulator-fixed"; | |
| 511 | + regulator-name = "HDMI_5V"; | |
| 512 | + regulator-min-microvolt = <5000000>; | |
| 513 | + regulator-max-microvolt = <5000000>; | |
| 514 | + gpio = <&gpe0 1 0>; | |
| 515 | + enable-active-high; | |
| 516 | + }; | |
| 517 | + | |
| 518 | + hdmi_ddc: i2c-ddc { | |
| 519 | + compatible = "i2c-gpio"; | |
| 520 | + gpios = <&gpe4 2 0 &gpe4 3 0>; | |
| 521 | + i2c-gpio,delay-us = <100>; | |
| 522 | + #address-cells = <1>; | |
| 523 | + #size-cells = <0>; | |
| 524 | + | |
| 525 | + pinctrl-0 = <&i2c_ddc_bus>; | |
| 526 | + pinctrl-names = "default"; | |
| 527 | + status = "okay"; | |
| 528 | + }; | |
| 529 | + | |
| 530 | + mixer@12C10000 { | |
| 531 | + status = "okay"; | |
| 532 | + }; | |
| 533 | + | |
| 534 | + hdmi@12D00000 { | |
| 535 | + hpd-gpio = <&gpx3 7 0>; | |
| 536 | + pinctrl-names = "default"; | |
| 537 | + pinctrl-0 = <&hdmi_hpd>; | |
| 538 | + hdmi-en-supply = <&hdmi_en>; | |
| 539 | + vdd-supply = <&ldo3_reg>; | |
| 540 | + vdd_osc-supply = <&ldo4_reg>; | |
| 541 | + vdd_pll-supply = <&ldo3_reg>; | |
| 542 | + ddc = <&hdmi_ddc>; | |
| 543 | + status = "okay"; | |
| 544 | + }; | |
| 545 | + | |
| 546 | + i2c@138E0000 { | |
| 547 | + status = "okay"; | |
| 548 | + }; | |
| 549 | +}; | |
| 550 | + | |
| 551 | +&pinctrl_1 { | |
| 552 | + hdmi_hpd: hdmi-hpd { | |
| 553 | + samsung,pins = "gpx3-7"; | |
| 554 | + samsung,pin-pud = <0>; | |
| 555 | + }; | |
| 556 | +}; | |
| 557 | + | |
| 558 | +&pinctrl_0 { | |
| 559 | + i2c_ddc_bus: i2c-ddc-bus { | |
| 560 | + samsung,pins = "gpe4-2", "gpe4-3"; | |
| 561 | + samsung,pin-function = <2>; | |
| 562 | + samsung,pin-pud = <3>; | |
| 563 | + samsung,pin-drv = <0>; | |
| 564 | + }; | |
| 508 | 565 | }; |
| 509 | 566 | |
| 510 | 567 | &mdma1 { |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include "exynos4.dtsi" |
| 23 | 23 | #include "exynos4210-pinctrl.dtsi" |
| 24 | +#include "exynos4-cpu-thermal.dtsi" | |
| 24 | 25 | |
| 25 | 26 | / { |
| 26 | 27 | compatible = "samsung,exynos4210", "samsung,exynos4"; |
| @@ -35,10 +36,13 @@ · 8 unmodified lines | ||
| 35 | 36 | #address-cells = <1>; |
| 36 | 37 | #size-cells = <0>; |
| 37 | 38 | |
| 38 | − cpu@900 { | |
| 39 | + cpu0: cpu@900 { | |
| 39 | 40 | device_type = "cpu"; |
| 40 | 41 | compatible = "arm,cortex-a9"; |
| 41 | 42 | reg = <0x900>; |
| 43 | + cooling-min-level = <4>; | |
| 44 | + cooling-max-level = <2>; | |
| 45 | + #cooling-cells = <2>; /* min followed by max */ | |
| 42 | 46 | }; |
| 43 | 47 | |
| 44 | 48 | cpu@901 { |
| @@ -153,16 +157,38 @@ · 108 unmodified lines | ||
| 153 | 157 | reg = <0x03860000 0x1000>; |
| 154 | 158 | }; |
| 155 | 159 | |
| 156 | − tmu@100C0000 { | |
| 160 | + tmu: tmu@100C0000 { | |
| 157 | 161 | compatible = "samsung,exynos4210-tmu"; |
| 158 | 162 | interrupt-parent = <&combiner>; |
| 159 | 163 | reg = <0x100C0000 0x100>; |
| 160 | 164 | interrupts = <2 4>; |
| 161 | 165 | clocks = <&clock CLK_TMU_APBIF>; |
| 162 | 166 | clock-names = "tmu_apbif"; |
| 167 | + samsung,tmu_gain = <15>; | |
| 168 | + samsung,tmu_reference_voltage = <7>; | |
| 163 | 169 | status = "disabled"; |
| 164 | 170 | }; |
| 165 | 171 | |
| 172 | + thermal-zones { | |
| 173 | + cpu_thermal: cpu-thermal { | |
| 174 | + polling-delay-passive = <0>; | |
| 175 | + polling-delay = <0>; | |
| 176 | + thermal-sensors = <&tmu 0>; | |
| 177 | + | |
| 178 | + trips { | |
| 179 | + cpu_alert0: cpu-alert-0 { | |
| 180 | + temperature = <85000>; /* millicelsius */ | |
| 181 | + }; | |
| 182 | + cpu_alert1: cpu-alert-1 { | |
| 183 | + temperature = <100000>; /* millicelsius */ | |
| 184 | + }; | |
| 185 | + cpu_alert2: cpu-alert-2 { | |
| 186 | + temperature = <110000>; /* millicelsius */ | |
| 187 | + }; | |
| 188 | + }; | |
| 189 | + }; | |
| 190 | + }; | |
| 191 | + | |
| 166 | 192 | g2d@12800000 { |
| 167 | 193 | compatible = "samsung,s5pv210-g2d"; |
| 168 | 194 | reg = <0x12800000 0x1000>; |
| @@ -203,6 +229,14 @@ · 34 unmodified lines | ||
| 203 | 229 | }; |
| 204 | 230 | }; |
| 205 | 231 | |
| 232 | + mixer: mixer@12C10000 { | |
| 233 | + clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer", | |
| 234 | + "sclk_mixer"; | |
| 235 | + clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | |
| 236 | + <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>, | |
| 237 | + <&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>; | |
| 238 | + }; | |
| 239 | + | |
| 206 | 240 | ppmu_lcd1: ppmu_lcd1@12240000 { |
| 207 | 241 | compatible = "samsung,exynos-ppmu"; |
| 208 | 242 | reg = <0x12240000 0x2000>; |
| @@ -26,10 +26,13 @@ · 25 unmodified lines | ||
| 26 | 26 | #address-cells = <1>; |
| 27 | 27 | #size-cells = <0>; |
| 28 | 28 | |
| 29 | − cpu@A00 { | |
| 29 | + cpu0: cpu@A00 { | |
| 30 | 30 | device_type = "cpu"; |
| 31 | 31 | compatible = "arm,cortex-a9"; |
| 32 | 32 | reg = <0xA00>; |
| 33 | + cooling-min-level = <13>; | |
| 34 | + cooling-max-level = <7>; | |
| 35 | + #cooling-cells = <2>; /* min followed by max */ | |
| 33 | 36 | }; |
| 34 | 37 | |
| 35 | 38 | cpu@A01 { |
| @@ -249,6 +249,20 @@ · 248 unmodified lines | ||
| 249 | 249 | regulator-always-on; |
| 250 | 250 | }; |
| 251 | 251 | |
| 252 | + ldo8_reg: ldo@8 { | |
| 253 | + regulator-compatible = "LDO8"; | |
| 254 | + regulator-name = "VDD10_HDMI_1.0V"; | |
| 255 | + regulator-min-microvolt = <1000000>; | |
| 256 | + regulator-max-microvolt = <1000000>; | |
| 257 | + }; | |
| 258 | + | |
| 259 | + ldo10_reg: ldo@10 { | |
| 260 | + regulator-compatible = "LDO10"; | |
| 261 | + regulator-name = "VDDQ_MIPIHSI_1.8V"; | |
| 262 | + regulator-min-microvolt = <1800000>; | |
| 263 | + regulator-max-microvolt = <1800000>; | |
| 264 | + }; | |
| 265 | + | |
| 252 | 266 | ldo11_reg: LDO11 { |
| 253 | 267 | regulator-name = "VDD18_ABB1_1.8V"; |
| 254 | 268 | regulator-min-microvolt = <1800000>; |
| @@ -411,6 +425,51 @@ · 156 unmodified lines | ||
| 411 | 425 | ehci: ehci@12580000 { |
| 412 | 426 | status = "okay"; |
| 413 | 427 | }; |
| 428 | + | |
| 429 | + tmu@100C0000 { | |
| 430 | + vtmu-supply = <&ldo10_reg>; | |
| 431 | + status = "okay"; | |
| 432 | + }; | |
| 433 | + | |
| 434 | + thermal-zones { | |
| 435 | + cpu_thermal: cpu-thermal { | |
| 436 | + cooling-maps { | |
| 437 | + map0 { | |
| 438 | + /* Corresponds to 800MHz at freq_table */ | |
| 439 | + cooling-device = <&cpu0 7 7>; | |
| 440 | + }; | |
| 441 | + map1 { | |
| 442 | + /* Corresponds to 200MHz at freq_table */ | |
| 443 | + cooling-device = <&cpu0 13 13>; | |
| 444 | + }; | |
| 445 | + }; | |
| 446 | + }; | |
| 447 | + }; | |
| 448 | + | |
| 449 | + mixer: mixer@12C10000 { | |
| 450 | + status = "okay"; | |
| 451 | + }; | |
| 452 | + | |
| 453 | + hdmi@12D00000 { | |
| 454 | + hpd-gpio = <&gpx3 7 0>; | |
| 455 | + pinctrl-names = "default"; | |
| 456 | + pinctrl-0 = <&hdmi_hpd>; | |
| 457 | + vdd-supply = <&ldo8_reg>; | |
| 458 | + vdd_osc-supply = <&ldo10_reg>; | |
| 459 | + vdd_pll-supply = <&ldo8_reg>; | |
| 460 | + ddc = <&hdmi_ddc>; | |
| 461 | + status = "okay"; | |
| 462 | + }; | |
| 463 | + | |
| 464 | + hdmi_ddc: i2c@13880000 { | |
| 465 | + status = "okay"; | |
| 466 | + pinctrl-names = "default"; | |
| 467 | + pinctrl-0 = <&i2c2_bus>; | |
| 468 | + }; | |
| 469 | + | |
| 470 | + i2c@138E0000 { | |
| 471 | + status = "okay"; | |
| 472 | + }; | |
| 414 | 473 | }; |
| 415 | 474 | |
| 416 | 475 | &pinctrl_1 { |
| @@ -425,4 +484,9 @@ · 8 unmodified lines | ||
| 425 | 484 | samsung,pin-pud = <0>; |
| 426 | 485 | samsung,pin-drv = <0>; |
| 427 | 486 | }; |
| 487 | + | |
| 488 | + hdmi_hpd: hdmi-hpd { | |
| 489 | + samsung,pins = "gpx3-7"; | |
| 490 | + samsung,pin-pud = <1>; | |
| 491 | + }; | |
| 428 | 492 | }; |
| @@ -0,0 +1,24 @@ | ||
| 1 | +/* | |
| 2 | + * Device tree sources for Exynos4412 TMU sensor configuration | |
| 3 | + * | |
| 4 | + * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License version 2 as | |
| 8 | + * published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <dt-bindings/thermal/thermal_exynos.h> | |
| 13 | + | |
| 14 | +#thermal-sensor-cells = <0>; | |
| 15 | +samsung,tmu_gain = <8>; | |
| 16 | +samsung,tmu_reference_voltage = <16>; | |
| 17 | +samsung,tmu_noise_cancel_mode = <4>; | |
| 18 | +samsung,tmu_efuse_value = <55>; | |
| 19 | +samsung,tmu_min_efuse_value = <40>; | |
| 20 | +samsung,tmu_max_efuse_value = <100>; | |
| 21 | +samsung,tmu_first_point_trim = <25>; | |
| 22 | +samsung,tmu_second_point_trim = <85>; | |
| 23 | +samsung,tmu_default_temp_offset = <50>; | |
| 24 | +samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>; | |
| @@ -927,6 +927,21 @@ · 926 unmodified lines | ||
| 927 | 927 | pulldown-ohm = <100000>; /* 100K */ |
| 928 | 928 | io-channels = <&adc 2>; /* Battery temperature */ |
| 929 | 929 | }; |
| 930 | + | |
| 931 | + thermal-zones { | |
| 932 | + cpu_thermal: cpu-thermal { | |
| 933 | + cooling-maps { | |
| 934 | + map0 { | |
| 935 | + /* Corresponds to 800MHz at freq_table */ | |
| 936 | + cooling-device = <&cpu0 7 7>; | |
| 937 | + }; | |
| 938 | + map1 { | |
| 939 | + /* Corresponds to 200MHz at freq_table */ | |
| 940 | + cooling-device = <&cpu0 13 13>; | |
| 941 | + }; | |
| 942 | + }; | |
| 943 | + }; | |
| 944 | + }; | |
| 930 | 945 | }; |
| 931 | 946 | |
| 932 | 947 | &pmu_system_controller { |
| @@ -26,10 +26,13 @@ · 25 unmodified lines | ||
| 26 | 26 | #address-cells = <1>; |
| 27 | 27 | #size-cells = <0>; |
| 28 | 28 | |
| 29 | − cpu@A00 { | |
| 29 | + cpu0: cpu@A00 { | |
| 30 | 30 | device_type = "cpu"; |
| 31 | 31 | compatible = "arm,cortex-a9"; |
| 32 | 32 | reg = <0xA00>; |
| 33 | + cooling-min-level = <13>; | |
| 34 | + cooling-max-level = <7>; | |
| 35 | + #cooling-cells = <2>; /* min followed by max */ | |
| 33 | 36 | }; |
| 34 | 37 | |
| 35 | 38 | cpu@A01 { |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #include "exynos4.dtsi" |
| 21 | 21 | #include "exynos4x12-pinctrl.dtsi" |
| 22 | +#include "exynos4-cpu-thermal.dtsi" | |
| 22 | 23 | |
| 23 | 24 | / { |
| 24 | 25 | aliases { |
| @@ -297,4 +298,15 @@ · 272 unmodified lines | ||
| 297 | 298 | clock-names = "tmu_apbif"; |
| 298 | 299 | status = "disabled"; |
| 299 | 300 | }; |
| 301 | + | |
| 302 | + hdmi: hdmi@12D00000 { | |
| 303 | + compatible = "samsung,exynos4212-hdmi"; | |
| 304 | + }; | |
| 305 | + | |
| 306 | + mixer: mixer@12C10000 { | |
| 307 | + compatible = "samsung,exynos4212-mixer"; | |
| 308 | + clock-names = "mixer", "hdmi", "sclk_hdmi", "vp"; | |
| 309 | + clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | |
| 310 | + <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>; | |
| 311 | + }; | |
| 300 | 312 | }; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <dt-bindings/clock/exynos5250.h> |
| 21 | 21 | #include "exynos5.dtsi" |
| 22 | 22 | #include "exynos5250-pinctrl.dtsi" |
| 23 | − | |
| 23 | +#include "exynos4-cpu-thermal.dtsi" | |
| 24 | 24 | #include <dt-bindings/clock/exynos-audss-clk.h> |
| 25 | 25 | |
| 26 | 26 | / { |
| @@ -58,11 +58,14 @@ · 31 unmodified lines | ||
| 58 | 58 | #address-cells = <1>; |
| 59 | 59 | #size-cells = <0>; |
| 60 | 60 | |
| 61 | − cpu@0 { | |
| 61 | + cpu0: cpu@0 { | |
| 62 | 62 | device_type = "cpu"; |
| 63 | 63 | compatible = "arm,cortex-a15"; |
| 64 | 64 | reg = <0>; |
| 65 | 65 | clock-frequency = <1700000000>; |
| 66 | + cooling-min-level = <15>; | |
| 67 | + cooling-max-level = <9>; | |
| 68 | + #cooling-cells = <2>; /* min followed by max */ | |
| 66 | 69 | }; |
| 67 | 70 | cpu@1 { |
| 68 | 71 | device_type = "cpu"; |
| @@ -102,6 +105,12 @@ · 33 unmodified lines | ||
| 102 | 105 | #power-domain-cells = <0>; |
| 103 | 106 | }; |
| 104 | 107 | |
| 108 | + pd_disp1: disp1-power-domain@100440A0 { | |
| 109 | + compatible = "samsung,exynos4210-pd"; | |
| 110 | + reg = <0x100440A0 0x20>; | |
| 111 | + #power-domain-cells = <0>; | |
| 112 | + }; | |
| 113 | + | |
| 105 | 114 | clock: clock-controller@10010000 { |
| 106 | 115 | compatible = "samsung,exynos5250-clock"; |
| 107 | 116 | reg = <0x10010000 0x30000>; |
| @@ -235,12 +244,32 @@ · 127 unmodified lines | ||
| 235 | 244 | status = "disabled"; |
| 236 | 245 | }; |
| 237 | 246 | |
| 238 | − tmu@10060000 { | |
| 247 | + tmu: tmu@10060000 { | |
| 239 | 248 | compatible = "samsung,exynos5250-tmu"; |
| 240 | 249 | reg = <0x10060000 0x100>; |
| 241 | 250 | interrupts = <0 65 0>; |
| 242 | 251 | clocks = <&clock CLK_TMU>; |
| 243 | 252 | clock-names = "tmu_apbif"; |
| 253 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 254 | + }; | |
| 255 | + | |
| 256 | + thermal-zones { | |
| 257 | + cpu_thermal: cpu-thermal { | |
| 258 | + polling-delay-passive = <0>; | |
| 259 | + polling-delay = <0>; | |
| 260 | + thermal-sensors = <&tmu 0>; | |
| 261 | + | |
| 262 | + cooling-maps { | |
| 263 | + map0 { | |
| 264 | + /* Corresponds to 800MHz at freq_table */ | |
| 265 | + cooling-device = <&cpu0 9 9>; | |
| 266 | + }; | |
| 267 | + map1 { | |
| 268 | + /* Corresponds to 200MHz at freq_table */ | |
| 269 | + cooling-device = <&cpu0 15 15>; | |
| 270 | + }; | |
| 271 | + }; | |
| 272 | + }; | |
| 244 | 273 | }; |
| 245 | 274 | |
| 246 | 275 | serial@12C00000 { |
| @@ -719,6 +748,7 @@ · 472 unmodified lines | ||
| 719 | 748 | hdmi: hdmi { |
| 720 | 749 | compatible = "samsung,exynos4212-hdmi"; |
| 721 | 750 | reg = <0x14530000 0x70000>; |
| 751 | + power-domains = <&pd_disp1>; | |
| 722 | 752 | interrupts = <0 95 0>; |
| 723 | 753 | clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>, |
| 724 | 754 | <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>, |
| @@ -731,9 +761,11 @@ · 6 unmodified lines | ||
| 731 | 761 | mixer { |
| 732 | 762 | compatible = "samsung,exynos5250-mixer"; |
| 733 | 763 | reg = <0x14450000 0x10000>; |
| 764 | + power-domains = <&pd_disp1>; | |
| 734 | 765 | interrupts = <0 94 0>; |
| 735 | − clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>; | |
| 736 | − clock-names = "mixer", "sclk_hdmi"; | |
| 766 | + clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | |
| 767 | + <&clock CLK_SCLK_HDMI>; | |
| 768 | + clock-names = "mixer", "hdmi", "sclk_hdmi"; | |
| 737 | 769 | }; |
| 738 | 770 | |
| 739 | 771 | dp_phy: video-phy@10040720 { |
| @@ -743,6 +775,7 @@ · 3 unmodified lines | ||
| 743 | 775 | }; |
| 744 | 776 | |
| 745 | 777 | dp: dp-controller@145B0000 { |
| 778 | + power-domains = <&pd_disp1>; | |
| 746 | 779 | clocks = <&clock CLK_DP>; |
| 747 | 780 | clock-names = "dp"; |
| 748 | 781 | phys = <&dp_phy>; |
| @@ -750,6 +783,7 @@ · 1 unmodified line | ||
| 750 | 783 | }; |
| 751 | 784 | |
| 752 | 785 | fimd: fimd@14400000 { |
| 786 | + power-domains = <&pd_disp1>; | |
| 753 | 787 | clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>; |
| 754 | 788 | clock-names = "sclk_fimd", "fimd"; |
| 755 | 789 | }; |
| @@ -0,0 +1,35 @@ | ||
| 1 | +/* | |
| 2 | + * Device tree sources for default Exynos5420 thermal zone definition | |
| 3 | + * | |
| 4 | + * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License version 2 as | |
| 8 | + * published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +polling-delay-passive = <0>; | |
| 13 | +polling-delay = <0>; | |
| 14 | +trips { | |
| 15 | + cpu-alert-0 { | |
| 16 | + temperature = <85000>; /* millicelsius */ | |
| 17 | + hysteresis = <10000>; /* millicelsius */ | |
| 18 | + type = "active"; | |
| 19 | + }; | |
| 20 | + cpu-alert-1 { | |
| 21 | + temperature = <103000>; /* millicelsius */ | |
| 22 | + hysteresis = <10000>; /* millicelsius */ | |
| 23 | + type = "active"; | |
| 24 | + }; | |
| 25 | + cpu-alert-2 { | |
| 26 | + temperature = <110000>; /* millicelsius */ | |
| 27 | + hysteresis = <10000>; /* millicelsius */ | |
| 28 | + type = "active"; | |
| 29 | + }; | |
| 30 | + cpu-crit-0 { | |
| 31 | + temperature = <1200000>; /* millicelsius */ | |
| 32 | + hysteresis = <0>; /* millicelsius */ | |
| 33 | + type = "critical"; | |
| 34 | + }; | |
| 35 | +}; | |
| @@ -740,8 +740,9 @@ · 739 unmodified lines | ||
| 740 | 740 | compatible = "samsung,exynos5420-mixer"; |
| 741 | 741 | reg = <0x14450000 0x10000>; |
| 742 | 742 | interrupts = <0 94 0>; |
| 743 | − clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>; | |
| 744 | − clock-names = "mixer", "sclk_hdmi"; | |
| 743 | + clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>, | |
| 744 | + <&clock CLK_SCLK_HDMI>; | |
| 745 | + clock-names = "mixer", "hdmi", "sclk_hdmi"; | |
| 745 | 746 | power-domains = <&disp_pd>; |
| 746 | 747 | }; |
| 747 | 748 | |
| @@ -782,6 +783,7 @@ · 34 unmodified lines | ||
| 782 | 783 | interrupts = <0 65 0>; |
| 783 | 784 | clocks = <&clock CLK_TMU>; |
| 784 | 785 | clock-names = "tmu_apbif"; |
| 786 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 785 | 787 | }; |
| 786 | 788 | |
| 787 | 789 | tmu_cpu1: tmu@10064000 { |
| @@ -790,6 +792,7 @@ · 2 unmodified lines | ||
| 790 | 792 | interrupts = <0 183 0>; |
| 791 | 793 | clocks = <&clock CLK_TMU>; |
| 792 | 794 | clock-names = "tmu_apbif"; |
| 795 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 793 | 796 | }; |
| 794 | 797 | |
| 795 | 798 | tmu_cpu2: tmu@10068000 { |
| @@ -798,6 +801,7 @@ · 2 unmodified lines | ||
| 798 | 801 | interrupts = <0 184 0>; |
| 799 | 802 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU>; |
| 800 | 803 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 804 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 801 | 805 | }; |
| 802 | 806 | |
| 803 | 807 | tmu_cpu3: tmu@1006c000 { |
| @@ -806,6 +810,7 @@ · 2 unmodified lines | ||
| 806 | 810 | interrupts = <0 185 0>; |
| 807 | 811 | clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>; |
| 808 | 812 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 813 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 809 | 814 | }; |
| 810 | 815 | |
| 811 | 816 | tmu_gpu: tmu@100a0000 { |
| @@ -814,6 +819,30 @@ · 2 unmodified lines | ||
| 814 | 819 | interrupts = <0 215 0>; |
| 815 | 820 | clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>; |
| 816 | 821 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 822 | + #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 823 | + }; | |
| 824 | + | |
| 825 | + thermal-zones { | |
| 826 | + cpu0_thermal: cpu0-thermal { | |
| 827 | + thermal-sensors = <&tmu_cpu0>; | |
| 828 | + #include "exynos5420-trip-points.dtsi" | |
| 829 | + }; | |
| 830 | + cpu1_thermal: cpu1-thermal { | |
| 831 | + thermal-sensors = <&tmu_cpu1>; | |
| 832 | + #include "exynos5420-trip-points.dtsi" | |
| 833 | + }; | |
| 834 | + cpu2_thermal: cpu2-thermal { | |
| 835 | + thermal-sensors = <&tmu_cpu2>; | |
| 836 | + #include "exynos5420-trip-points.dtsi" | |
| 837 | + }; | |
| 838 | + cpu3_thermal: cpu3-thermal { | |
| 839 | + thermal-sensors = <&tmu_cpu3>; | |
| 840 | + #include "exynos5420-trip-points.dtsi" | |
| 841 | + }; | |
| 842 | + gpu_thermal: gpu-thermal { | |
| 843 | + thermal-sensors = <&tmu_gpu>; | |
| 844 | + #include "exynos5420-trip-points.dtsi" | |
| 845 | + }; | |
| 817 | 846 | }; |
| 818 | 847 | |
| 819 | 848 | watchdog: watchdog@101D0000 { |
| @@ -0,0 +1,24 @@ | ||
| 1 | +/* | |
| 2 | + * Device tree sources for Exynos5440 TMU sensor configuration | |
| 3 | + * | |
| 4 | + * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License version 2 as | |
| 8 | + * published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <dt-bindings/thermal/thermal_exynos.h> | |
| 13 | + | |
| 14 | +#thermal-sensor-cells = <0>; | |
| 15 | +samsung,tmu_gain = <5>; | |
| 16 | +samsung,tmu_reference_voltage = <16>; | |
| 17 | +samsung,tmu_noise_cancel_mode = <4>; | |
| 18 | +samsung,tmu_efuse_value = <0x5d2d>; | |
| 19 | +samsung,tmu_min_efuse_value = <16>; | |
| 20 | +samsung,tmu_max_efuse_value = <76>; | |
| 21 | +samsung,tmu_first_point_trim = <25>; | |
| 22 | +samsung,tmu_second_point_trim = <70>; | |
| 23 | +samsung,tmu_default_temp_offset = <25>; | |
| 24 | +samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>; | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +/* | |
| 2 | + * Device tree sources for default Exynos5440 thermal zone definition | |
| 3 | + * | |
| 4 | + * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License version 2 as | |
| 8 | + * published by the Free Software Foundation. | |
| 9 | + * | |
| 10 | + */ | |
| 11 | + | |
| 12 | +polling-delay-passive = <0>; | |
| 13 | +polling-delay = <0>; | |
| 14 | +trips { | |
| 15 | + cpu-alert-0 { | |
| 16 | + temperature = <100000>; /* millicelsius */ | |
| 17 | + hysteresis = <0>; /* millicelsius */ | |
| 18 | + type = "active"; | |
| 19 | + }; | |
| 20 | + cpu-crit-0 { | |
| 21 | + temperature = <1050000>; /* millicelsius */ | |
| 22 | + hysteresis = <0>; /* millicelsius */ | |
| 23 | + type = "critical"; | |
| 24 | + }; | |
| 25 | +}; | |
| @@ -219,6 +219,7 @@ · 218 unmodified lines | ||
| 219 | 219 | interrupts = <0 58 0>; |
| 220 | 220 | clocks = <&clock CLK_B_125>; |
| 221 | 221 | clock-names = "tmu_apbif"; |
| 222 | + #include "exynos5440-tmu-sensor-conf.dtsi" | |
| 222 | 223 | }; |
| 223 | 224 | |
| 224 | 225 | tmuctrl_1: tmuctrl@16011C { |
| @@ -227,6 +228,7 @@ · 2 unmodified lines | ||
| 227 | 228 | interrupts = <0 58 0>; |
| 228 | 229 | clocks = <&clock CLK_B_125>; |
| 229 | 230 | clock-names = "tmu_apbif"; |
| 231 | + #include "exynos5440-tmu-sensor-conf.dtsi" | |
| 230 | 232 | }; |
| 231 | 233 | |
| 232 | 234 | tmuctrl_2: tmuctrl@160120 { |
| @@ -235,6 +237,22 @@ · 2 unmodified lines | ||
| 235 | 237 | interrupts = <0 58 0>; |
| 236 | 238 | clocks = <&clock CLK_B_125>; |
| 237 | 239 | clock-names = "tmu_apbif"; |
| 240 | + #include "exynos5440-tmu-sensor-conf.dtsi" | |
| 241 | + }; | |
| 242 | + | |
| 243 | + thermal-zones { | |
| 244 | + cpu0_thermal: cpu0-thermal { | |
| 245 | + thermal-sensors = <&tmuctrl_0>; | |
| 246 | + #include "exynos5440-trip-points.dtsi" | |
| 247 | + }; | |
| 248 | + cpu1_thermal: cpu1-thermal { | |
| 249 | + thermal-sensors = <&tmuctrl_1>; | |
| 250 | + #include "exynos5440-trip-points.dtsi" | |
| 251 | + }; | |
| 252 | + cpu2_thermal: cpu2-thermal { | |
| 253 | + thermal-sensors = <&tmuctrl_2>; | |
| 254 | + #include "exynos5440-trip-points.dtsi" | |
| 255 | + }; | |
| 238 | 256 | }; |
| 239 | 257 | |
| 240 | 258 | sata@210000 { |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | regulator-max-microvolt = <5000000>; |
| 36 | 36 | gpio = <&gpio3 22 0>; |
| 37 | 37 | enable-active-high; |
| 38 | + vin-supply = <&swbst_reg>; | |
| 38 | 39 | }; |
| 39 | 40 | |
| 40 | 41 | reg_usb_h1_vbus: regulator@1 { |
| @@ -45,6 +46,7 @@ · 4 unmodified lines | ||
| 45 | 46 | regulator-max-microvolt = <5000000>; |
| 46 | 47 | gpio = <&gpio1 29 0>; |
| 47 | 48 | enable-active-high; |
| 49 | + vin-supply = <&swbst_reg>; | |
| 48 | 50 | }; |
| 49 | 51 | |
| 50 | 52 | reg_audio: regulator@2 { |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | regulator-max-microvolt = <5000000>; |
| 53 | 53 | gpio = <&gpio4 0 0>; |
| 54 | 54 | enable-active-high; |
| 55 | + vin-supply = <&swbst_reg>; | |
| 55 | 56 | }; |
| 56 | 57 | |
| 57 | 58 | reg_usb_otg2_vbus: regulator@1 { |
| @@ -62,6 +63,7 @@ · 4 unmodified lines | ||
| 62 | 63 | regulator-max-microvolt = <5000000>; |
| 63 | 64 | gpio = <&gpio4 2 0>; |
| 64 | 65 | enable-active-high; |
| 66 | + vin-supply = <&swbst_reg>; | |
| 65 | 67 | }; |
| 66 | 68 | |
| 67 | 69 | reg_aud3v: regulator@2 { |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | core_thermal: core_thermal { |
| 15 | 15 | polling-delay-passive = <250>; /* milliseconds */ |
| 16 | − polling-delay = <1000>; /* milliseconds */ | |
| 16 | + polling-delay = <500>; /* milliseconds */ | |
| 17 | 17 | |
| 18 | 18 | /* sensor ID */ |
| 19 | 19 | thermal-sensors = <&bandgap 2>; |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | gpu_thermal: gpu_thermal { |
| 15 | 15 | polling-delay-passive = <250>; /* milliseconds */ |
| 16 | − polling-delay = <1000>; /* milliseconds */ | |
| 16 | + polling-delay = <500>; /* milliseconds */ | |
| 17 | 17 | |
| 18 | 18 | /* sensor ID */ |
| 19 | 19 | thermal-sensors = <&bandgap 1>; |
| @@ -1079,4 +1079,8 @@ · 1078 unmodified lines | ||
| 1079 | 1079 | }; |
| 1080 | 1080 | }; |
| 1081 | 1081 | |
| 1082 | +&cpu_thermal { | |
| 1083 | + polling-delay = <500>; /* milliseconds */ | |
| 1084 | +}; | |
| 1085 | + | |
| 1082 | 1086 | /include/ "omap54xx-clocks.dtsi" |
| @@ -167,10 +167,18 @@ · 166 unmodified lines | ||
| 167 | 167 | ti,index-starts-at-one; |
| 168 | 168 | }; |
| 169 | 169 | |
| 170 | + dpll_core_byp_mux: dpll_core_byp_mux { | |
| 171 | + #clock-cells = <0>; | |
| 172 | + compatible = "ti,mux-clock"; | |
| 173 | + clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; | |
| 174 | + ti,bit-shift = <23>; | |
| 175 | + reg = <0x012c>; | |
| 176 | + }; | |
| 177 | + | |
| 170 | 178 | dpll_core_ck: dpll_core_ck { |
| 171 | 179 | #clock-cells = <0>; |
| 172 | 180 | compatible = "ti,omap4-dpll-core-clock"; |
| 173 | − clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>; | |
| 181 | + clocks = <&sys_clkin>, <&dpll_core_byp_mux>; | |
| 174 | 182 | reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; |
| 175 | 183 | }; |
| 176 | 184 | |
| @@ -294,10 +302,18 @@ · 117 unmodified lines | ||
| 294 | 302 | clock-div = <1>; |
| 295 | 303 | }; |
| 296 | 304 | |
| 305 | + dpll_iva_byp_mux: dpll_iva_byp_mux { | |
| 306 | + #clock-cells = <0>; | |
| 307 | + compatible = "ti,mux-clock"; | |
| 308 | + clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; | |
| 309 | + ti,bit-shift = <23>; | |
| 310 | + reg = <0x01ac>; | |
| 311 | + }; | |
| 312 | + | |
| 297 | 313 | dpll_iva_ck: dpll_iva_ck { |
| 298 | 314 | #clock-cells = <0>; |
| 299 | 315 | compatible = "ti,omap4-dpll-clock"; |
| 300 | − clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>; | |
| 316 | + clocks = <&sys_clkin>, <&dpll_iva_byp_mux>; | |
| 301 | 317 | reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; |
| 302 | 318 | }; |
| 303 | 319 | |
| @@ -599,10 +615,19 @@ · 295 unmodified lines | ||
| 599 | 615 | }; |
| 600 | 616 | }; |
| 601 | 617 | &cm_core_clocks { |
| 618 | + | |
| 619 | + dpll_per_byp_mux: dpll_per_byp_mux { | |
| 620 | + #clock-cells = <0>; | |
| 621 | + compatible = "ti,mux-clock"; | |
| 622 | + clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; | |
| 623 | + ti,bit-shift = <23>; | |
| 624 | + reg = <0x014c>; | |
| 625 | + }; | |
| 626 | + | |
| 602 | 627 | dpll_per_ck: dpll_per_ck { |
| 603 | 628 | #clock-cells = <0>; |
| 604 | 629 | compatible = "ti,omap4-dpll-clock"; |
| 605 | − clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>; | |
| 630 | + clocks = <&sys_clkin>, <&dpll_per_byp_mux>; | |
| 606 | 631 | reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; |
| 607 | 632 | }; |
| 608 | 633 | |
| @@ -714,10 +739,18 @@ · 105 unmodified lines | ||
| 714 | 739 | ti,index-starts-at-one; |
| 715 | 740 | }; |
| 716 | 741 | |
| 742 | + dpll_usb_byp_mux: dpll_usb_byp_mux { | |
| 743 | + #clock-cells = <0>; | |
| 744 | + compatible = "ti,mux-clock"; | |
| 745 | + clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; | |
| 746 | + ti,bit-shift = <23>; | |
| 747 | + reg = <0x018c>; | |
| 748 | + }; | |
| 749 | + | |
| 717 | 750 | dpll_usb_ck: dpll_usb_ck { |
| 718 | 751 | #clock-cells = <0>; |
| 719 | 752 | compatible = "ti,omap4-dpll-j-type-clock"; |
| 720 | − clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>; | |
| 753 | + clocks = <&sys_clkin>, <&dpll_usb_byp_mux>; | |
| 721 | 754 | reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; |
| 722 | 755 | }; |
| 723 | 756 | |
| @@ -1248,7 +1248,6 @@ · 1247 unmodified lines | ||
| 1248 | 1248 | atmel,watchdog-type = "hardware"; |
| 1249 | 1249 | atmel,reset-type = "all"; |
| 1250 | 1250 | atmel,dbg-halt; |
| 1251 | − atmel,idle-halt; | |
| 1252 | 1251 | status = "disabled"; |
| 1253 | 1252 | }; |
| 1254 | 1253 | |
| @@ -1416,7 +1415,7 @@ · 161 unmodified lines | ||
| 1416 | 1415 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
| 1417 | 1416 | reg = <0x00700000 0x100000>; |
| 1418 | 1417 | interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; |
| 1419 | − clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | |
| 1418 | + clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; | |
| 1420 | 1419 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
| 1421 | 1420 | status = "disabled"; |
| 1422 | 1421 | }; |
| @@ -66,6 +66,7 @@ · 65 unmodified lines | ||
| 66 | 66 | gpio4 = &pioE; |
| 67 | 67 | tcb0 = &tcb0; |
| 68 | 68 | tcb1 = &tcb1; |
| 69 | + i2c0 = &i2c0; | |
| 69 | 70 | i2c2 = &i2c2; |
| 70 | 71 | }; |
| 71 | 72 | cpus { |
| @@ -259,7 +260,7 @@ · 187 unmodified lines | ||
| 259 | 260 | compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; |
| 260 | 261 | reg = <0x00600000 0x100000>; |
| 261 | 262 | interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>; |
| 262 | − clocks = <&usb>, <&uhphs_clk>, <&uhpck>; | |
| 263 | + clocks = <&utmi>, <&uhphs_clk>, <&uhpck>; | |
| 263 | 264 | clock-names = "usb_clk", "ehci_clk", "uhpck"; |
| 264 | 265 | status = "disabled"; |
| 265 | 266 | }; |
| @@ -461,8 +462,8 @@ · 195 unmodified lines | ||
| 461 | 462 | |
| 462 | 463 | lcdck: lcdck { |
| 463 | 464 | #clock-cells = <0>; |
| 464 | − reg = <4>; | |
| 465 | − clocks = <&smd>; | |
| 465 | + reg = <3>; | |
| 466 | + clocks = <&mck>; | |
| 466 | 467 | }; |
| 467 | 468 | |
| 468 | 469 | smdck: smdck { |
| @@ -770,7 +771,7 @@ · 301 unmodified lines | ||
| 770 | 771 | reg = <50>; |
| 771 | 772 | }; |
| 772 | 773 | |
| 773 | − lcd_clk: lcd_clk { | |
| 774 | + lcdc_clk: lcdc_clk { | |
| 774 | 775 | #clock-cells = <0>; |
| 775 | 776 | reg = <51>; |
| 776 | 777 | }; |
| @@ -713,6 +713,9 @@ · 712 unmodified lines | ||
| 713 | 713 | reg-shift = <2>; |
| 714 | 714 | reg-io-width = <4>; |
| 715 | 715 | clocks = <&l4_sp_clk>; |
| 716 | + dmas = <&pdma 28>, | |
| 717 | + <&pdma 29>; | |
| 718 | + dma-names = "tx", "rx"; | |
| 716 | 719 | }; |
| 717 | 720 | |
| 718 | 721 | uart1: serial1@ffc03000 { |
| @@ -722,6 +725,9 @@ · 3 unmodified lines | ||
| 722 | 725 | reg-shift = <2>; |
| 723 | 726 | reg-io-width = <4>; |
| 724 | 727 | clocks = <&l4_sp_clk>; |
| 728 | + dmas = <&pdma 30>, | |
| 729 | + <&pdma 31>; | |
| 730 | + dma-names = "tx", "rx"; | |
| 725 | 731 | }; |
| 726 | 732 | |
| 727 | 733 | rst: rstmgr@ffd05000 { |
| @@ -70,6 +70,7 @@ CONFIG_SCSI=y · 69 unmodified lines | ||
| 70 | 70 | CONFIG_BLK_DEV_SD=y |
| 71 | 71 | # CONFIG_SCSI_LOWLEVEL is not set |
| 72 | 72 | CONFIG_NETDEVICES=y |
| 73 | +CONFIG_ARM_AT91_ETHER=y | |
| 73 | 74 | CONFIG_MACB=y |
| 74 | 75 | # CONFIG_NET_VENDOR_BROADCOM is not set |
| 75 | 76 | CONFIG_DM9000=y |
| @@ -99,7 +99,7 @@ CONFIG_PCI_RCAR_GEN2=y · 98 unmodified lines | ||
| 99 | 99 | CONFIG_PCI_RCAR_GEN2_PCIE=y |
| 100 | 100 | CONFIG_PCIEPORTBUS=y |
| 101 | 101 | CONFIG_SMP=y |
| 102 | −CONFIG_NR_CPUS=8 | |
| 102 | +CONFIG_NR_CPUS=16 | |
| 103 | 103 | CONFIG_HIGHPTE=y |
| 104 | 104 | CONFIG_CMA=y |
| 105 | 105 | CONFIG_ARM_APPENDED_DTB=y |
| @@ -377,6 +377,7 @@ CONFIG_PWM_TWL=m · 376 unmodified lines | ||
| 377 | 377 | CONFIG_PWM_TWL_LED=m |
| 378 | 378 | CONFIG_OMAP_USB2=m |
| 379 | 379 | CONFIG_TI_PIPE3=y |
| 380 | +CONFIG_TWL4030_USB=m | |
| 380 | 381 | CONFIG_EXT2_FS=y |
| 381 | 382 | CONFIG_EXT3_FS=y |
| 382 | 383 | # CONFIG_EXT3_FS_XATTR is not set |
| @@ -3,8 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | CONFIG_SYSVIPC=y |
| 4 | 4 | CONFIG_IRQ_DOMAIN_DEBUG=y |
| 5 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
| 6 | −CONFIG_SYSFS_DEPRECATED=y | |
| 7 | −CONFIG_SYSFS_DEPRECATED_V2=y | |
| 8 | 6 | CONFIG_BLK_DEV_INITRD=y |
| 9 | 7 | CONFIG_EMBEDDED=y |
| 10 | 8 | CONFIG_SLAB=y |
| @@ -4,6 +4,7 @@ CONFIG_BLK_DEV_INITRD=y · 3 unmodified lines | ||
| 4 | 4 | CONFIG_PERF_EVENTS=y |
| 5 | 5 | CONFIG_ARCH_SUNXI=y |
| 6 | 6 | CONFIG_SMP=y |
| 7 | +CONFIG_NR_CPUS=8 | |
| 7 | 8 | CONFIG_AEABI=y |
| 8 | 9 | CONFIG_HIGHMEM=y |
| 9 | 10 | CONFIG_HIGHPTE=y |
| @@ -118,8 +118,8 @@ CONFIG_HID_ZEROPLUS=y · 117 unmodified lines | ||
| 118 | 118 | CONFIG_USB=y |
| 119 | 119 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
| 120 | 120 | CONFIG_USB_MON=y |
| 121 | −CONFIG_USB_ISP1760_HCD=y | |
| 122 | 121 | CONFIG_USB_STORAGE=y |
| 122 | +CONFIG_USB_ISP1760=y | |
| 123 | 123 | CONFIG_MMC=y |
| 124 | 124 | CONFIG_MMC_ARMMMCI=y |
| 125 | 125 | CONFIG_NEW_LEDS=y |
| @@ -58,14 +58,18 @@ · 57 unmodified lines | ||
| 58 | 58 | # define VFP_ABI_FRAME 0 |
| 59 | 59 | # define BSAES_ASM_EXTENDED_KEY |
| 60 | 60 | # define XTS_CHAIN_TWEAK |
| 61 | −# define __ARM_ARCH__ 7 | |
| 61 | +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ | |
| 62 | +# define __ARM_MAX_ARCH__ 7 | |
| 62 | 63 | #endif |
| 63 | 64 | |
| 64 | 65 | #ifdef __thumb__ |
| 65 | 66 | # define adrl adr |
| 66 | 67 | #endif |
| 67 | 68 | |
| 68 | −#if __ARM_ARCH__>=7 | |
| 69 | +#if __ARM_MAX_ARCH__>=7 | |
| 70 | +.arch armv7-a | |
| 71 | +.fpu neon | |
| 72 | + | |
| 69 | 73 | .text |
| 70 | 74 | .syntax unified @ ARMv7-capable assembler is expected to handle this |
| 71 | 75 | #ifdef __thumb2__ |
| @@ -74,8 +78,6 @@ · 2 unmodified lines | ||
| 74 | 78 | .code 32 |
| 75 | 79 | #endif |
| 76 | 80 | |
| 77 | −.fpu neon | |
| 78 | − | |
| 79 | 81 | .type _bsaes_decrypt8,%function |
| 80 | 82 | .align 4 |
| 81 | 83 | _bsaes_decrypt8: |
| @@ -2095,9 +2097,11 @@ bsaes_xts_decrypt: · 2013 unmodified lines | ||
| 2095 | 2097 | vld1.8 {q8}, [r0] @ initial tweak |
| 2096 | 2098 | adr r2, .Lxts_magic |
| 2097 | 2099 | |
| 2100 | +#ifndef XTS_CHAIN_TWEAK | |
| 2098 | 2101 | tst r9, #0xf @ if not multiple of 16 |
| 2099 | 2102 | it ne @ Thumb2 thing, sanity check in ARM |
| 2100 | 2103 | subne r9, #0x10 @ subtract another 16 bytes |
| 2104 | +#endif | |
| 2101 | 2105 | subs r9, #0x80 |
| 2102 | 2106 | |
| 2103 | 2107 | blo .Lxts_dec_short |
| @@ -701,14 +701,18 @@ $code.=<<___; · 700 unmodified lines | ||
| 701 | 701 | # define VFP_ABI_FRAME 0 |
| 702 | 702 | # define BSAES_ASM_EXTENDED_KEY |
| 703 | 703 | # define XTS_CHAIN_TWEAK |
| 704 | −# define __ARM_ARCH__ 7 | |
| 704 | +# define __ARM_ARCH__ __LINUX_ARM_ARCH__ | |
| 705 | +# define __ARM_MAX_ARCH__ 7 | |
| 705 | 706 | #endif |
| 706 | 707 | |
| 707 | 708 | #ifdef __thumb__ |
| 708 | 709 | # define adrl adr |
| 709 | 710 | #endif |
| 710 | 711 | |
| 711 | −#if __ARM_ARCH__>=7 | |
| 712 | +#if __ARM_MAX_ARCH__>=7 | |
| 713 | +.arch armv7-a | |
| 714 | +.fpu neon | |
| 715 | + | |
| 712 | 716 | .text |
| 713 | 717 | .syntax unified @ ARMv7-capable assembler is expected to handle this |
| 714 | 718 | #ifdef __thumb2__ |
| @@ -717,8 +721,6 @@ $code.=<<___; · 2 unmodified lines | ||
| 717 | 721 | .code 32 |
| 718 | 722 | #endif |
| 719 | 723 | |
| 720 | −.fpu neon | |
| 721 | − | |
| 722 | 724 | .type _bsaes_decrypt8,%function |
| 723 | 725 | .align 4 |
| 724 | 726 | _bsaes_decrypt8: |
| @@ -2076,9 +2078,11 @@ bsaes_xts_decrypt: · 1351 unmodified lines | ||
| 2076 | 2078 | vld1.8 {@XMM[8]}, [r0] @ initial tweak |
| 2077 | 2079 | adr $magic, .Lxts_magic |
| 2078 | 2080 | |
| 2081 | +#ifndef XTS_CHAIN_TWEAK | |
| 2079 | 2082 | tst $len, #0xf @ if not multiple of 16 |
| 2080 | 2083 | it ne @ Thumb2 thing, sanity check in ARM |
| 2081 | 2084 | subne $len, #0x10 @ subtract another 16 bytes |
| 2085 | +#endif | |
| 2082 | 2086 | subs $len, #0x80 |
| 2083 | 2087 | |
| 2084 | 2088 | blo .Lxts_dec_short |
| @@ -149,29 +149,28 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) · 148 unmodified lines | ||
| 149 | 149 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ |
| 150 | 150 | }) |
| 151 | 151 | |
| 152 | +#define kvm_pgd_index(addr) pgd_index(addr) | |
| 153 | + | |
| 152 | 154 | static inline bool kvm_page_empty(void *ptr) |
| 153 | 155 | { |
| 154 | 156 | struct page *ptr_page = virt_to_page(ptr); |
| 155 | 157 | return page_count(ptr_page) == 1; |
| 156 | 158 | } |
| 157 | 159 | |
| 158 | − | |
| 159 | 160 | #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep) |
| 160 | 161 | #define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp) |
| 161 | 162 | #define kvm_pud_table_empty(kvm, pudp) (0) |
| 162 | 163 | |
| 163 | 164 | #define KVM_PREALLOC_LEVEL 0 |
| 164 | 165 | |
| 165 | −static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | |
| 166 | +static inline void *kvm_get_hwpgd(struct kvm *kvm) | |
| 166 | 167 | { |
| 167 | − return 0; | |
| 168 | + return kvm->arch.pgd; | |
| 168 | 169 | } |
| 169 | 170 | |
| 170 | −static inline void kvm_free_hwpgd(struct kvm *kvm) { } | |
| 171 | − | |
| 172 | −static inline void *kvm_get_hwpgd(struct kvm *kvm) | |
| 171 | +static inline unsigned int kvm_get_hwpgd_size(void) | |
| 173 | 172 | { |
| 174 | − return kvm->arch.pgd; | |
| 173 | + return PTRS_PER_S2_PGD * sizeof(pgd_t); | |
| 175 | 174 | } |
| 176 | 175 | |
| 177 | 176 | struct kvm; |
| @@ -18,8 +18,11 @@ · 17 unmodified lines | ||
| 18 | 18 | #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | −/* Keep in sync with mach-at91/include/mach/hardware.h */ | |
| 21 | +#ifdef CONFIG_MMU | |
| 22 | 22 | #define AT91_IO_P2V(x) ((x) - 0x01000000) |
| 23 | +#else | |
| 24 | +#define AT91_IO_P2V(x) (x) | |
| 25 | +#endif | |
| 23 | 26 | |
| 24 | 27 | #define AT91_DBGU_SR (0x14) /* Status Register */ |
| 25 | 28 | #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ |
| @@ -246,12 +246,9 @@ static int __get_cpu_architecture(void) · 245 unmodified lines | ||
| 246 | 246 | if (cpu_arch) |
| 247 | 247 | cpu_arch += CPU_ARCH_ARMv3; |
| 248 | 248 | } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { |
| 249 | − unsigned int mmfr0; | |
| 250 | − | |
| 251 | 249 | /* Revised CPUID format. Read the Memory Model Feature |
| 252 | 250 | * Register 0 and check for VMSAv7 or PMSAv7 */ |
| 253 | − asm("mrc p15, 0, %0, c0, c1, 4" | |
| 254 | − : "=r" (mmfr0)); | |
| 251 | + unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0); | |
| 255 | 252 | if ((mmfr0 & 0x0000000f) >= 0x00000003 || |
| 256 | 253 | (mmfr0 & 0x000000f0) >= 0x00000030) |
| 257 | 254 | cpu_arch = CPU_ARCH_ARMv7; |
| @@ -290,7 +290,7 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, · 289 unmodified lines | ||
| 290 | 290 | phys_addr_t addr = start, end = start + size; |
| 291 | 291 | phys_addr_t next; |
| 292 | 292 | |
| 293 | − pgd = pgdp + pgd_index(addr); | |
| 293 | + pgd = pgdp + kvm_pgd_index(addr); | |
| 294 | 294 | do { |
| 295 | 295 | next = kvm_pgd_addr_end(addr, end); |
| 296 | 296 | if (!pgd_none(*pgd)) |
| @@ -355,7 +355,7 @@ static void stage2_flush_memslot(struct kvm *kvm, · 58 unmodified lines | ||
| 355 | 355 | phys_addr_t next; |
| 356 | 356 | pgd_t *pgd; |
| 357 | 357 | |
| 358 | − pgd = kvm->arch.pgd + pgd_index(addr); | |
| 358 | + pgd = kvm->arch.pgd + kvm_pgd_index(addr); | |
| 359 | 359 | do { |
| 360 | 360 | next = kvm_pgd_addr_end(addr, end); |
| 361 | 361 | stage2_flush_puds(kvm, pgd, addr, next); |
| @@ -632,6 +632,20 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) · 270 unmodified lines | ||
| 632 | 632 | __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE); |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | +/* Free the HW pgd, one page at a time */ | |
| 636 | +static void kvm_free_hwpgd(void *hwpgd) | |
| 637 | +{ | |
| 638 | + free_pages_exact(hwpgd, kvm_get_hwpgd_size()); | |
| 639 | +} | |
| 640 | + | |
| 641 | +/* Allocate the HW PGD, making sure that each page gets its own refcount */ | |
| 642 | +static void *kvm_alloc_hwpgd(void) | |
| 643 | +{ | |
| 644 | + unsigned int size = kvm_get_hwpgd_size(); | |
| 645 | + | |
| 646 | + return alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); | |
| 647 | +} | |
| 648 | + | |
| 635 | 649 | /** |
| 636 | 650 | * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation. |
| 637 | 651 | * @kvm: The KVM struct pointer for the VM. |
| @@ -645,15 +659,31 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) · 7 unmodified lines | ||
| 645 | 659 | */ |
| 646 | 660 | int kvm_alloc_stage2_pgd(struct kvm *kvm) |
| 647 | 661 | { |
| 648 | − int ret; | |
| 649 | 662 | pgd_t *pgd; |
| 663 | + void *hwpgd; | |
| 650 | 664 | |
| 651 | 665 | if (kvm->arch.pgd != NULL) { |
| 652 | 666 | kvm_err("kvm_arch already initialized?\n"); |
| 653 | 667 | return -EINVAL; |
| 654 | 668 | } |
| 655 | 669 | |
| 670 | + hwpgd = kvm_alloc_hwpgd(); | |
| 671 | + if (!hwpgd) | |
| 672 | + return -ENOMEM; | |
| 673 | + | |
| 674 | + /* When the kernel uses more levels of page tables than the | |
| 675 | + * guest, we allocate a fake PGD and pre-populate it to point | |
| 676 | + * to the next-level page table, which will be the real | |
| 677 | + * initial page table pointed to by the VTTBR. | |
| 678 | + * | |
| 679 | + * When KVM_PREALLOC_LEVEL==2, we allocate a single page for | |
| 680 | + * the PMD and the kernel will use folded pud. | |
| 681 | + * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD | |
| 682 | + * pages. | |
| 683 | + */ | |
| 656 | 684 | if (KVM_PREALLOC_LEVEL > 0) { |
| 685 | + int i; | |
| 686 | + | |
| 657 | 687 | /* |
| 658 | 688 | * Allocate fake pgd for the page table manipulation macros to |
| 659 | 689 | * work. This is not used by the hardware and we have no |
| @@ -661,30 +691,32 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) · 1 unmodified line | ||
| 661 | 691 | */ |
| 662 | 692 | pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), |
| 663 | 693 | GFP_KERNEL | __GFP_ZERO); |
| 694 | + | |
| 695 | + if (!pgd) { | |
| 696 | + kvm_free_hwpgd(hwpgd); | |
| 697 | + return -ENOMEM; | |
| 698 | + } | |
| 699 | + | |
| 700 | + /* Plug the HW PGD into the fake one. */ | |
| 701 | + for (i = 0; i < PTRS_PER_S2_PGD; i++) { | |
| 702 | + if (KVM_PREALLOC_LEVEL == 1) | |
| 703 | + pgd_populate(NULL, pgd + i, | |
| 704 | + (pud_t *)hwpgd + i * PTRS_PER_PUD); | |
| 705 | + else if (KVM_PREALLOC_LEVEL == 2) | |
| 706 | + pud_populate(NULL, pud_offset(pgd, 0) + i, | |
| 707 | + (pmd_t *)hwpgd + i * PTRS_PER_PMD); | |
| 708 | + } | |
| 664 | 709 | } else { |
| 665 | 710 | /* |
| 666 | 711 | * Allocate actual first-level Stage-2 page table used by the |
| 667 | 712 | * hardware for Stage-2 page table walks. |
| 668 | 713 | */ |
| 669 | − pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, S2_PGD_ORDER); | |
| 714 | + pgd = (pgd_t *)hwpgd; | |
| 670 | 715 | } |
| 671 | 716 | |
| 672 | − if (!pgd) | |
| 673 | − return -ENOMEM; | |
| 674 | − | |
| 675 | − ret = kvm_prealloc_hwpgd(kvm, pgd); | |
| 676 | − if (ret) | |
| 677 | − goto out_err; | |
| 678 | − | |
| 679 | 717 | kvm_clean_pgd(pgd); |
| 680 | 718 | kvm->arch.pgd = pgd; |
| 681 | 719 | return 0; |
| 682 | −out_err: | |
| 683 | − if (KVM_PREALLOC_LEVEL > 0) | |
| 684 | − kfree(pgd); | |
| 685 | − else | |
| 686 | − free_pages((unsigned long)pgd, S2_PGD_ORDER); | |
| 687 | − return ret; | |
| 688 | 720 | } |
| 689 | 721 | |
| 690 | 722 | /** |
| @@ -785,11 +817,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) · 94 unmodified lines | ||
| 785 | 817 | return; |
| 786 | 818 | |
| 787 | 819 | unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); |
| 788 | − kvm_free_hwpgd(kvm); | |
| 820 | + kvm_free_hwpgd(kvm_get_hwpgd(kvm)); | |
| 789 | 821 | if (KVM_PREALLOC_LEVEL > 0) |
| 790 | 822 | kfree(kvm->arch.pgd); |
| 791 | − else | |
| 792 | − free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER); | |
| 823 | + | |
| 793 | 824 | kvm->arch.pgd = NULL; |
| 794 | 825 | } |
| 795 | 826 | |
| @@ -799,7 +830,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache · 3 unmodified lines | ||
| 799 | 830 | pgd_t *pgd; |
| 800 | 831 | pud_t *pud; |
| 801 | 832 | |
| 802 | − pgd = kvm->arch.pgd + pgd_index(addr); | |
| 833 | + pgd = kvm->arch.pgd + kvm_pgd_index(addr); | |
| 803 | 834 | if (WARN_ON(pgd_none(*pgd))) { |
| 804 | 835 | if (!cache) |
| 805 | 836 | return NULL; |
| @@ -1089,7 +1120,7 @@ static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end) · 283 unmodified lines | ||
| 1089 | 1120 | pgd_t *pgd; |
| 1090 | 1121 | phys_addr_t next; |
| 1091 | 1122 | |
| 1092 | − pgd = kvm->arch.pgd + pgd_index(addr); | |
| 1123 | + pgd = kvm->arch.pgd + kvm_pgd_index(addr); | |
| 1093 | 1124 | do { |
| 1094 | 1125 | /* |
| 1095 | 1126 | * Release kvm_mmu_lock periodically if the memory region is |
| @@ -270,37 +270,35 @@ static void __init at91_pm_sram_init(void) · 269 unmodified lines | ||
| 270 | 270 | phys_addr_t sram_pbase; |
| 271 | 271 | unsigned long sram_base; |
| 272 | 272 | struct device_node *node; |
| 273 | − struct platform_device *pdev; | |
| 273 | + struct platform_device *pdev = NULL; | |
| 274 | 274 | |
| 275 | − node = of_find_compatible_node(NULL, NULL, "mmio-sram"); | |
| 276 | − if (!node) { | |
| 277 | − pr_warn("%s: failed to find sram node!\n", __func__); | |
| 278 | − return; | |
| 275 | + for_each_compatible_node(node, NULL, "mmio-sram") { | |
| 276 | + pdev = of_find_device_by_node(node); | |
| 277 | + if (pdev) { | |
| 278 | + of_node_put(node); | |
| 279 | + break; | |
| 280 | + } | |
| 279 | 281 | } |
| 280 | 282 | |
| 281 | − pdev = of_find_device_by_node(node); | |
| 282 | 283 | if (!pdev) { |
| 283 | 284 | pr_warn("%s: failed to find sram device!\n", __func__); |
| 284 | − goto put_node; | |
| 285 | + return; | |
| 285 | 286 | } |
| 286 | 287 | |
| 287 | 288 | sram_pool = dev_get_gen_pool(&pdev->dev); |
| 288 | 289 | if (!sram_pool) { |
| 289 | 290 | pr_warn("%s: sram pool unavailable!\n", __func__); |
| 290 | − goto put_node; | |
| 291 | + return; | |
| 291 | 292 | } |
| 292 | 293 | |
| 293 | 294 | sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz); |
| 294 | 295 | if (!sram_base) { |
| 295 | 296 | pr_warn("%s: unable to alloc ocram!\n", __func__); |
| 296 | − goto put_node; | |
| 297 | + return; | |
| 297 | 298 | } |
| 298 | 299 | |
| 299 | 300 | sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); |
| 300 | 301 | slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false); |
| 301 | − | |
| 302 | −put_node: | |
| 303 | − of_node_put(node); | |
| 304 | 302 | } |
| 305 | 303 | #endif |
| 306 | 304 | |
| @@ -44,7 +44,7 @@ static inline void at91rm9200_standby(void) · 43 unmodified lines | ||
| 44 | 44 | " mcr p15, 0, %0, c7, c0, 4\n\t" |
| 45 | 45 | " str %5, [%1, %2]" |
| 46 | 46 | : |
| 47 | − : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR), | |
| 47 | + : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR), | |
| 48 | 48 | "r" (1), "r" (AT91RM9200_SDRAMC_SRR), |
| 49 | 49 | "r" (lpr)); |
| 50 | 50 | } |
| @@ -25,11 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | */ |
| 26 | 26 | #undef SLOWDOWN_MASTER_CLOCK |
| 27 | 27 | |
| 28 | −#define MCKRDY_TIMEOUT 1000 | |
| 29 | −#define MOSCRDY_TIMEOUT 1000 | |
| 30 | −#define PLLALOCK_TIMEOUT 1000 | |
| 31 | −#define PLLBLOCK_TIMEOUT 1000 | |
| 32 | − | |
| 33 | 28 | pmc .req r0 |
| 34 | 29 | sdramc .req r1 |
| 35 | 30 | ramc1 .req r2 |
| @@ -41,60 +36,42 @@ tmp2 .req r5 · 5 unmodified lines | ||
| 41 | 36 | * Wait until master clock is ready (after switching master clock source) |
| 42 | 37 | */ |
| 43 | 38 | .macro wait_mckrdy |
| 44 | − mov tmp2, #MCKRDY_TIMEOUT | |
| 45 | −1: sub tmp2, tmp2, #1 | |
| 46 | − cmp tmp2, #0 | |
| 47 | − beq 2f | |
| 48 | − ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 39 | +1: ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 49 | 40 | tst tmp1, #AT91_PMC_MCKRDY |
| 50 | 41 | beq 1b |
| 51 | −2: | |
| 52 | 42 | .endm |
| 53 | 43 | |
| 54 | 44 | /* |
| 55 | 45 | * Wait until master oscillator has stabilized. |
| 56 | 46 | */ |
| 57 | 47 | .macro wait_moscrdy |
| 58 | − mov tmp2, #MOSCRDY_TIMEOUT | |
| 59 | −1: sub tmp2, tmp2, #1 | |
| 60 | − cmp tmp2, #0 | |
| 61 | − beq 2f | |
| 62 | − ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 48 | +1: ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 63 | 49 | tst tmp1, #AT91_PMC_MOSCS |
| 64 | 50 | beq 1b |
| 65 | −2: | |
| 66 | 51 | .endm |
| 67 | 52 | |
| 68 | 53 | /* |
| 69 | 54 | * Wait until PLLA has locked. |
| 70 | 55 | */ |
| 71 | 56 | .macro wait_pllalock |
| 72 | − mov tmp2, #PLLALOCK_TIMEOUT | |
| 73 | −1: sub tmp2, tmp2, #1 | |
| 74 | − cmp tmp2, #0 | |
| 75 | − beq 2f | |
| 76 | − ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 57 | +1: ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 77 | 58 | tst tmp1, #AT91_PMC_LOCKA |
| 78 | 59 | beq 1b |
| 79 | −2: | |
| 80 | 60 | .endm |
| 81 | 61 | |
| 82 | 62 | /* |
| 83 | 63 | * Wait until PLLB has locked. |
| 84 | 64 | */ |
| 85 | 65 | .macro wait_pllblock |
| 86 | − mov tmp2, #PLLBLOCK_TIMEOUT | |
| 87 | −1: sub tmp2, tmp2, #1 | |
| 88 | − cmp tmp2, #0 | |
| 89 | − beq 2f | |
| 90 | − ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 66 | +1: ldr tmp1, [pmc, #AT91_PMC_SR] | |
| 91 | 67 | tst tmp1, #AT91_PMC_LOCKB |
| 92 | 68 | beq 1b |
| 93 | −2: | |
| 94 | 69 | .endm |
| 95 | 70 | |
| 96 | 71 | .text |
| 97 | 72 | |
| 73 | + .arm | |
| 74 | + | |
| 98 | 75 | /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, |
| 99 | 76 | * void __iomem *ramc1, int memctrl) |
| 100 | 77 | */ |
| @@ -134,6 +111,16 @@ ddr_sr_enable: · 33 unmodified lines | ||
| 134 | 111 | cmp memctrl, #AT91_MEMCTRL_DDRSDR |
| 135 | 112 | bne sdr_sr_enable |
| 136 | 113 | |
| 114 | + /* LPDDR1 --> force DDR2 mode during self-refresh */ | |
| 115 | + ldr tmp1, [sdramc, #AT91_DDRSDRC_MDR] | |
| 116 | + str tmp1, .saved_sam9_mdr | |
| 117 | + bic tmp1, tmp1, #~AT91_DDRSDRC_MD | |
| 118 | + cmp tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR | |
| 119 | + ldreq tmp1, [sdramc, #AT91_DDRSDRC_MDR] | |
| 120 | + biceq tmp1, tmp1, #AT91_DDRSDRC_MD | |
| 121 | + orreq tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2 | |
| 122 | + streq tmp1, [sdramc, #AT91_DDRSDRC_MDR] | |
| 123 | + | |
| 137 | 124 | /* prepare for DDRAM self-refresh mode */ |
| 138 | 125 | ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
| 139 | 126 | str tmp1, .saved_sam9_lpr |
| @@ -142,14 +129,26 @@ ddr_sr_enable: · 2 unmodified lines | ||
| 142 | 129 | |
| 143 | 130 | /* figure out if we use the second ram controller */ |
| 144 | 131 | cmp ramc1, #0 |
| 145 | − ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | |
| 146 | − strne tmp2, .saved_sam9_lpr1 | |
| 147 | − bicne tmp2, #AT91_DDRSDRC_LPCB | |
| 148 | − orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH | |
| 132 | + beq ddr_no_2nd_ctrl | |
| 133 | + | |
| 134 | + ldr tmp2, [ramc1, #AT91_DDRSDRC_MDR] | |
| 135 | + str tmp2, .saved_sam9_mdr1 | |
| 136 | + bic tmp2, tmp2, #~AT91_DDRSDRC_MD | |
| 137 | + cmp tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR | |
| 138 | + ldreq tmp2, [ramc1, #AT91_DDRSDRC_MDR] | |
| 139 | + biceq tmp2, tmp2, #AT91_DDRSDRC_MD | |
| 140 | + orreq tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2 | |
| 141 | + streq tmp2, [ramc1, #AT91_DDRSDRC_MDR] | |
| 142 | + | |
| 143 | + ldr tmp2, [ramc1, #AT91_DDRSDRC_LPR] | |
| 144 | + str tmp2, .saved_sam9_lpr1 | |
| 145 | + bic tmp2, #AT91_DDRSDRC_LPCB | |
| 146 | + orr tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH | |
| 149 | 147 | |
| 150 | 148 | /* Enable DDRAM self-refresh mode */ |
| 149 | + str tmp2, [ramc1, #AT91_DDRSDRC_LPR] | |
| 150 | +ddr_no_2nd_ctrl: | |
| 151 | 151 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
| 152 | − strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] | |
| 153 | 152 | |
| 154 | 153 | b sdr_sr_done |
| 155 | 154 | |
| @@ -208,6 +207,7 @@ sdr_sr_done: · 52 unmodified lines | ||
| 208 | 207 | /* Turn off the main oscillator */ |
| 209 | 208 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
| 210 | 209 | bic tmp1, tmp1, #AT91_PMC_MOSCEN |
| 210 | + orr tmp1, tmp1, #AT91_PMC_KEY | |
| 211 | 211 | str tmp1, [pmc, #AT91_CKGR_MOR] |
| 212 | 212 | |
| 213 | 213 | /* Wait for interrupt */ |
| @@ -216,6 +216,7 @@ sdr_sr_done: · 2 unmodified lines | ||
| 216 | 216 | /* Turn on the main oscillator */ |
| 217 | 217 | ldr tmp1, [pmc, #AT91_CKGR_MOR] |
| 218 | 218 | orr tmp1, tmp1, #AT91_PMC_MOSCEN |
| 219 | + orr tmp1, tmp1, #AT91_PMC_KEY | |
| 219 | 220 | str tmp1, [pmc, #AT91_CKGR_MOR] |
| 220 | 221 | |
| 221 | 222 | wait_moscrdy |
| @@ -280,12 +281,17 @@ sdr_sr_done: · 58 unmodified lines | ||
| 280 | 281 | */ |
| 281 | 282 | cmp memctrl, #AT91_MEMCTRL_DDRSDR |
| 282 | 283 | bne sdr_en_restore |
| 284 | + /* Restore MDR in case of LPDDR1 */ | |
| 285 | + ldr tmp1, .saved_sam9_mdr | |
| 286 | + str tmp1, [sdramc, #AT91_DDRSDRC_MDR] | |
| 283 | 287 | /* Restore LPR on AT91 with DDRAM */ |
| 284 | 288 | ldr tmp1, .saved_sam9_lpr |
| 285 | 289 | str tmp1, [sdramc, #AT91_DDRSDRC_LPR] |
| 286 | 290 | |
| 287 | 291 | /* if we use the second ram controller */ |
| 288 | 292 | cmp ramc1, #0 |
| 293 | + ldrne tmp2, .saved_sam9_mdr1 | |
| 294 | + strne tmp2, [ramc1, #AT91_DDRSDRC_MDR] | |
| 289 | 295 | ldrne tmp2, .saved_sam9_lpr1 |
| 290 | 296 | strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] |
| 291 | 297 | |
| @@ -319,5 +325,11 @@ ram_restored: · 27 unmodified lines | ||
| 319 | 325 | .saved_sam9_lpr1: |
| 320 | 326 | .word 0 |
| 321 | 327 | |
| 328 | +.saved_sam9_mdr: | |
| 329 | + .word 0 | |
| 330 | + | |
| 331 | +.saved_sam9_mdr1: | |
| 332 | + .word 0 | |
| 333 | + | |
| 322 | 334 | ENTRY(at91_slow_clock_sz) |
| 323 | 335 | .word .-at91_slow_clock |
| @@ -126,8 +126,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) · 125 unmodified lines | ||
| 126 | 126 | */ |
| 127 | 127 | void exynos_cpu_power_down(int cpu) |
| 128 | 128 | { |
| 129 | − if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") || | |
| 130 | − of_machine_is_compatible("samsung,exynos5800"))) { | |
| 129 | + if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) { | |
| 131 | 130 | /* |
| 132 | 131 | * Bypass power down for CPU0 during suspend. Check for |
| 133 | 132 | * the SYS_PWR_REG value to decide if we are suspending |
| @@ -161,6 +161,34 @@ no_clk: · 160 unmodified lines | ||
| 161 | 161 | of_genpd_add_provider_simple(np, &pd->pd); |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | + /* Assign the child power domains to their parents */ | |
| 165 | + for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") { | |
| 166 | + struct generic_pm_domain *child_domain, *parent_domain; | |
| 167 | + struct of_phandle_args args; | |
| 168 | + | |
| 169 | + args.np = np; | |
| 170 | + args.args_count = 0; | |
| 171 | + child_domain = of_genpd_get_from_provider(&args); | |
| 172 | + if (!child_domain) | |
| 173 | + continue; | |
| 174 | + | |
| 175 | + if (of_parse_phandle_with_args(np, "power-domains", | |
| 176 | + "#power-domain-cells", 0, &args) != 0) | |
| 177 | + continue; | |
| 178 | + | |
| 179 | + parent_domain = of_genpd_get_from_provider(&args); | |
| 180 | + if (!parent_domain) | |
| 181 | + continue; | |
| 182 | + | |
| 183 | + if (pm_genpd_add_subdomain(parent_domain, child_domain)) | |
| 184 | + pr_warn("%s failed to add subdomain: %s\n", | |
| 185 | + parent_domain->name, child_domain->name); | |
| 186 | + else | |
| 187 | + pr_info("%s has as child subdomain: %s.\n", | |
| 188 | + parent_domain->name, child_domain->name); | |
| 189 | + of_node_put(np); | |
| 190 | + } | |
| 191 | + | |
| 164 | 192 | return 0; |
| 165 | 193 | } |
| 166 | 194 | arch_initcall(exynos4_pm_init_power_domain); |
| @@ -87,8 +87,8 @@ static unsigned int exynos_pmu_spare3; · 86 unmodified lines | ||
| 87 | 87 | static u32 exynos_irqwake_intmask = 0xffffffff; |
| 88 | 88 | |
| 89 | 89 | static const struct exynos_wkup_irq exynos3250_wkup_irq[] = { |
| 90 | − { 73, BIT(1) }, /* RTC alarm */ | |
| 91 | − { 74, BIT(2) }, /* RTC tick */ | |
| 90 | + { 105, BIT(1) }, /* RTC alarm */ | |
| 91 | + { 106, BIT(2) }, /* RTC tick */ | |
| 92 | 92 | { /* sentinel */ }, |
| 93 | 93 | }; |
| 94 | 94 | |
| @@ -211,8 +211,9 @@ static void __init imx6q_1588_init(void) · 210 unmodified lines | ||
| 211 | 211 | * set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad |
| 212 | 212 | * (external OSC), and we need to clear the bit. |
| 213 | 213 | */ |
| 214 | − clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP : | |
| 215 | − IMX6Q_GPR1_ENET_CLK_SEL_PAD; | |
| 214 | + clksel = clk_is_match(ptp_clk, enet_ref) ? | |
| 215 | + IMX6Q_GPR1_ENET_CLK_SEL_ANATOP : | |
| 216 | + IMX6Q_GPR1_ENET_CLK_SEL_PAD; | |
| 216 | 217 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); |
| 217 | 218 | if (!IS_ERR(gpr)) |
| 218 | 219 | regmap_update_bits(gpr, IOMUXC_GPR1, |
| @@ -1692,16 +1692,15 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) · 1691 unmodified lines | ||
| 1692 | 1692 | if (ret == -EBUSY) |
| 1693 | 1693 | pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name); |
| 1694 | 1694 | |
| 1695 | − if (!ret) { | |
| 1695 | + if (oh->clkdm) { | |
| 1696 | 1696 | /* |
| 1697 | 1697 | * Set the clockdomain to HW_AUTO, assuming that the |
| 1698 | 1698 | * previous state was HW_AUTO. |
| 1699 | 1699 | */ |
| 1700 | − if (oh->clkdm && hwsup) | |
| 1700 | + if (hwsup) | |
| 1701 | 1701 | clkdm_allow_idle(oh->clkdm); |
| 1702 | − } else { | |
| 1703 | − if (oh->clkdm) | |
| 1704 | − clkdm_hwmod_disable(oh->clkdm, oh); | |
| 1702 | + | |
| 1703 | + clkdm_hwmod_disable(oh->clkdm, oh); | |
| 1705 | 1704 | } |
| 1706 | 1705 | |
| 1707 | 1706 | return ret; |
| @@ -2698,6 +2697,7 @@ static int __init _register(struct omap_hwmod *oh) · 990 unmodified lines | ||
| 2698 | 2697 | INIT_LIST_HEAD(&oh->master_ports); |
| 2699 | 2698 | INIT_LIST_HEAD(&oh->slave_ports); |
| 2700 | 2699 | spin_lock_init(&oh->_lock); |
| 2700 | + lockdep_set_class(&oh->_lock, &oh->hwmod_key); | |
| 2701 | 2701 | |
| 2702 | 2702 | oh->_state = _HWMOD_STATE_REGISTERED; |
| 2703 | 2703 | |
| @@ -674,6 +674,7 @@ struct omap_hwmod { · 673 unmodified lines | ||
| 674 | 674 | u32 _sysc_cache; |
| 675 | 675 | void __iomem *_mpu_rt_va; |
| 676 | 676 | spinlock_t _lock; |
| 677 | + struct lock_class_key hwmod_key; /* unique lock class */ | |
| 677 | 678 | struct list_head node; |
| 678 | 679 | struct omap_hwmod_ocp_if *_mpu_port; |
| 679 | 680 | unsigned int (*xlate_irq)(unsigned int); |
| @@ -1466,53 +1466,16 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { · 1465 unmodified lines | ||
| 1466 | 1466 | * |
| 1467 | 1467 | */ |
| 1468 | 1468 | |
| 1469 | −static struct omap_hwmod_class dra7xx_pcie_hwmod_class = { | |
| 1469 | +static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { | |
| 1470 | 1470 | .name = "pcie", |
| 1471 | 1471 | }; |
| 1472 | 1472 | |
| 1473 | 1473 | /* pcie1 */ |
| 1474 | −static struct omap_hwmod dra7xx_pcie1_hwmod = { | |
| 1474 | +static struct omap_hwmod dra7xx_pciess1_hwmod = { | |
| 1475 | 1475 | .name = "pcie1", |
| 1476 | − .class = &dra7xx_pcie_hwmod_class, | |
| 1476 | + .class = &dra7xx_pciess_hwmod_class, | |
| 1477 | 1477 | .clkdm_name = "pcie_clkdm", |
| 1478 | 1478 | .main_clk = "l4_root_clk_div", |
| 1479 | − .prcm = { | |
| 1480 | − .omap4 = { | |
| 1481 | − .clkctrl_offs = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET, | |
| 1482 | − .modulemode = MODULEMODE_SWCTRL, | |
| 1483 | − }, | |
| 1484 | − }, | |
| 1485 | −}; | |
| 1486 | − | |
| 1487 | −/* pcie2 */ | |
| 1488 | −static struct omap_hwmod dra7xx_pcie2_hwmod = { | |
| 1489 | − .name = "pcie2", | |
| 1490 | − .class = &dra7xx_pcie_hwmod_class, | |
| 1491 | − .clkdm_name = "pcie_clkdm", | |
| 1492 | − .main_clk = "l4_root_clk_div", | |
| 1493 | − .prcm = { | |
| 1494 | − .omap4 = { | |
| 1495 | − .clkctrl_offs = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET, | |
| 1496 | − .modulemode = MODULEMODE_SWCTRL, | |
| 1497 | − }, | |
| 1498 | − }, | |
| 1499 | −}; | |
| 1500 | − | |
| 1501 | −/* | |
| 1502 | − * 'PCIE PHY' class | |
| 1503 | − * | |
| 1504 | − */ | |
| 1505 | − | |
| 1506 | −static struct omap_hwmod_class dra7xx_pcie_phy_hwmod_class = { | |
| 1507 | − .name = "pcie-phy", | |
| 1508 | −}; | |
| 1509 | − | |
| 1510 | −/* pcie1 phy */ | |
| 1511 | −static struct omap_hwmod dra7xx_pcie1_phy_hwmod = { | |
| 1512 | − .name = "pcie1-phy", | |
| 1513 | − .class = &dra7xx_pcie_phy_hwmod_class, | |
| 1514 | − .clkdm_name = "l3init_clkdm", | |
| 1515 | − .main_clk = "l4_root_clk_div", | |
| 1516 | 1479 | .prcm = { |
| 1517 | 1480 | .omap4 = { |
| 1518 | 1481 | .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, |
| @@ -1522,11 +1485,11 @@ static struct omap_hwmod dra7xx_pcie1_phy_hwmod = { · 3 unmodified lines | ||
| 1522 | 1485 | }, |
| 1523 | 1486 | }; |
| 1524 | 1487 | |
| 1525 | −/* pcie2 phy */ | |
| 1526 | −static struct omap_hwmod dra7xx_pcie2_phy_hwmod = { | |
| 1527 | − .name = "pcie2-phy", | |
| 1528 | − .class = &dra7xx_pcie_phy_hwmod_class, | |
| 1529 | − .clkdm_name = "l3init_clkdm", | |
| 1488 | +/* pcie2 */ | |
| 1489 | +static struct omap_hwmod dra7xx_pciess2_hwmod = { | |
| 1490 | + .name = "pcie2", | |
| 1491 | + .class = &dra7xx_pciess_hwmod_class, | |
| 1492 | + .clkdm_name = "pcie_clkdm", | |
| 1530 | 1493 | .main_clk = "l4_root_clk_div", |
| 1531 | 1494 | .prcm = { |
| 1532 | 1495 | .omap4 = { |
| @@ -2877,50 +2840,34 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = { · 1344 unmodified lines | ||
| 2877 | 2840 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
| 2878 | 2841 | }; |
| 2879 | 2842 | |
| 2880 | −/* l3_main_1 -> pcie1 */ | |
| 2881 | −static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie1 = { | |
| 2843 | +/* l3_main_1 -> pciess1 */ | |
| 2844 | +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess1 = { | |
| 2882 | 2845 | .master = &dra7xx_l3_main_1_hwmod, |
| 2883 | − .slave = &dra7xx_pcie1_hwmod, | |
| 2846 | + .slave = &dra7xx_pciess1_hwmod, | |
| 2884 | 2847 | .clk = "l3_iclk_div", |
| 2885 | 2848 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
| 2886 | 2849 | }; |
| 2887 | 2850 | |
| 2888 | −/* l4_cfg -> pcie1 */ | |
| 2889 | −static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1 = { | |
| 2851 | +/* l4_cfg -> pciess1 */ | |
| 2852 | +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess1 = { | |
| 2890 | 2853 | .master = &dra7xx_l4_cfg_hwmod, |
| 2891 | − .slave = &dra7xx_pcie1_hwmod, | |
| 2854 | + .slave = &dra7xx_pciess1_hwmod, | |
| 2892 | 2855 | .clk = "l4_root_clk_div", |
| 2893 | 2856 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
| 2894 | 2857 | }; |
| 2895 | 2858 | |
| 2896 | −/* l3_main_1 -> pcie2 */ | |
| 2897 | −static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie2 = { | |
| 2859 | +/* l3_main_1 -> pciess2 */ | |
| 2860 | +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess2 = { | |
| 2898 | 2861 | .master = &dra7xx_l3_main_1_hwmod, |
| 2899 | − .slave = &dra7xx_pcie2_hwmod, | |
| 2862 | + .slave = &dra7xx_pciess2_hwmod, | |
| 2900 | 2863 | .clk = "l3_iclk_div", |
| 2901 | 2864 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
| 2902 | 2865 | }; |
| 2903 | 2866 | |
| 2904 | −/* l4_cfg -> pcie2 */ | |
| 2905 | −static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2 = { | |
| 2906 | − .master = &dra7xx_l4_cfg_hwmod, | |
| 2907 | − .slave = &dra7xx_pcie2_hwmod, | |
| 2908 | − .clk = "l4_root_clk_div", | |
| 2909 | − .user = OCP_USER_MPU | OCP_USER_SDMA, | |
| 2910 | −}; | |
| 2911 | − | |
| 2912 | −/* l4_cfg -> pcie1 phy */ | |
| 2913 | −static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1_phy = { | |
| 2914 | − .master = &dra7xx_l4_cfg_hwmod, | |
| 2915 | − .slave = &dra7xx_pcie1_phy_hwmod, | |
| 2916 | − .clk = "l4_root_clk_div", | |
| 2917 | − .user = OCP_USER_MPU | OCP_USER_SDMA, | |
| 2918 | −}; | |
| 2919 | − | |
| 2920 | −/* l4_cfg -> pcie2 phy */ | |
| 2921 | −static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2_phy = { | |
| 2867 | +/* l4_cfg -> pciess2 */ | |
| 2868 | +static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess2 = { | |
| 2922 | 2869 | .master = &dra7xx_l4_cfg_hwmod, |
| 2923 | − .slave = &dra7xx_pcie2_phy_hwmod, | |
| 2870 | + .slave = &dra7xx_pciess2_hwmod, | |
| 2924 | 2871 | .clk = "l4_root_clk_div", |
| 2925 | 2872 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
| 2926 | 2873 | }; |
| @@ -3327,12 +3274,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { · 400 unmodified lines | ||
| 3327 | 3274 | &dra7xx_l4_cfg__mpu, |
| 3328 | 3275 | &dra7xx_l4_cfg__ocp2scp1, |
| 3329 | 3276 | &dra7xx_l4_cfg__ocp2scp3, |
| 3330 | − &dra7xx_l3_main_1__pcie1, | |
| 3331 | − &dra7xx_l4_cfg__pcie1, | |
| 3332 | − &dra7xx_l3_main_1__pcie2, | |
| 3333 | − &dra7xx_l4_cfg__pcie2, | |
| 3334 | − &dra7xx_l4_cfg__pcie1_phy, | |
| 3335 | − &dra7xx_l4_cfg__pcie2_phy, | |
| 3277 | + &dra7xx_l3_main_1__pciess1, | |
| 3278 | + &dra7xx_l4_cfg__pciess1, | |
| 3279 | + &dra7xx_l3_main_1__pciess2, | |
| 3280 | + &dra7xx_l4_cfg__pciess2, | |
| 3336 | 3281 | &dra7xx_l3_main_1__qspi, |
| 3337 | 3282 | &dra7xx_l4_per3__rtcss, |
| 3338 | 3283 | &dra7xx_l4_cfg__sata, |
| @@ -173,6 +173,7 @@ static void __init omap3_igep0030_rev_g_legacy_init(void) · 172 unmodified lines | ||
| 173 | 173 | |
| 174 | 174 | static void __init omap3_evm_legacy_init(void) |
| 175 | 175 | { |
| 176 | + hsmmc2_internal_input_clk(); | |
| 176 | 177 | legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149); |
| 177 | 178 | } |
| 178 | 179 | |
| @@ -252,10 +252,10 @@ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) · 251 unmodified lines | ||
| 252 | 252 | { |
| 253 | 253 | saved_mask[0] = |
| 254 | 254 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
| 255 | − OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | |
| 255 | + OMAP4_PRM_IRQENABLE_MPU_OFFSET); | |
| 256 | 256 | saved_mask[1] = |
| 257 | 257 | omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, |
| 258 | − OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | |
| 258 | + OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); | |
| 259 | 259 | |
| 260 | 260 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, |
| 261 | 261 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <linux/platform_data/video-pxafb.h> |
| 37 | 37 | #include <mach/bitfield.h> |
| 38 | 38 | #include <linux/platform_data/mmc-pxamci.h> |
| 39 | +#include <linux/smc91x.h> | |
| 39 | 40 | |
| 40 | 41 | #include "generic.h" |
| 41 | 42 | #include "devices.h" |
| @@ -195,7 +195,7 @@ static struct resource smc91x_resources[] = { · 194 unmodified lines | ||
| 195 | 195 | }; |
| 196 | 196 | |
| 197 | 197 | struct smc91x_platdata smc91x_platdata = { |
| 198 | − .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT; | |
| 198 | + .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | |
| 199 | 199 | }; |
| 200 | 200 | |
| 201 | 201 | static struct platform_device smc91x_device = { |
| @@ -268,8 +268,8 @@ static int neponset_probe(struct platform_device *dev) · 267 unmodified lines | ||
| 268 | 268 | .id = 0, |
| 269 | 269 | .res = smc91x_resources, |
| 270 | 270 | .num_res = ARRAY_SIZE(smc91x_resources), |
| 271 | − .data = &smc91c_platdata, | |
| 272 | − .size_data = sizeof(smc91c_platdata), | |
| 271 | + .data = &smc91x_platdata, | |
| 272 | + .size_data = sizeof(smc91x_platdata), | |
| 273 | 273 | }; |
| 274 | 274 | int ret, irq; |
| 275 | 275 | |
| @@ -54,7 +54,7 @@ static struct platform_device smc91x_device = { · 53 unmodified lines | ||
| 54 | 54 | .num_resources = ARRAY_SIZE(smc91x_resources), |
| 55 | 55 | .resource = smc91x_resources, |
| 56 | 56 | .dev = { |
| 57 | − .platform_data = &smc91c_platdata, | |
| 57 | + .platform_data = &smc91x_platdata, | |
| 58 | 58 | }, |
| 59 | 59 | }; |
| 60 | 60 | |
| @@ -45,6 +45,6 @@ extern char secondary_trampoline, secondary_trampoline_end; · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | extern unsigned long socfpga_cpu1start_addr; |
| 47 | 47 | |
| 48 | −#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 | |
| 48 | +#define SOCFPGA_SCU_VIRT_BASE 0xfee00000 | |
| 49 | 49 | |
| 50 | 50 | #endif |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <asm/hardware/cache-l2x0.h> |
| 24 | 24 | #include <asm/mach/arch.h> |
| 25 | 25 | #include <asm/mach/map.h> |
| 26 | +#include <asm/cacheflush.h> | |
| 26 | 27 | |
| 27 | 28 | #include "core.h" |
| 28 | 29 | |
| @@ -73,6 +74,10 @@ void __init socfpga_sysmgr_init(void) · 44 unmodified lines | ||
| 73 | 74 | (u32 *) &socfpga_cpu1start_addr)) |
| 74 | 75 | pr_err("SMP: Need cpu1-start-addr in device tree.\n"); |
| 75 | 76 | |
| 77 | + /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */ | |
| 78 | + smp_wmb(); | |
| 79 | + sync_cache_w(&socfpga_cpu1start_addr); | |
| 80 | + | |
| 76 | 81 | sys_manager_base_addr = of_iomap(np, 0); |
| 77 | 82 | |
| 78 | 83 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); |
| @@ -18,6 +18,7 @@ static const char *stih41x_dt_match[] __initdata = { · 17 unmodified lines | ||
| 18 | 18 | "st,stih415", |
| 19 | 19 | "st,stih416", |
| 20 | 20 | "st,stih407", |
| 21 | + "st,stih410", | |
| 21 | 22 | "st,stih418", |
| 22 | 23 | NULL |
| 23 | 24 | }; |
| @@ -1131,23 +1131,22 @@ static void __init l2c310_of_parse(const struct device_node *np, · 1130 unmodified lines | ||
| 1131 | 1131 | } |
| 1132 | 1132 | |
| 1133 | 1133 | ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); |
| 1134 | − if (ret) | |
| 1135 | − return; | |
| 1136 | − | |
| 1137 | − switch (assoc) { | |
| 1138 | − case 16: | |
| 1139 | − *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1140 | − *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16; | |
| 1141 | − *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1142 | − break; | |
| 1143 | − case 8: | |
| 1144 | − *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1145 | − *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1146 | − break; | |
| 1147 | − default: | |
| 1148 | − pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n", | |
| 1149 | − assoc); | |
| 1150 | − break; | |
| 1134 | + if (!ret) { | |
| 1135 | + switch (assoc) { | |
| 1136 | + case 16: | |
| 1137 | + *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1138 | + *aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16; | |
| 1139 | + *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1140 | + break; | |
| 1141 | + case 8: | |
| 1142 | + *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1143 | + *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; | |
| 1144 | + break; | |
| 1145 | + default: | |
| 1146 | + pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n", | |
| 1147 | + assoc); | |
| 1148 | + break; | |
| 1149 | + } | |
| 1151 | 1150 | } |
| 1152 | 1151 | |
| 1153 | 1152 | prefetch = l2x0_saved_regs.prefetch_ctrl; |
| @@ -171,7 +171,7 @@ static int __dma_supported(struct device *dev, u64 mask, bool warn) · 170 unmodified lines | ||
| 171 | 171 | */ |
| 172 | 172 | if (sizeof(mask) != sizeof(dma_addr_t) && |
| 173 | 173 | mask > (dma_addr_t)~0 && |
| 174 | − dma_to_pfn(dev, ~0) < max_pfn) { | |
| 174 | + dma_to_pfn(dev, ~0) < max_pfn - 1) { | |
| 175 | 175 | if (warn) { |
| 176 | 176 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", |
| 177 | 177 | mask); |
| @@ -552,6 +552,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 551 unmodified lines | ||
| 552 | 552 | |
| 553 | 553 | pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
| 554 | 554 | inf->name, fsr, addr); |
| 555 | + show_pte(current->mm, addr); | |
| 555 | 556 | |
| 556 | 557 | info.si_signo = inf->sig; |
| 557 | 558 | info.si_errno = 0; |
| @@ -49,7 +49,10 @@ static int change_memory_common(unsigned long addr, int numpages, · 48 unmodified lines | ||
| 49 | 49 | WARN_ON_ONCE(1); |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | − if (!is_module_address(start) || !is_module_address(end - 1)) | |
| 52 | + if (start < MODULES_VADDR || start >= MODULES_END) | |
| 53 | + return -EINVAL; | |
| 54 | + | |
| 55 | + if (end < MODULES_VADDR || start >= MODULES_END) | |
| 53 | 56 | return -EINVAL; |
| 54 | 57 | |
| 55 | 58 | data.set_mask = set_mask; |
| @@ -622,7 +622,7 @@ · 621 unmodified lines | ||
| 622 | 622 | }; |
| 623 | 623 | |
| 624 | 624 | sgenet0: ethernet@1f210000 { |
| 625 | − compatible = "apm,xgene-enet"; | |
| 625 | + compatible = "apm,xgene1-sgenet"; | |
| 626 | 626 | status = "disabled"; |
| 627 | 627 | reg = <0x0 0x1f210000 0x0 0xd100>, |
| 628 | 628 | <0x0 0x1f200000 0x0 0Xc300>, |
| @@ -636,7 +636,7 @@ · 7 unmodified lines | ||
| 636 | 636 | }; |
| 637 | 637 | |
| 638 | 638 | xgenet: ethernet@1f610000 { |
| 639 | − compatible = "apm,xgene-enet"; | |
| 639 | + compatible = "apm,xgene1-xgenet"; | |
| 640 | 640 | status = "disabled"; |
| 641 | 641 | reg = <0x0 0x1f610000 0x0 0xd100>, |
| 642 | 642 | <0x0 0x1f600000 0x0 0Xc300>, |
| @@ -129,6 +129,9 @@ · 128 unmodified lines | ||
| 129 | 129 | * 40 bits wide (T0SZ = 24). Systems with a PARange smaller than 40 bits are |
| 130 | 130 | * not known to exist and will break with this configuration. |
| 131 | 131 | * |
| 132 | + * VTCR_EL2.PS is extracted from ID_AA64MMFR0_EL1.PARange at boot time | |
| 133 | + * (see hyp-init.S). | |
| 134 | + * | |
| 132 | 135 | * Note that when using 4K pages, we concatenate two first level page tables |
| 133 | 136 | * together. |
| 134 | 137 | * |
| @@ -138,7 +141,6 @@ · 3 unmodified lines | ||
| 138 | 141 | #ifdef CONFIG_ARM64_64K_PAGES |
| 139 | 142 | /* |
| 140 | 143 | * Stage2 translation configuration: |
| 141 | − * 40bits output (PS = 2) | |
| 142 | 144 | * 40bits input (T0SZ = 24) |
| 143 | 145 | * 64kB pages (TG0 = 1) |
| 144 | 146 | * 2 level page tables (SL = 1) |
| @@ -150,7 +152,6 @@ · 5 unmodified lines | ||
| 150 | 152 | #else |
| 151 | 153 | /* |
| 152 | 154 | * Stage2 translation configuration: |
| 153 | − * 40bits output (PS = 2) | |
| 154 | 155 | * 40bits input (T0SZ = 24) |
| 155 | 156 | * 4kB pages (TG0 = 0) |
| 156 | 157 | * 3 level page tables (SL = 1) |
| @@ -158,6 +158,8 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) · 157 unmodified lines | ||
| 158 | 158 | #define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) |
| 159 | 159 | #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) |
| 160 | 160 | |
| 161 | +#define kvm_pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1)) | |
| 162 | + | |
| 161 | 163 | /* |
| 162 | 164 | * If we are concatenating first level stage-2 page tables, we would have less |
| 163 | 165 | * than or equal to 16 pointers in the fake PGD, because that's what the |
| @@ -171,43 +173,6 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd) · 7 unmodified lines | ||
| 171 | 173 | #define KVM_PREALLOC_LEVEL (0) |
| 172 | 174 | #endif |
| 173 | 175 | |
| 174 | −/** | |
| 175 | − * kvm_prealloc_hwpgd - allocate inital table for VTTBR | |
| 176 | − * @kvm: The KVM struct pointer for the VM. | |
| 177 | − * @pgd: The kernel pseudo pgd | |
| 178 | − * | |
| 179 | − * When the kernel uses more levels of page tables than the guest, we allocate | |
| 180 | − * a fake PGD and pre-populate it to point to the next-level page table, which | |
| 181 | − * will be the real initial page table pointed to by the VTTBR. | |
| 182 | − * | |
| 183 | − * When KVM_PREALLOC_LEVEL==2, we allocate a single page for the PMD and | |
| 184 | − * the kernel will use folded pud. When KVM_PREALLOC_LEVEL==1, we | |
| 185 | − * allocate 2 consecutive PUD pages. | |
| 186 | − */ | |
| 187 | −static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd) | |
| 188 | −{ | |
| 189 | − unsigned int i; | |
| 190 | − unsigned long hwpgd; | |
| 191 | − | |
| 192 | − if (KVM_PREALLOC_LEVEL == 0) | |
| 193 | − return 0; | |
| 194 | − | |
| 195 | − hwpgd = __get_free_pages(GFP_KERNEL | __GFP_ZERO, PTRS_PER_S2_PGD_SHIFT); | |
| 196 | − if (!hwpgd) | |
| 197 | − return -ENOMEM; | |
| 198 | − | |
| 199 | − for (i = 0; i < PTRS_PER_S2_PGD; i++) { | |
| 200 | − if (KVM_PREALLOC_LEVEL == 1) | |
| 201 | − pgd_populate(NULL, pgd + i, | |
| 202 | − (pud_t *)hwpgd + i * PTRS_PER_PUD); | |
| 203 | − else if (KVM_PREALLOC_LEVEL == 2) | |
| 204 | − pud_populate(NULL, pud_offset(pgd, 0) + i, | |
| 205 | − (pmd_t *)hwpgd + i * PTRS_PER_PMD); | |
| 206 | − } | |
| 207 | − | |
| 208 | − return 0; | |
| 209 | −} | |
| 210 | − | |
| 211 | 176 | static inline void *kvm_get_hwpgd(struct kvm *kvm) |
| 212 | 177 | { |
| 213 | 178 | pgd_t *pgd = kvm->arch.pgd; |
| @@ -224,12 +189,11 @@ static inline void *kvm_get_hwpgd(struct kvm *kvm) · 10 unmodified lines | ||
| 224 | 189 | return pmd_offset(pud, 0); |
| 225 | 190 | } |
| 226 | 191 | |
| 227 | −static inline void kvm_free_hwpgd(struct kvm *kvm) | |
| 192 | +static inline unsigned int kvm_get_hwpgd_size(void) | |
| 228 | 193 | { |
| 229 | − if (KVM_PREALLOC_LEVEL > 0) { | |
| 230 | − unsigned long hwpgd = (unsigned long)kvm_get_hwpgd(kvm); | |
| 231 | − free_pages(hwpgd, PTRS_PER_S2_PGD_SHIFT); | |
| 232 | − } | |
| 194 | + if (KVM_PREALLOC_LEVEL > 0) | |
| 195 | + return PTRS_PER_S2_PGD * PAGE_SIZE; | |
| 196 | + return PTRS_PER_S2_PGD * sizeof(pgd_t); | |
| 233 | 197 | } |
| 234 | 198 | |
| 235 | 199 | static inline bool kvm_page_empty(void *ptr) |
| @@ -39,7 +39,11 @@ extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr); · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #include <asm/memory.h> |
| 41 | 41 | |
| 42 | −#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) | |
| 42 | +#define cpu_switch_mm(pgd,mm) \ | |
| 43 | +do { \ | |
| 44 | + BUG_ON(pgd == swapper_pg_dir); \ | |
| 45 | + cpu_do_switch_mm(virt_to_phys(pgd),mm); \ | |
| 46 | +} while (0) | |
| 43 | 47 | |
| 44 | 48 | #define cpu_get_pgd() \ |
| 45 | 49 | ({ \ |
| @@ -48,6 +48,7 @@ static inline void tlb_flush(struct mmu_gather *tlb) · 47 unmodified lines | ||
| 48 | 48 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, |
| 49 | 49 | unsigned long addr) |
| 50 | 50 | { |
| 51 | + __flush_tlb_pgtable(tlb->mm, addr); | |
| 51 | 52 | pgtable_page_dtor(pte); |
| 52 | 53 | tlb_remove_entry(tlb, pte); |
| 53 | 54 | } |
| @@ -56,6 +57,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, · 2 unmodified lines | ||
| 56 | 57 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, |
| 57 | 58 | unsigned long addr) |
| 58 | 59 | { |
| 60 | + __flush_tlb_pgtable(tlb->mm, addr); | |
| 59 | 61 | tlb_remove_entry(tlb, virt_to_page(pmdp)); |
| 60 | 62 | } |
| 61 | 63 | #endif |
| @@ -64,6 +66,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, · 2 unmodified lines | ||
| 64 | 66 | static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp, |
| 65 | 67 | unsigned long addr) |
| 66 | 68 | { |
| 69 | + __flush_tlb_pgtable(tlb->mm, addr); | |
| 67 | 70 | tlb_remove_entry(tlb, virt_to_page(pudp)); |
| 68 | 71 | } |
| 69 | 72 | #endif |
| @@ -143,6 +143,19 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end · 142 unmodified lines | ||
| 143 | 143 | flush_tlb_all(); |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | +/* | |
| 147 | + * Used to invalidate the TLB (walk caches) corresponding to intermediate page | |
| 148 | + * table levels (pgd/pud/pmd). | |
| 149 | + */ | |
| 150 | +static inline void __flush_tlb_pgtable(struct mm_struct *mm, | |
| 151 | + unsigned long uaddr) | |
| 152 | +{ | |
| 153 | + unsigned long addr = uaddr >> 12 | ((unsigned long)ASID(mm) << 48); | |
| 154 | + | |
| 155 | + dsb(ishst); | |
| 156 | + asm("tlbi vae1is, %0" : : "r" (addr)); | |
| 157 | + dsb(ish); | |
| 158 | +} | |
| 146 | 159 | /* |
| 147 | 160 | * On AArch64, the cache coherency is handled via the set_pte_at() function. |
| 148 | 161 | */ |
| @@ -337,7 +337,11 @@ core_initcall(arm64_dmi_init); · 336 unmodified lines | ||
| 337 | 337 | |
| 338 | 338 | static void efi_set_pgd(struct mm_struct *mm) |
| 339 | 339 | { |
| 340 | − cpu_switch_mm(mm->pgd, mm); | |
| 340 | + if (mm == &init_mm) | |
| 341 | + cpu_set_reserved_ttbr0(); | |
| 342 | + else | |
| 343 | + cpu_switch_mm(mm->pgd, mm); | |
| 344 | + | |
| 341 | 345 | flush_tlb_all(); |
| 342 | 346 | if (icache_is_aivivt()) |
| 343 | 347 | __flush_icache_all(); |
| @@ -354,3 +358,12 @@ void efi_virtmap_unload(void) · 10 unmodified lines | ||
| 354 | 358 | efi_set_pgd(current->active_mm); |
| 355 | 359 | preempt_enable(); |
| 356 | 360 | } |
| 361 | + | |
| 362 | +/* | |
| 363 | + * UpdateCapsule() depends on the system being shutdown via | |
| 364 | + * ResetSystem(). | |
| 365 | + */ | |
| 366 | +bool efi_poweroff_required(void) | |
| 367 | +{ | |
| 368 | + return efi_enabled(EFI_RUNTIME_SERVICES); | |
| 369 | +} | |
| @@ -585,8 +585,8 @@ ENDPROC(set_cpu_boot_mode_flag) · 584 unmodified lines | ||
| 585 | 585 | * zeroing of .bss would clobber it. |
| 586 | 586 | */ |
| 587 | 587 | .pushsection .data..cacheline_aligned |
| 588 | −ENTRY(__boot_cpu_mode) | |
| 589 | 588 | .align L1_CACHE_SHIFT |
| 589 | +ENTRY(__boot_cpu_mode) | |
| 590 | 590 | .long BOOT_CPU_MODE_EL2 |
| 591 | 591 | .long 0 |
| 592 | 592 | .popsection |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <stdarg.h> |
| 22 | 22 | |
| 23 | 23 | #include <linux/compat.h> |
| 24 | +#include <linux/efi.h> | |
| 24 | 25 | #include <linux/export.h> |
| 25 | 26 | #include <linux/sched.h> |
| 26 | 27 | #include <linux/kernel.h> |
| @@ -150,6 +151,13 @@ void machine_restart(char *cmd) · 123 unmodified lines | ||
| 150 | 151 | local_irq_disable(); |
| 151 | 152 | smp_send_stop(); |
| 152 | 153 | |
| 154 | + /* | |
| 155 | + * UpdateCapsule() depends on the system being reset via | |
| 156 | + * ResetSystem(). | |
| 157 | + */ | |
| 158 | + if (efi_enabled(EFI_RUNTIME_SERVICES)) | |
| 159 | + efi_reboot(reboot_mode, NULL); | |
| 160 | + | |
| 153 | 161 | /* Now call the architecture specific reboot code. */ |
| 154 | 162 | if (arm_pm_restart) |
| 155 | 163 | arm_pm_restart(reboot_mode, cmd); |
| @@ -51,7 +51,7 @@ static int __init early_coherent_pool(char *p) · 50 unmodified lines | ||
| 51 | 51 | } |
| 52 | 52 | early_param("coherent_pool", early_coherent_pool); |
| 53 | 53 | |
| 54 | −static void *__alloc_from_pool(size_t size, struct page **ret_page) | |
| 54 | +static void *__alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags) | |
| 55 | 55 | { |
| 56 | 56 | unsigned long val; |
| 57 | 57 | void *ptr = NULL; |
| @@ -67,6 +67,8 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) · 9 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | *ret_page = phys_to_page(phys); |
| 69 | 69 | ptr = (void *)val; |
| 70 | + if (flags & __GFP_ZERO) | |
| 71 | + memset(ptr, 0, size); | |
| 70 | 72 | } |
| 71 | 73 | |
| 72 | 74 | return ptr; |
| @@ -101,6 +103,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size, · 28 unmodified lines | ||
| 101 | 103 | flags |= GFP_DMA; |
| 102 | 104 | if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) { |
| 103 | 105 | struct page *page; |
| 106 | + void *addr; | |
| 104 | 107 | |
| 105 | 108 | size = PAGE_ALIGN(size); |
| 106 | 109 | page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, |
| @@ -109,7 +112,10 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size, · 2 unmodified lines | ||
| 109 | 112 | return NULL; |
| 110 | 113 | |
| 111 | 114 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); |
| 112 | − return page_address(page); | |
| 115 | + addr = page_address(page); | |
| 116 | + if (flags & __GFP_ZERO) | |
| 117 | + memset(addr, 0, size); | |
| 118 | + return addr; | |
| 113 | 119 | } else { |
| 114 | 120 | return swiotlb_alloc_coherent(dev, size, dma_handle, flags); |
| 115 | 121 | } |
| @@ -146,7 +152,7 @@ static void *__dma_alloc(struct device *dev, size_t size, · 30 unmodified lines | ||
| 146 | 152 | |
| 147 | 153 | if (!coherent && !(flags & __GFP_WAIT)) { |
| 148 | 154 | struct page *page = NULL; |
| 149 | − void *addr = __alloc_from_pool(size, &page); | |
| 155 | + void *addr = __alloc_from_pool(size, &page, flags); | |
| 150 | 156 | |
| 151 | 157 | if (addr) |
| 152 | 158 | *dma_handle = phys_to_dma(dev, page_to_phys(page)); |
| @@ -67,6 +67,11 @@ extern unsigned long empty_zero_page; · 66 unmodified lines | ||
| 67 | 67 | */ |
| 68 | 68 | #define pgtable_cache_init() do { } while (0) |
| 69 | 69 | |
| 70 | +/* | |
| 71 | + * c6x is !MMU, so define the simpliest implementation | |
| 72 | + */ | |
| 73 | +#define pgprot_writecombine pgprot_noncached | |
| 74 | + | |
| 70 | 75 | #include <asm-generic/pgtable.h> |
| 71 | 76 | |
| 72 | 77 | #endif /* _ASM_C6X_PGTABLE_H */ |
| @@ -348,8 +348,9 @@ C_ENTRY(_user_exception): · 347 unmodified lines | ||
| 348 | 348 | * The LP register should point to the location where the called function |
| 349 | 349 | * should return. [note that MAKE_SYS_CALL uses label 1] */ |
| 350 | 350 | /* See if the system call number is valid */ |
| 351 | + blti r12, 5f | |
| 351 | 352 | addi r11, r12, -__NR_syscalls; |
| 352 | − bgei r11,5f; | |
| 353 | + bgei r11, 5f; | |
| 353 | 354 | /* Figure out which function to use for this system call. */ |
| 354 | 355 | /* Note Microblaze barrel shift is optional, so don't rely on it */ |
| 355 | 356 | add r12, r12, r12; /* convert num -> ptr */ |
| @@ -375,7 +376,7 @@ C_ENTRY(_user_exception): · 19 unmodified lines | ||
| 375 | 376 | |
| 376 | 377 | /* The syscall number is invalid, return an error. */ |
| 377 | 378 | 5: |
| 378 | − rtsd r15, 8; /* looks like a normal subroutine return */ | |
| 379 | + braid ret_from_trap | |
| 379 | 380 | addi r3, r0, -ENOSYS; |
| 380 | 381 | |
| 381 | 382 | /* Entry point used to return from a syscall/trap */ |
| @@ -411,7 +412,7 @@ C_ENTRY(ret_from_trap): · 29 unmodified lines | ||
| 411 | 412 | bri 1b |
| 412 | 413 | |
| 413 | 414 | /* Maybe handle a signal */ |
| 414 | −5: | |
| 415 | +5: | |
| 415 | 416 | andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME; |
| 416 | 417 | beqi r11, 4f; /* Signals to handle, handle them */ |
| 417 | 418 | |
| @@ -15,7 +15,54 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include <uapi/asm/ptrace.h> |
| 17 | 17 | |
| 18 | +/* This struct defines the way the registers are stored on the | |
| 19 | + stack during a system call. */ | |
| 20 | + | |
| 18 | 21 | #ifndef __ASSEMBLY__ |
| 22 | +struct pt_regs { | |
| 23 | + unsigned long r8; /* r8-r15 Caller-saved GP registers */ | |
| 24 | + unsigned long r9; | |
| 25 | + unsigned long r10; | |
| 26 | + unsigned long r11; | |
| 27 | + unsigned long r12; | |
| 28 | + unsigned long r13; | |
| 29 | + unsigned long r14; | |
| 30 | + unsigned long r15; | |
| 31 | + unsigned long r1; /* Assembler temporary */ | |
| 32 | + unsigned long r2; /* Retval LS 32bits */ | |
| 33 | + unsigned long r3; /* Retval MS 32bits */ | |
| 34 | + unsigned long r4; /* r4-r7 Register arguments */ | |
| 35 | + unsigned long r5; | |
| 36 | + unsigned long r6; | |
| 37 | + unsigned long r7; | |
| 38 | + unsigned long orig_r2; /* Copy of r2 ?? */ | |
| 39 | + unsigned long ra; /* Return address */ | |
| 40 | + unsigned long fp; /* Frame pointer */ | |
| 41 | + unsigned long sp; /* Stack pointer */ | |
| 42 | + unsigned long gp; /* Global pointer */ | |
| 43 | + unsigned long estatus; | |
| 44 | + unsigned long ea; /* Exception return address (pc) */ | |
| 45 | + unsigned long orig_r7; | |
| 46 | +}; | |
| 47 | + | |
| 48 | +/* | |
| 49 | + * This is the extended stack used by signal handlers and the context | |
| 50 | + * switcher: it's pushed after the normal "struct pt_regs". | |
| 51 | + */ | |
| 52 | +struct switch_stack { | |
| 53 | + unsigned long r16; /* r16-r23 Callee-saved GP registers */ | |
| 54 | + unsigned long r17; | |
| 55 | + unsigned long r18; | |
| 56 | + unsigned long r19; | |
| 57 | + unsigned long r20; | |
| 58 | + unsigned long r21; | |
| 59 | + unsigned long r22; | |
| 60 | + unsigned long r23; | |
| 61 | + unsigned long fp; | |
| 62 | + unsigned long gp; | |
| 63 | + unsigned long ra; | |
| 64 | +}; | |
| 65 | + | |
| 19 | 66 | #define user_mode(regs) (((regs)->estatus & ESTATUS_EU)) |
| 20 | 67 | |
| 21 | 68 | #define instruction_pointer(regs) ((regs)->ra) |
| @@ -1,32 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch> | |
| 3 | − * Copyright (C) 2004 Microtronix Datacom Ltd | |
| 4 | − * | |
| 5 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 6 | − * License. See the file "COPYING" in the main directory of this archive | |
| 7 | − * for more details. | |
| 8 | − */ | |
| 9 | − | |
| 10 | −#ifndef _ASM_NIOS2_UCONTEXT_H | |
| 11 | −#define _ASM_NIOS2_UCONTEXT_H | |
| 12 | − | |
| 13 | −typedef int greg_t; | |
| 14 | −#define NGREG 32 | |
| 15 | −typedef greg_t gregset_t[NGREG]; | |
| 16 | − | |
| 17 | −struct mcontext { | |
| 18 | − int version; | |
| 19 | − gregset_t gregs; | |
| 20 | −}; | |
| 21 | − | |
| 22 | −#define MCONTEXT_VERSION 2 | |
| 23 | − | |
| 24 | −struct ucontext { | |
| 25 | − unsigned long uc_flags; | |
| 26 | − struct ucontext *uc_link; | |
| 27 | − stack_t uc_stack; | |
| 28 | − struct mcontext uc_mcontext; | |
| 29 | − sigset_t uc_sigmask; /* mask last for extensibility */ | |
| 30 | −}; | |
| 31 | − | |
| 32 | −#endif | |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | include include/uapi/asm-generic/Kbuild.asm |
| 2 | 2 | |
| 3 | 3 | header-y += elf.h |
| 4 | −header-y += ucontext.h | |
| 4 | + | |
| 5 | +generic-y += ucontext.h | |
| @@ -50,9 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | typedef unsigned long elf_greg_t; |
| 52 | 52 | |
| 53 | −#define ELF_NGREG \ | |
| 54 | − ((sizeof(struct pt_regs) + sizeof(struct switch_stack)) / \ | |
| 55 | − sizeof(elf_greg_t)) | |
| 53 | +#define ELF_NGREG 49 | |
| 56 | 54 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
| 57 | 55 | |
| 58 | 56 | typedef unsigned long elf_fpregset_t; |
| @@ -67,53 +67,9 @@ · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | #define NUM_PTRACE_REG (PTR_TLBMISC + 1) |
| 69 | 69 | |
| 70 | −/* this struct defines the way the registers are stored on the | |
| 71 | − stack during a system call. | |
| 72 | − | |
| 73 | − There is a fake_regs in setup.c that has to match pt_regs.*/ | |
| 74 | − | |
| 75 | −struct pt_regs { | |
| 76 | − unsigned long r8; /* r8-r15 Caller-saved GP registers */ | |
| 77 | − unsigned long r9; | |
| 78 | − unsigned long r10; | |
| 79 | − unsigned long r11; | |
| 80 | − unsigned long r12; | |
| 81 | − unsigned long r13; | |
| 82 | − unsigned long r14; | |
| 83 | − unsigned long r15; | |
| 84 | − unsigned long r1; /* Assembler temporary */ | |
| 85 | − unsigned long r2; /* Retval LS 32bits */ | |
| 86 | − unsigned long r3; /* Retval MS 32bits */ | |
| 87 | − unsigned long r4; /* r4-r7 Register arguments */ | |
| 88 | − unsigned long r5; | |
| 89 | − unsigned long r6; | |
| 90 | − unsigned long r7; | |
| 91 | − unsigned long orig_r2; /* Copy of r2 ?? */ | |
| 92 | − unsigned long ra; /* Return address */ | |
| 93 | − unsigned long fp; /* Frame pointer */ | |
| 94 | − unsigned long sp; /* Stack pointer */ | |
| 95 | − unsigned long gp; /* Global pointer */ | |
| 96 | − unsigned long estatus; | |
| 97 | − unsigned long ea; /* Exception return address (pc) */ | |
| 98 | − unsigned long orig_r7; | |
| 99 | −}; | |
| 100 | − | |
| 101 | −/* | |
| 102 | − * This is the extended stack used by signal handlers and the context | |
| 103 | − * switcher: it's pushed after the normal "struct pt_regs". | |
| 104 | − */ | |
| 105 | −struct switch_stack { | |
| 106 | − unsigned long r16; /* r16-r23 Callee-saved GP registers */ | |
| 107 | − unsigned long r17; | |
| 108 | − unsigned long r18; | |
| 109 | − unsigned long r19; | |
| 110 | − unsigned long r20; | |
| 111 | − unsigned long r21; | |
| 112 | − unsigned long r22; | |
| 113 | − unsigned long r23; | |
| 114 | − unsigned long fp; | |
| 115 | − unsigned long gp; | |
| 116 | − unsigned long ra; | |
| 70 | +/* User structures for general purpose registers. */ | |
| 71 | +struct user_pt_regs { | |
| 72 | + __u32 regs[49]; | |
| 117 | 73 | }; |
| 118 | 74 | |
| 119 | 75 | #endif /* __ASSEMBLY__ */ |
| @@ -15,14 +15,16 @@ · 14 unmodified lines | ||
| 15 | 15 | * details. |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | −#ifndef _ASM_NIOS2_SIGCONTEXT_H | |
| 19 | −#define _ASM_NIOS2_SIGCONTEXT_H | |
| 18 | +#ifndef _UAPI__ASM_SIGCONTEXT_H | |
| 19 | +#define _UAPI__ASM_SIGCONTEXT_H | |
| 20 | 20 | |
| 21 | −#include <asm/ptrace.h> | |
| 21 | +#include <linux/types.h> | |
| 22 | + | |
| 23 | +#define MCONTEXT_VERSION 2 | |
| 22 | 24 | |
| 23 | 25 | struct sigcontext { |
| 24 | − struct pt_regs regs; | |
| 25 | − unsigned long sc_mask; /* old sigmask */ | |
| 26 | + int version; | |
| 27 | + unsigned long gregs[32]; | |
| 26 | 28 | }; |
| 27 | 29 | |
| 28 | 30 | #endif |
| @@ -39,7 +39,7 @@ static inline int rt_restore_ucontext(struct pt_regs *regs, · 38 unmodified lines | ||
| 39 | 39 | struct ucontext *uc, int *pr2) |
| 40 | 40 | { |
| 41 | 41 | int temp; |
| 42 | − greg_t *gregs = uc->uc_mcontext.gregs; | |
| 42 | + unsigned long *gregs = uc->uc_mcontext.gregs; | |
| 43 | 43 | int err; |
| 44 | 44 | |
| 45 | 45 | /* Always make any pending restarted system calls return -EINTR */ |
| @@ -127,7 +127,7 @@ badframe: · 81 unmodified lines | ||
| 127 | 127 | static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) |
| 128 | 128 | { |
| 129 | 129 | struct switch_stack *sw = (struct switch_stack *)regs - 1; |
| 130 | − greg_t *gregs = uc->uc_mcontext.gregs; | |
| 130 | + unsigned long *gregs = uc->uc_mcontext.gregs; | |
| 131 | 131 | int err = 0; |
| 132 | 132 | |
| 133 | 133 | err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); |
| @@ -126,7 +126,6 @@ good_area: · 125 unmodified lines | ||
| 126 | 126 | break; |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | −survive: | |
| 130 | 129 | /* |
| 131 | 130 | * If for any reason at all we couldn't handle the fault, |
| 132 | 131 | * make sure we exit gracefully rather than endlessly redo |
| @@ -220,11 +219,6 @@ no_context: · 87 unmodified lines | ||
| 220 | 219 | */ |
| 221 | 220 | out_of_memory: |
| 222 | 221 | up_read(&mm->mmap_sem); |
| 223 | − if (is_global_init(tsk)) { | |
| 224 | − yield(); | |
| 225 | − down_read(&mm->mmap_sem); | |
| 226 | − goto survive; | |
| 227 | − } | |
| 228 | 222 | if (!user_mode(regs)) |
| 229 | 223 | goto no_context; |
| 230 | 224 | pagefault_out_of_memory(); |
| @@ -515,15 +515,15 @@ struct s390_io_adapter { · 514 unmodified lines | ||
| 515 | 515 | #define S390_ARCH_FAC_MASK_SIZE_U64 \ |
| 516 | 516 | (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) |
| 517 | 517 | |
| 518 | −struct s390_model_fac { | |
| 519 | − /* facilities used in SIE context */ | |
| 520 | − __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; | |
| 521 | − /* subset enabled by kvm */ | |
| 522 | − __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; | |
| 518 | +struct kvm_s390_fac { | |
| 519 | + /* facility list requested by guest */ | |
| 520 | + __u64 list[S390_ARCH_FAC_LIST_SIZE_U64]; | |
| 521 | + /* facility mask supported by kvm & hosting machine */ | |
| 522 | + __u64 mask[S390_ARCH_FAC_LIST_SIZE_U64]; | |
| 523 | 523 | }; |
| 524 | 524 | |
| 525 | 525 | struct kvm_s390_cpu_model { |
| 526 | − struct s390_model_fac *fac; | |
| 526 | + struct kvm_s390_fac *fac; | |
| 527 | 527 | struct cpuid cpu_id; |
| 528 | 528 | unsigned short ibc; |
| 529 | 529 | }; |
| @@ -62,6 +62,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, · 61 unmodified lines | ||
| 62 | 62 | { |
| 63 | 63 | int cpu = smp_processor_id(); |
| 64 | 64 | |
| 65 | + S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | |
| 65 | 66 | if (prev == next) |
| 66 | 67 | return; |
| 67 | 68 | if (MACHINE_HAS_TLB_LC) |
| @@ -73,7 +74,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, · 5 unmodified lines | ||
| 73 | 74 | atomic_dec(&prev->context.attach_count); |
| 74 | 75 | if (MACHINE_HAS_TLB_LC) |
| 75 | 76 | cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask); |
| 76 | − S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd); | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | #define finish_arch_post_lock_switch finish_arch_post_lock_switch |
| @@ -37,16 +37,7 @@ static inline void storage_key_init_range(unsigned long start, unsigned long end · 36 unmodified lines | ||
| 37 | 37 | #endif |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | −static inline void clear_page(void *page) | |
| 41 | −{ | |
| 42 | − register unsigned long reg1 asm ("1") = 0; | |
| 43 | − register void *reg2 asm ("2") = page; | |
| 44 | − register unsigned long reg3 asm ("3") = 4096; | |
| 45 | − asm volatile( | |
| 46 | − " mvcl 2,0" | |
| 47 | − : "+d" (reg2), "+d" (reg3) : "d" (reg1) | |
| 48 | − : "memory", "cc"); | |
| 49 | −} | |
| 40 | +#define clear_page(page) memset((page), 0, PAGE_SIZE) | |
| 50 | 41 | |
| 51 | 42 | /* |
| 52 | 43 | * copy_page uses the mvcl instruction with 0xb0 padding byte in order to |
| @@ -36,16 +36,20 @@ static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn) · 35 unmodified lines | ||
| 36 | 36 | insn->offset = (entry->target - entry->code) >> 1; |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | −static void jump_label_bug(struct jump_entry *entry, struct insn *insn) | |
| 39 | +static void jump_label_bug(struct jump_entry *entry, struct insn *expected, | |
| 40 | + struct insn *new) | |
| 40 | 41 | { |
| 41 | 42 | unsigned char *ipc = (unsigned char *)entry->code; |
| 42 | − unsigned char *ipe = (unsigned char *)insn; | |
| 43 | + unsigned char *ipe = (unsigned char *)expected; | |
| 44 | + unsigned char *ipn = (unsigned char *)new; | |
| 43 | 45 | |
| 44 | 46 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); |
| 45 | 47 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", |
| 46 | 48 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); |
| 47 | 49 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", |
| 48 | 50 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); |
| 51 | + pr_emerg("New: %02x %02x %02x %02x %02x %02x\n", | |
| 52 | + ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]); | |
| 49 | 53 | panic("Corrupted kernel text"); |
| 50 | 54 | } |
| 51 | 55 | |
| @@ -69,10 +73,10 @@ static void __jump_label_transform(struct jump_entry *entry, · 17 unmodified lines | ||
| 69 | 73 | } |
| 70 | 74 | if (init) { |
| 71 | 75 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) |
| 72 | − jump_label_bug(entry, &old); | |
| 76 | + jump_label_bug(entry, &orignop, &new); | |
| 73 | 77 | } else { |
| 74 | 78 | if (memcmp((void *)entry->code, &old, sizeof(old))) |
| 75 | − jump_label_bug(entry, &old); | |
| 79 | + jump_label_bug(entry, &old, &new); | |
| 76 | 80 | } |
| 77 | 81 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); |
| 78 | 82 | } |
| @@ -436,6 +436,7 @@ int module_finalize(const Elf_Ehdr *hdr, · 435 unmodified lines | ||
| 436 | 436 | const Elf_Shdr *sechdrs, |
| 437 | 437 | struct module *me) |
| 438 | 438 | { |
| 439 | + jump_label_apply_nops(me); | |
| 439 | 440 | vfree(me->arch.syminfo); |
| 440 | 441 | me->arch.syminfo = NULL; |
| 441 | 442 | return 0; |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); |
| 20 | 20 | |
| 21 | −void cpu_relax(void) | |
| 21 | +void notrace cpu_relax(void) | |
| 22 | 22 | { |
| 23 | 23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) |
| 24 | 24 | asm volatile("diag 0,0,0x44"); |
| @@ -165,7 +165,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 164 unmodified lines | ||
| 165 | 165 | case KVM_CAP_ONE_REG: |
| 166 | 166 | case KVM_CAP_ENABLE_CAP: |
| 167 | 167 | case KVM_CAP_S390_CSS_SUPPORT: |
| 168 | − case KVM_CAP_IRQFD: | |
| 169 | 168 | case KVM_CAP_IOEVENTFD: |
| 170 | 169 | case KVM_CAP_DEVICE_CTRL: |
| 171 | 170 | case KVM_CAP_ENABLE_CAP_VM: |
| @@ -522,7 +521,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) · 350 unmodified lines | ||
| 522 | 521 | memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, |
| 523 | 522 | sizeof(struct cpuid)); |
| 524 | 523 | kvm->arch.model.ibc = proc->ibc; |
| 525 | − memcpy(kvm->arch.model.fac->kvm, proc->fac_list, | |
| 524 | + memcpy(kvm->arch.model.fac->list, proc->fac_list, | |
| 526 | 525 | S390_ARCH_FAC_LIST_SIZE_BYTE); |
| 527 | 526 | } else |
| 528 | 527 | ret = -EFAULT; |
| @@ -556,7 +555,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) · 27 unmodified lines | ||
| 556 | 555 | } |
| 557 | 556 | memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); |
| 558 | 557 | proc->ibc = kvm->arch.model.ibc; |
| 559 | − memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 558 | + memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 560 | 559 | if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) |
| 561 | 560 | ret = -EFAULT; |
| 562 | 561 | kfree(proc); |
| @@ -576,10 +575,10 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) · 13 unmodified lines | ||
| 576 | 575 | } |
| 577 | 576 | get_cpu_id((struct cpuid *) &mach->cpuid); |
| 578 | 577 | mach->ibc = sclp_get_ibc(); |
| 579 | − memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, | |
| 580 | − kvm_s390_fac_list_mask_size() * sizeof(u64)); | |
| 578 | + memcpy(&mach->fac_mask, kvm->arch.model.fac->mask, | |
| 579 | + S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 581 | 580 | memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, |
| 582 | − S390_ARCH_FAC_LIST_SIZE_U64); | |
| 581 | + S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 583 | 582 | if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) |
| 584 | 583 | ret = -EFAULT; |
| 585 | 584 | kfree(mach); |
| @@ -778,15 +777,18 @@ long kvm_arch_vm_ioctl(struct file *filp, · 192 unmodified lines | ||
| 778 | 777 | static int kvm_s390_query_ap_config(u8 *config) |
| 779 | 778 | { |
| 780 | 779 | u32 fcn_code = 0x04000000UL; |
| 781 | − u32 cc; | |
| 780 | + u32 cc = 0; | |
| 782 | 781 | |
| 782 | + memset(config, 0, 128); | |
| 783 | 783 | asm volatile( |
| 784 | 784 | "lgr 0,%1\n" |
| 785 | 785 | "lgr 2,%2\n" |
| 786 | 786 | ".long 0xb2af0000\n" /* PQAP(QCI) */ |
| 787 | − "ipm %0\n" | |
| 787 | + "0: ipm %0\n" | |
| 788 | 788 | "srl %0,28\n" |
| 789 | − : "=r" (cc) | |
| 789 | + "1:\n" | |
| 790 | + EX_TABLE(0b, 1b) | |
| 791 | + : "+r" (cc) | |
| 790 | 792 | : "r" (fcn_code), "r" (config) |
| 791 | 793 | : "cc", "0", "2", "memory" |
| 792 | 794 | ); |
| @@ -839,9 +841,13 @@ static int kvm_s390_crypto_init(struct kvm *kvm) · 46 unmodified lines | ||
| 839 | 841 | |
| 840 | 842 | kvm_s390_set_crycb_format(kvm); |
| 841 | 843 | |
| 842 | − /* Disable AES/DEA protected key functions by default */ | |
| 843 | − kvm->arch.crypto.aes_kw = 0; | |
| 844 | − kvm->arch.crypto.dea_kw = 0; | |
| 844 | + /* Enable AES/DEA protected key functions by default */ | |
| 845 | + kvm->arch.crypto.aes_kw = 1; | |
| 846 | + kvm->arch.crypto.dea_kw = 1; | |
| 847 | + get_random_bytes(kvm->arch.crypto.crycb->aes_wrapping_key_mask, | |
| 848 | + sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask)); | |
| 849 | + get_random_bytes(kvm->arch.crypto.crycb->dea_wrapping_key_mask, | |
| 850 | + sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask)); | |
| 845 | 851 | |
| 846 | 852 | return 0; |
| 847 | 853 | } |
| @@ -886,40 +892,29 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 38 unmodified lines | ||
| 886 | 892 | /* |
| 887 | 893 | * The architectural maximum amount of facilities is 16 kbit. To store |
| 888 | 894 | * this amount, 2 kbyte of memory is required. Thus we need a full |
| 889 | − * page to hold the active copy (arch.model.fac->sie) and the current | |
| 890 | − * facilities set (arch.model.fac->kvm). Its address size has to be | |
| 895 | + * page to hold the guest facility list (arch.model.fac->list) and the | |
| 896 | + * facility mask (arch.model.fac->mask). Its address size has to be | |
| 891 | 897 | * 31 bits and word aligned. |
| 892 | 898 | */ |
| 893 | 899 | kvm->arch.model.fac = |
| 894 | − (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | |
| 900 | + (struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | |
| 895 | 901 | if (!kvm->arch.model.fac) |
| 896 | 902 | goto out_nofac; |
| 897 | 903 | |
| 898 | − memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, | |
| 899 | − S390_ARCH_FAC_LIST_SIZE_U64); | |
| 900 | − | |
| 901 | − /* | |
| 902 | − * If this KVM host runs *not* in a LPAR, relax the facility bits | |
| 903 | − * of the kvm facility mask by all missing facilities. This will allow | |
| 904 | − * to determine the right CPU model by means of the remaining facilities. | |
| 905 | − * Live guest migration must prohibit the migration of KVMs running in | |
| 906 | − * a LPAR to non LPAR hosts. | |
| 907 | − */ | |
| 908 | − if (!MACHINE_IS_LPAR) | |
| 909 | − for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) | |
| 910 | − kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i]; | |
| 911 | − | |
| 912 | − /* | |
| 913 | − * Apply the kvm facility mask to limit the kvm supported/tolerated | |
| 914 | − * facility list. | |
| 915 | − */ | |
| 904 | + /* Populate the facility mask initially. */ | |
| 905 | + memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list, | |
| 906 | + S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 916 | 907 | for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { |
| 917 | 908 | if (i < kvm_s390_fac_list_mask_size()) |
| 918 | − kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; | |
| 909 | + kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i]; | |
| 919 | 910 | else |
| 920 | − kvm->arch.model.fac->kvm[i] = 0UL; | |
| 911 | + kvm->arch.model.fac->mask[i] = 0UL; | |
| 921 | 912 | } |
| 922 | 913 | |
| 914 | + /* Populate the facility list initially. */ | |
| 915 | + memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask, | |
| 916 | + S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 917 | + | |
| 923 | 918 | kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); |
| 924 | 919 | kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; |
| 925 | 920 | |
| @@ -1165,8 +1160,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) · 239 unmodified lines | ||
| 1165 | 1160 | |
| 1166 | 1161 | mutex_lock(&vcpu->kvm->lock); |
| 1167 | 1162 | vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; |
| 1168 | − memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm, | |
| 1169 | − S390_ARCH_FAC_LIST_SIZE_BYTE); | |
| 1170 | 1163 | vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; |
| 1171 | 1164 | mutex_unlock(&vcpu->kvm->lock); |
| 1172 | 1165 | |
| @@ -1212,7 +1205,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, · 39 unmodified lines | ||
| 1212 | 1205 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; |
| 1213 | 1206 | set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); |
| 1214 | 1207 | } |
| 1215 | − vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; | |
| 1208 | + vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->list; | |
| 1216 | 1209 | |
| 1217 | 1210 | spin_lock_init(&vcpu->arch.local_int.lock); |
| 1218 | 1211 | vcpu->arch.local_int.float_int = &kvm->arch.float_int; |
| @@ -128,7 +128,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc) · 127 unmodified lines | ||
| 128 | 128 | /* test availability of facility in a kvm intance */ |
| 129 | 129 | static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) |
| 130 | 130 | { |
| 131 | − return __test_facility(nr, kvm->arch.model.fac->kvm); | |
| 131 | + return __test_facility(nr, kvm->arch.model.fac->mask) && | |
| 132 | + __test_facility(nr, kvm->arch.model.fac->list); | |
| 132 | 133 | } |
| 133 | 134 | |
| 134 | 135 | /* are cpu states controlled by user space */ |
| @@ -348,7 +348,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) · 347 unmodified lines | ||
| 348 | 348 | * We need to shift the lower 32 facility bits (bit 0-31) from a u64 |
| 349 | 349 | * into a u32 memory representation. They will remain bits 0-31. |
| 350 | 350 | */ |
| 351 | − fac = *vcpu->kvm->arch.model.fac->sie >> 32; | |
| 351 | + fac = *vcpu->kvm->arch.model.fac->list >> 32; | |
| 352 | 352 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), |
| 353 | 353 | &fac, sizeof(fac)); |
| 354 | 354 | if (rc) |
| @@ -287,7 +287,7 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev, · 286 unmodified lines | ||
| 287 | 287 | addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); |
| 288 | 288 | return (void __iomem *) addr + offset; |
| 289 | 289 | } |
| 290 | −EXPORT_SYMBOL_GPL(pci_iomap_range); | |
| 290 | +EXPORT_SYMBOL(pci_iomap_range); | |
| 291 | 291 | |
| 292 | 292 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) |
| 293 | 293 | { |
| @@ -309,7 +309,7 @@ void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) · 15 unmodified lines | ||
| 309 | 309 | } |
| 310 | 310 | spin_unlock(&zpci_iomap_lock); |
| 311 | 311 | } |
| 312 | −EXPORT_SYMBOL_GPL(pci_iounmap); | |
| 312 | +EXPORT_SYMBOL(pci_iounmap); | |
| 313 | 313 | |
| 314 | 314 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
| 315 | 315 | int size, u32 *val) |
| @@ -483,9 +483,8 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) · 167 unmodified lines | ||
| 483 | 483 | airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | −static void zpci_map_resources(struct zpci_dev *zdev) | |
| 486 | +static void zpci_map_resources(struct pci_dev *pdev) | |
| 487 | 487 | { |
| 488 | − struct pci_dev *pdev = zdev->pdev; | |
| 489 | 488 | resource_size_t len; |
| 490 | 489 | int i; |
| 491 | 490 | |
| @@ -499,9 +498,8 @@ static void zpci_map_resources(struct zpci_dev *zdev) · 7 unmodified lines | ||
| 499 | 498 | } |
| 500 | 499 | } |
| 501 | 500 | |
| 502 | −static void zpci_unmap_resources(struct zpci_dev *zdev) | |
| 501 | +static void zpci_unmap_resources(struct pci_dev *pdev) | |
| 503 | 502 | { |
| 504 | − struct pci_dev *pdev = zdev->pdev; | |
| 505 | 503 | resource_size_t len; |
| 506 | 504 | int i; |
| 507 | 505 | |
| @@ -651,7 +649,7 @@ int pcibios_add_device(struct pci_dev *pdev) · 143 unmodified lines | ||
| 651 | 649 | |
| 652 | 650 | zdev->pdev = pdev; |
| 653 | 651 | pdev->dev.groups = zpci_attr_groups; |
| 654 | − zpci_map_resources(zdev); | |
| 652 | + zpci_map_resources(pdev); | |
| 655 | 653 | |
| 656 | 654 | for (i = 0; i < PCI_BAR_COUNT; i++) { |
| 657 | 655 | res = &pdev->resource[i]; |
| @@ -663,6 +661,11 @@ int pcibios_add_device(struct pci_dev *pdev) · 5 unmodified lines | ||
| 663 | 661 | return 0; |
| 664 | 662 | } |
| 665 | 663 | |
| 664 | +void pcibios_release_device(struct pci_dev *pdev) | |
| 665 | +{ | |
| 666 | + zpci_unmap_resources(pdev); | |
| 667 | +} | |
| 668 | + | |
| 666 | 669 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
| 667 | 670 | { |
| 668 | 671 | struct zpci_dev *zdev = get_zdev(pdev); |
| @@ -670,7 +673,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) · 1 unmodified line | ||
| 670 | 673 | zdev->pdev = pdev; |
| 671 | 674 | zpci_debug_init_device(zdev); |
| 672 | 675 | zpci_fmb_enable_device(zdev); |
| 673 | − zpci_map_resources(zdev); | |
| 674 | 676 | |
| 675 | 677 | return pci_enable_resources(pdev, mask); |
| 676 | 678 | } |
| @@ -679,7 +681,6 @@ void pcibios_disable_device(struct pci_dev *pdev) · 2 unmodified lines | ||
| 679 | 681 | { |
| 680 | 682 | struct zpci_dev *zdev = get_zdev(pdev); |
| 681 | 683 | |
| 682 | − zpci_unmap_resources(zdev); | |
| 683 | 684 | zpci_fmb_disable_device(zdev); |
| 684 | 685 | zpci_debug_exit_device(zdev); |
| 685 | 686 | zdev->pdev = NULL; |
| @@ -688,7 +689,8 @@ void pcibios_disable_device(struct pci_dev *pdev) · 2 unmodified lines | ||
| 688 | 689 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
| 689 | 690 | static int zpci_restore(struct device *dev) |
| 690 | 691 | { |
| 691 | − struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); | |
| 692 | + struct pci_dev *pdev = to_pci_dev(dev); | |
| 693 | + struct zpci_dev *zdev = get_zdev(pdev); | |
| 692 | 694 | int ret = 0; |
| 693 | 695 | |
| 694 | 696 | if (zdev->state != ZPCI_FN_STATE_ONLINE) |
| @@ -698,7 +700,7 @@ static int zpci_restore(struct device *dev) · 3 unmodified lines | ||
| 698 | 700 | if (ret) |
| 699 | 701 | goto out; |
| 700 | 702 | |
| 701 | − zpci_map_resources(zdev); | |
| 703 | + zpci_map_resources(pdev); | |
| 702 | 704 | zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, |
| 703 | 705 | zdev->start_dma + zdev->iommu_size - 1, |
| 704 | 706 | (u64) zdev->dma_table); |
| @@ -709,12 +711,14 @@ out: · 4 unmodified lines | ||
| 709 | 711 | |
| 710 | 712 | static int zpci_freeze(struct device *dev) |
| 711 | 713 | { |
| 712 | − struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); | |
| 714 | + struct pci_dev *pdev = to_pci_dev(dev); | |
| 715 | + struct zpci_dev *zdev = get_zdev(pdev); | |
| 713 | 716 | |
| 714 | 717 | if (zdev->state != ZPCI_FN_STATE_ONLINE) |
| 715 | 718 | return 0; |
| 716 | 719 | |
| 717 | 720 | zpci_unregister_ioat(zdev, 0); |
| 721 | + zpci_unmap_resources(pdev); | |
| 718 | 722 | return clp_disable_fh(zdev); |
| 719 | 723 | } |
| 720 | 724 | |
| @@ -64,8 +64,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, · 63 unmodified lines | ||
| 64 | 64 | if (copy_from_user(buf, user_buffer, length)) |
| 65 | 65 | goto out; |
| 66 | 66 | |
| 67 | − memcpy_toio(io_addr, buf, length); | |
| 68 | − ret = 0; | |
| 67 | + ret = zpci_memcpy_toio(io_addr, buf, length); | |
| 69 | 68 | out: |
| 70 | 69 | if (buf != local_buf) |
| 71 | 70 | kfree(buf); |
| @@ -98,16 +97,16 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, · 26 unmodified lines | ||
| 98 | 97 | goto out; |
| 99 | 98 | io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); |
| 100 | 99 | |
| 101 | − ret = -EFAULT; | |
| 102 | − if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) | |
| 100 | + if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) { | |
| 101 | + ret = -EFAULT; | |
| 103 | 102 | goto out; |
| 104 | − | |
| 105 | − memcpy_fromio(buf, io_addr, length); | |
| 106 | − | |
| 107 | − if (copy_to_user(user_buffer, buf, length)) | |
| 103 | + } | |
| 104 | + ret = zpci_memcpy_fromio(buf, io_addr, length); | |
| 105 | + if (ret) | |
| 108 | 106 | goto out; |
| 107 | + if (copy_to_user(user_buffer, buf, length)) | |
| 108 | + ret = -EFAULT; | |
| 109 | 109 | |
| 110 | − ret = 0; | |
| 111 | 110 | out: |
| 112 | 111 | if (buf != local_buf) |
| 113 | 112 | kfree(buf); |
| @@ -86,6 +86,9 @@ config ARCH_DEFCONFIG · 85 unmodified lines | ||
| 86 | 86 | default "arch/sparc/configs/sparc32_defconfig" if SPARC32 |
| 87 | 87 | default "arch/sparc/configs/sparc64_defconfig" if SPARC64 |
| 88 | 88 | |
| 89 | +config ARCH_PROC_KCORE_TEXT | |
| 90 | + def_bool y | |
| 91 | + | |
| 89 | 92 | config IOMMU_HELPER |
| 90 | 93 | bool |
| 91 | 94 | default y if SPARC64 |
| @@ -407,16 +407,16 @@ static inline void iounmap(volatile void __iomem *addr) · 406 unmodified lines | ||
| 407 | 407 | { |
| 408 | 408 | } |
| 409 | 409 | |
| 410 | −#define ioread8(X) readb(X) | |
| 411 | −#define ioread16(X) readw(X) | |
| 412 | −#define ioread16be(X) __raw_readw(X) | |
| 413 | −#define ioread32(X) readl(X) | |
| 414 | −#define ioread32be(X) __raw_readl(X) | |
| 415 | −#define iowrite8(val,X) writeb(val,X) | |
| 416 | −#define iowrite16(val,X) writew(val,X) | |
| 417 | −#define iowrite16be(val,X) __raw_writew(val,X) | |
| 418 | −#define iowrite32(val,X) writel(val,X) | |
| 419 | −#define iowrite32be(val,X) __raw_writel(val,X) | |
| 410 | +#define ioread8 readb | |
| 411 | +#define ioread16 readw | |
| 412 | +#define ioread16be __raw_readw | |
| 413 | +#define ioread32 readl | |
| 414 | +#define ioread32be __raw_readl | |
| 415 | +#define iowrite8 writeb | |
| 416 | +#define iowrite16 writew | |
| 417 | +#define iowrite16be __raw_writew | |
| 418 | +#define iowrite32 writel | |
| 419 | +#define iowrite32be __raw_writel | |
| 420 | 420 | |
| 421 | 421 | /* Create a virtual mapping cookie for an IO port range */ |
| 422 | 422 | void __iomem *ioport_map(unsigned long port, unsigned int nr); |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | extern int this_is_starfire; |
| 13 | 13 | |
| 14 | 14 | void check_if_starfire(void); |
| 15 | −int starfire_hard_smp_processor_id(void); | |
| 16 | 15 | void starfire_hookup(int); |
| 17 | 16 | unsigned int starfire_translate(unsigned long imap, unsigned int upaid); |
| 18 | 17 | |
| @@ -98,11 +98,7 @@ void sun4v_do_mna(struct pt_regs *regs, · 97 unmodified lines | ||
| 98 | 98 | void do_privop(struct pt_regs *regs); |
| 99 | 99 | void do_privact(struct pt_regs *regs); |
| 100 | 100 | void do_cee(struct pt_regs *regs); |
| 101 | −void do_cee_tl1(struct pt_regs *regs); | |
| 102 | −void do_dae_tl1(struct pt_regs *regs); | |
| 103 | −void do_iae_tl1(struct pt_regs *regs); | |
| 104 | 101 | void do_div0_tl1(struct pt_regs *regs); |
| 105 | −void do_fpdis_tl1(struct pt_regs *regs); | |
| 106 | 102 | void do_fpieee_tl1(struct pt_regs *regs); |
| 107 | 103 | void do_fpother_tl1(struct pt_regs *regs); |
| 108 | 104 | void do_ill_tl1(struct pt_regs *regs); |
| @@ -1406,11 +1406,32 @@ void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) · 1405 unmodified lines | ||
| 1406 | 1406 | scheduler_ipi(); |
| 1407 | 1407 | } |
| 1408 | 1408 | |
| 1409 | −/* This is a nop because we capture all other cpus | |
| 1410 | − * anyways when making the PROM active. | |
| 1411 | − */ | |
| 1409 | +static void stop_this_cpu(void *dummy) | |
| 1410 | +{ | |
| 1411 | + prom_stopself(); | |
| 1412 | +} | |
| 1413 | + | |
| 1412 | 1414 | void smp_send_stop(void) |
| 1413 | 1415 | { |
| 1416 | + int cpu; | |
| 1417 | + | |
| 1418 | + if (tlb_type == hypervisor) { | |
| 1419 | + for_each_online_cpu(cpu) { | |
| 1420 | + if (cpu == smp_processor_id()) | |
| 1421 | + continue; | |
| 1422 | +#ifdef CONFIG_SUN_LDOMS | |
| 1423 | + if (ldom_domaining_enabled) { | |
| 1424 | + unsigned long hv_err; | |
| 1425 | + hv_err = sun4v_cpu_stop(cpu); | |
| 1426 | + if (hv_err) | |
| 1427 | + printk(KERN_ERR "sun4v_cpu_stop() " | |
| 1428 | + "failed err=%lu\n", hv_err); | |
| 1429 | + } else | |
| 1430 | +#endif | |
| 1431 | + prom_stopcpu_cpuid(cpu); | |
| 1432 | + } | |
| 1433 | + } else | |
| 1434 | + smp_call_function(stop_this_cpu, NULL, 0); | |
| 1414 | 1435 | } |
| 1415 | 1436 | |
| 1416 | 1437 | /** |
| @@ -28,11 +28,6 @@ void check_if_starfire(void) · 27 unmodified lines | ||
| 28 | 28 | this_is_starfire = 1; |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | −int starfire_hard_smp_processor_id(void) | |
| 32 | −{ | |
| 33 | − return upa_readl(0x1fff40000d0UL); | |
| 34 | −} | |
| 35 | − | |
| 36 | 31 | /* |
| 37 | 32 | * Each Starfire board has 32 registers which perform translation |
| 38 | 33 | * and delivery of traditional interrupt packets into the extended |
| @@ -333,7 +333,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second · 332 unmodified lines | ||
| 333 | 333 | long err; |
| 334 | 334 | |
| 335 | 335 | /* No need for backward compatibility. We can start fresh... */ |
| 336 | − if (call <= SEMCTL) { | |
| 336 | + if (call <= SEMTIMEDOP) { | |
| 337 | 337 | switch (call) { |
| 338 | 338 | case SEMOP: |
| 339 | 339 | err = sys_semtimedop(first, ptr, |
| @@ -2427,6 +2427,8 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs) · 2426 unmodified lines | ||
| 2427 | 2427 | } |
| 2428 | 2428 | user_instruction_dump ((unsigned int __user *) regs->tpc); |
| 2429 | 2429 | } |
| 2430 | + if (panic_on_oops) | |
| 2431 | + panic("Fatal exception"); | |
| 2430 | 2432 | if (regs->tstate & TSTATE_PRIV) |
| 2431 | 2433 | do_exit(SIGKILL); |
| 2432 | 2434 | do_exit(SIGSEGV); |
| @@ -2564,27 +2566,6 @@ void do_cee(struct pt_regs *regs) · 131 unmodified lines | ||
| 2564 | 2566 | die_if_kernel("TL0: Cache Error Exception", regs); |
| 2565 | 2567 | } |
| 2566 | 2568 | |
| 2567 | −void do_cee_tl1(struct pt_regs *regs) | |
| 2568 | −{ | |
| 2569 | − exception_enter(); | |
| 2570 | − dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | |
| 2571 | − die_if_kernel("TL1: Cache Error Exception", regs); | |
| 2572 | −} | |
| 2573 | − | |
| 2574 | −void do_dae_tl1(struct pt_regs *regs) | |
| 2575 | −{ | |
| 2576 | − exception_enter(); | |
| 2577 | − dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | |
| 2578 | − die_if_kernel("TL1: Data Access Exception", regs); | |
| 2579 | −} | |
| 2580 | − | |
| 2581 | −void do_iae_tl1(struct pt_regs *regs) | |
| 2582 | −{ | |
| 2583 | − exception_enter(); | |
| 2584 | − dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | |
| 2585 | − die_if_kernel("TL1: Instruction Access Exception", regs); | |
| 2586 | −} | |
| 2587 | − | |
| 2588 | 2569 | void do_div0_tl1(struct pt_regs *regs) |
| 2589 | 2570 | { |
| 2590 | 2571 | exception_enter(); |
| @@ -2592,13 +2573,6 @@ void do_div0_tl1(struct pt_regs *regs) · 1 unmodified line | ||
| 2592 | 2573 | die_if_kernel("TL1: DIV0 Exception", regs); |
| 2593 | 2574 | } |
| 2594 | 2575 | |
| 2595 | −void do_fpdis_tl1(struct pt_regs *regs) | |
| 2596 | −{ | |
| 2597 | − exception_enter(); | |
| 2598 | − dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); | |
| 2599 | − die_if_kernel("TL1: FPU Disabled", regs); | |
| 2600 | −} | |
| 2601 | − | |
| 2602 | 2576 | void do_fpieee_tl1(struct pt_regs *regs) |
| 2603 | 2577 | { |
| 2604 | 2578 | exception_enter(); |
| @@ -2820,7 +2820,7 @@ static int __init report_memory(void) · 2819 unmodified lines | ||
| 2820 | 2820 | |
| 2821 | 2821 | return 0; |
| 2822 | 2822 | } |
| 2823 | −device_initcall(report_memory); | |
| 2823 | +arch_initcall(report_memory); | |
| 2824 | 2824 | |
| 2825 | 2825 | #ifdef CONFIG_SMP |
| 2826 | 2826 | #define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range |
| @@ -14,13 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" |
| 15 | 15 | LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; |
| 16 | 16 | |
| 17 | −struct kaslr_setup_data { | |
| 18 | − __u64 next; | |
| 19 | − __u32 type; | |
| 20 | − __u32 len; | |
| 21 | − __u8 data[1]; | |
| 22 | −} kaslr_setup_data; | |
| 23 | − | |
| 24 | 17 | #define I8254_PORT_CONTROL 0x43 |
| 25 | 18 | #define I8254_PORT_COUNTER0 0x40 |
| 26 | 19 | #define I8254_CMD_READBACK 0xC0 |
| @@ -302,29 +295,7 @@ static unsigned long find_random_addr(unsigned long minimum, · 275 unmodified lines | ||
| 302 | 295 | return slots_fetch_random(); |
| 303 | 296 | } |
| 304 | 297 | |
| 305 | −static void add_kaslr_setup_data(struct boot_params *params, __u8 enabled) | |
| 306 | −{ | |
| 307 | − struct setup_data *data; | |
| 308 | − | |
| 309 | − kaslr_setup_data.type = SETUP_KASLR; | |
| 310 | − kaslr_setup_data.len = 1; | |
| 311 | − kaslr_setup_data.next = 0; | |
| 312 | − kaslr_setup_data.data[0] = enabled; | |
| 313 | − | |
| 314 | − data = (struct setup_data *)(unsigned long)params->hdr.setup_data; | |
| 315 | − | |
| 316 | − while (data && data->next) | |
| 317 | − data = (struct setup_data *)(unsigned long)data->next; | |
| 318 | − | |
| 319 | − if (data) | |
| 320 | − data->next = (unsigned long)&kaslr_setup_data; | |
| 321 | − else | |
| 322 | − params->hdr.setup_data = (unsigned long)&kaslr_setup_data; | |
| 323 | − | |
| 324 | −} | |
| 325 | − | |
| 326 | −unsigned char *choose_kernel_location(struct boot_params *params, | |
| 327 | − unsigned char *input, | |
| 298 | +unsigned char *choose_kernel_location(unsigned char *input, | |
| 328 | 299 | unsigned long input_size, |
| 329 | 300 | unsigned char *output, |
| 330 | 301 | unsigned long output_size) |
| @@ -335,17 +306,14 @@ unsigned char *choose_kernel_location(struct boot_params *params, · 4 unmodified lines | ||
| 335 | 306 | #ifdef CONFIG_HIBERNATION |
| 336 | 307 | if (!cmdline_find_option_bool("kaslr")) { |
| 337 | 308 | debug_putstr("KASLR disabled by default...\n"); |
| 338 | − add_kaslr_setup_data(params, 0); | |
| 339 | 309 | goto out; |
| 340 | 310 | } |
| 341 | 311 | #else |
| 342 | 312 | if (cmdline_find_option_bool("nokaslr")) { |
| 343 | 313 | debug_putstr("KASLR disabled by cmdline...\n"); |
| 344 | − add_kaslr_setup_data(params, 0); | |
| 345 | 314 | goto out; |
| 346 | 315 | } |
| 347 | 316 | #endif |
| 348 | − add_kaslr_setup_data(params, 1); | |
| 349 | 317 | |
| 350 | 318 | /* Record the various known unsafe memory ranges. */ |
| 351 | 319 | mem_avoid_init((unsigned long)input, input_size, |
| @@ -401,8 +401,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, · 400 unmodified lines | ||
| 401 | 401 | * the entire decompressed kernel plus relocation table, or the |
| 402 | 402 | * entire decompressed kernel plus .bss and .brk sections. |
| 403 | 403 | */ |
| 404 | − output = choose_kernel_location(real_mode, input_data, input_len, | |
| 405 | − output, | |
| 404 | + output = choose_kernel_location(input_data, input_len, output, | |
| 406 | 405 | output_len > run_size ? output_len |
| 407 | 406 | : run_size); |
| 408 | 407 | |
| @@ -57,8 +57,7 @@ int cmdline_find_option_bool(const char *option); · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | #if CONFIG_RANDOMIZE_BASE |
| 59 | 59 | /* aslr.c */ |
| 60 | −unsigned char *choose_kernel_location(struct boot_params *params, | |
| 61 | − unsigned char *input, | |
| 60 | +unsigned char *choose_kernel_location(unsigned char *input, | |
| 62 | 61 | unsigned long input_size, |
| 63 | 62 | unsigned char *output, |
| 64 | 63 | unsigned long output_size); |
| @@ -66,8 +65,7 @@ unsigned char *choose_kernel_location(struct boot_params *params, · 1 unmodified line | ||
| 66 | 65 | bool has_cpuflag(int flag); |
| 67 | 66 | #else |
| 68 | 67 | static inline |
| 69 | −unsigned char *choose_kernel_location(struct boot_params *params, | |
| 70 | − unsigned char *input, | |
| 68 | +unsigned char *choose_kernel_location(unsigned char *input, | |
| 71 | 69 | unsigned long input_size, |
| 72 | 70 | unsigned char *output, |
| 73 | 71 | unsigned long output_size) |
| @@ -1155,7 +1155,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) · 1154 unmodified lines | ||
| 1155 | 1155 | src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); |
| 1156 | 1156 | if (!src) |
| 1157 | 1157 | return -ENOMEM; |
| 1158 | − assoc = (src + req->cryptlen + auth_tag_len); | |
| 1158 | + assoc = (src + req->cryptlen); | |
| 1159 | 1159 | scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); |
| 1160 | 1160 | scatterwalk_map_and_copy(assoc, req->assoc, 0, |
| 1161 | 1161 | req->assoclen, 0); |
| @@ -1180,7 +1180,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req) · 18 unmodified lines | ||
| 1180 | 1180 | scatterwalk_done(&src_sg_walk, 0, 0); |
| 1181 | 1181 | scatterwalk_done(&assoc_sg_walk, 0, 0); |
| 1182 | 1182 | } else { |
| 1183 | − scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); | |
| 1183 | + scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1); | |
| 1184 | 1184 | kfree(src); |
| 1185 | 1185 | } |
| 1186 | 1186 | return retval; |
| @@ -370,7 +370,7 @@ static inline void drop_fpu(struct task_struct *tsk) · 369 unmodified lines | ||
| 370 | 370 | preempt_disable(); |
| 371 | 371 | tsk->thread.fpu_counter = 0; |
| 372 | 372 | __drop_fpu(tsk); |
| 373 | − clear_used_math(); | |
| 373 | + clear_stopped_child_used_math(tsk); | |
| 374 | 374 | preempt_enable(); |
| 375 | 375 | } |
| 376 | 376 | |
| @@ -51,8 +51,6 @@ extern int devmem_is_allowed(unsigned long pagenr); · 50 unmodified lines | ||
| 51 | 51 | extern unsigned long max_low_pfn_mapped; |
| 52 | 52 | extern unsigned long max_pfn_mapped; |
| 53 | 53 | |
| 54 | −extern bool kaslr_enabled; | |
| 55 | − | |
| 56 | 54 | static inline phys_addr_t get_max_mapped(void) |
| 57 | 55 | { |
| 58 | 56 | return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT; |
| @@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock; · 92 unmodified lines | ||
| 93 | 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
| 94 | 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
| 95 | 95 | |
| 96 | +extern bool mp_should_keep_irq(struct device *dev); | |
| 97 | + | |
| 96 | 98 | struct pci_raw_ops { |
| 97 | 99 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, |
| 98 | 100 | int reg, int len, u32 *val); |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #define SETUP_DTB 2 |
| 8 | 8 | #define SETUP_PCI 3 |
| 9 | 9 | #define SETUP_EFI 4 |
| 10 | −#define SETUP_KASLR 5 | |
| 11 | 10 | |
| 12 | 11 | /* ram_size flags */ |
| 13 | 12 | #define RAMDISK_IMAGE_START_MASK 0x07FF |
| @@ -1337,6 +1337,26 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) · 1336 unmodified lines | ||
| 1337 | 1337 | return 0; |
| 1338 | 1338 | } |
| 1339 | 1339 | |
| 1340 | +/* | |
| 1341 | + * ACPI offers an alternative platform interface model that removes | |
| 1342 | + * ACPI hardware requirements for platforms that do not implement | |
| 1343 | + * the PC Architecture. | |
| 1344 | + * | |
| 1345 | + * We initialize the Hardware-reduced ACPI model here: | |
| 1346 | + */ | |
| 1347 | +static void __init acpi_reduced_hw_init(void) | |
| 1348 | +{ | |
| 1349 | + if (acpi_gbl_reduced_hardware) { | |
| 1350 | + /* | |
| 1351 | + * Override x86_init functions and bypass legacy pic | |
| 1352 | + * in Hardware-reduced ACPI mode | |
| 1353 | + */ | |
| 1354 | + x86_init.timers.timer_init = x86_init_noop; | |
| 1355 | + x86_init.irqs.pre_vector_init = x86_init_noop; | |
| 1356 | + legacy_pic = &null_legacy_pic; | |
| 1357 | + } | |
| 1358 | +} | |
| 1359 | + | |
| 1340 | 1360 | /* |
| 1341 | 1361 | * If your system is blacklisted here, but you find that acpi=force |
| 1342 | 1362 | * works for you, please contact linux-acpi@vger.kernel.org |
| @@ -1536,6 +1556,11 @@ int __init early_acpi_boot_init(void) · 193 unmodified lines | ||
| 1536 | 1556 | */ |
| 1537 | 1557 | early_acpi_process_madt(); |
| 1538 | 1558 | |
| 1559 | + /* | |
| 1560 | + * Hardware-reduced ACPI mode initialization: | |
| 1561 | + */ | |
| 1562 | + acpi_reduced_hw_init(); | |
| 1563 | + | |
| 1539 | 1564 | return 0; |
| 1540 | 1565 | } |
| 1541 | 1566 | |
| @@ -37,10 +37,12 @@ static const struct apic apic_numachip; · 36 unmodified lines | ||
| 37 | 37 | static unsigned int get_apic_id(unsigned long x) |
| 38 | 38 | { |
| 39 | 39 | unsigned long value; |
| 40 | − unsigned int id; | |
| 40 | + unsigned int id = (x >> 24) & 0xff; | |
| 41 | 41 | |
| 42 | − rdmsrl(MSR_FAM10H_NODE_ID, value); | |
| 43 | − id = ((x >> 24) & 0xffU) | ((value << 2) & 0xff00U); | |
| 42 | + if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { | |
| 43 | + rdmsrl(MSR_FAM10H_NODE_ID, value); | |
| 44 | + id |= (value << 2) & 0xff00; | |
| 45 | + } | |
| 44 | 46 | |
| 45 | 47 | return id; |
| 46 | 48 | } |
| @@ -155,10 +157,18 @@ static int __init numachip_probe(void) · 108 unmodified lines | ||
| 155 | 157 | |
| 156 | 158 | static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) |
| 157 | 159 | { |
| 158 | − if (c->phys_proc_id != node) { | |
| 159 | − c->phys_proc_id = node; | |
| 160 | − per_cpu(cpu_llc_id, smp_processor_id()) = node; | |
| 160 | + u64 val; | |
| 161 | + u32 nodes = 1; | |
| 162 | + | |
| 163 | + this_cpu_write(cpu_llc_id, node); | |
| 164 | + | |
| 165 | + /* Account for nodes per socket in multi-core-module processors */ | |
| 166 | + if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { | |
| 167 | + rdmsrl(MSR_FAM10H_NODE_ID, val); | |
| 168 | + nodes = ((val >> 3) & 7) + 1; | |
| 161 | 169 | } |
| 170 | + | |
| 171 | + c->phys_proc_id = node / nodes; | |
| 162 | 172 | } |
| 163 | 173 | |
| 164 | 174 | static int __init numachip_system_init(void) |
| @@ -47,13 +47,21 @@ do { \ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #ifdef CONFIG_RANDOMIZE_BASE |
| 49 | 49 | static unsigned long module_load_offset; |
| 50 | +static int randomize_modules = 1; | |
| 50 | 51 | |
| 51 | 52 | /* Mutex protects the module_load_offset. */ |
| 52 | 53 | static DEFINE_MUTEX(module_kaslr_mutex); |
| 53 | 54 | |
| 55 | +static int __init parse_nokaslr(char *p) | |
| 56 | +{ | |
| 57 | + randomize_modules = 0; | |
| 58 | + return 0; | |
| 59 | +} | |
| 60 | +early_param("nokaslr", parse_nokaslr); | |
| 61 | + | |
| 54 | 62 | static unsigned long int get_module_load_offset(void) |
| 55 | 63 | { |
| 56 | − if (kaslr_enabled) { | |
| 64 | + if (randomize_modules) { | |
| 57 | 65 | mutex_lock(&module_kaslr_mutex); |
| 58 | 66 | /* |
| 59 | 67 | * Calculate the module_load_offset the first time this |
| @@ -122,8 +122,6 @@ · 121 unmodified lines | ||
| 122 | 122 | unsigned long max_low_pfn_mapped; |
| 123 | 123 | unsigned long max_pfn_mapped; |
| 124 | 124 | |
| 125 | −bool __read_mostly kaslr_enabled = false; | |
| 126 | − | |
| 127 | 125 | #ifdef CONFIG_DMI |
| 128 | 126 | RESERVE_BRK(dmi_alloc, 65536); |
| 129 | 127 | #endif |
| @@ -427,11 +425,6 @@ static void __init reserve_initrd(void) · 297 unmodified lines | ||
| 427 | 425 | } |
| 428 | 426 | #endif /* CONFIG_BLK_DEV_INITRD */ |
| 429 | 427 | |
| 430 | −static void __init parse_kaslr_setup(u64 pa_data, u32 data_len) | |
| 431 | −{ | |
| 432 | − kaslr_enabled = (bool)(pa_data + sizeof(struct setup_data)); | |
| 433 | −} | |
| 434 | − | |
| 435 | 428 | static void __init parse_setup_data(void) |
| 436 | 429 | { |
| 437 | 430 | struct setup_data *data; |
| @@ -457,9 +450,6 @@ static void __init parse_setup_data(void) · 19 unmodified lines | ||
| 457 | 450 | case SETUP_EFI: |
| 458 | 451 | parse_efi_setup(pa_data, data_len); |
| 459 | 452 | break; |
| 460 | − case SETUP_KASLR: | |
| 461 | − parse_kaslr_setup(pa_data, data_len); | |
| 462 | − break; | |
| 463 | 453 | default: |
| 464 | 454 | break; |
| 465 | 455 | } |
| @@ -842,14 +832,10 @@ static void __init trim_low_memory_range(void) · 376 unmodified lines | ||
| 842 | 832 | static int |
| 843 | 833 | dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) |
| 844 | 834 | { |
| 845 | − if (kaslr_enabled) | |
| 846 | − pr_emerg("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n", | |
| 847 | − (unsigned long)&_text - __START_KERNEL, | |
| 848 | − __START_KERNEL, | |
| 849 | − __START_KERNEL_map, | |
| 850 | − MODULES_VADDR-1); | |
| 851 | − else | |
| 852 | − pr_emerg("Kernel Offset: disabled\n"); | |
| 835 | + pr_emerg("Kernel Offset: 0x%lx from 0x%lx " | |
| 836 | + "(relocation range: 0x%lx-0x%lx)\n", | |
| 837 | + (unsigned long)&_text - __START_KERNEL, __START_KERNEL, | |
| 838 | + __START_KERNEL_map, MODULES_VADDR-1); | |
| 853 | 839 | |
| 854 | 840 | return 0; |
| 855 | 841 | } |
| @@ -384,7 +384,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) · 383 unmodified lines | ||
| 384 | 384 | goto exit; |
| 385 | 385 | conditional_sti(regs); |
| 386 | 386 | |
| 387 | − if (!user_mode(regs)) | |
| 387 | + if (!user_mode_vm(regs)) | |
| 388 | 388 | die("bounds", regs, error_code); |
| 389 | 389 | |
| 390 | 390 | if (!cpu_feature_enabled(X86_FEATURE_MPX)) { |
| @@ -637,7 +637,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) · 246 unmodified lines | ||
| 637 | 637 | * then it's very likely the result of an icebp/int01 trap. |
| 638 | 638 | * User wants a sigtrap for that. |
| 639 | 639 | */ |
| 640 | − if (!dr6 && user_mode(regs)) | |
| 640 | + if (!dr6 && user_mode_vm(regs)) | |
| 641 | 641 | user_icebp = 1; |
| 642 | 642 | |
| 643 | 643 | /* Catch kmemcheck conditions first of all! */ |
| @@ -379,7 +379,7 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size) · 378 unmodified lines | ||
| 379 | 379 | * thread's fpu state, reconstruct fxstate from the fsave |
| 380 | 380 | * header. Sanitize the copied state etc. |
| 381 | 381 | */ |
| 382 | − struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave; | |
| 382 | + struct fpu *fpu = &tsk->thread.fpu; | |
| 383 | 383 | struct user_i387_ia32_struct env; |
| 384 | 384 | int err = 0; |
| 385 | 385 | |
| @@ -393,14 +393,15 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size) · 7 unmodified lines | ||
| 393 | 393 | */ |
| 394 | 394 | drop_fpu(tsk); |
| 395 | 395 | |
| 396 | − if (__copy_from_user(xsave, buf_fx, state_size) || | |
| 396 | + if (__copy_from_user(&fpu->state->xsave, buf_fx, state_size) || | |
| 397 | 397 | __copy_from_user(&env, buf, sizeof(env))) { |
| 398 | + fpu_finit(fpu); | |
| 398 | 399 | err = -1; |
| 399 | 400 | } else { |
| 400 | 401 | sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only); |
| 401 | − set_used_math(); | |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | + set_used_math(); | |
| 404 | 405 | if (use_eager_fpu()) { |
| 405 | 406 | preempt_disable(); |
| 406 | 407 | math_state_restore(); |
| @@ -507,6 +507,7 @@ static int picdev_read(struct kvm_pic *s, · 506 unmodified lines | ||
| 507 | 507 | return -EOPNOTSUPP; |
| 508 | 508 | |
| 509 | 509 | if (len != 1) { |
| 510 | + memset(val, 0, len); | |
| 510 | 511 | pr_pic_unimpl("non byte read\n"); |
| 511 | 512 | return 0; |
| 512 | 513 | } |
| @@ -2168,7 +2168,10 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) · 2167 unmodified lines | ||
| 2168 | 2168 | { |
| 2169 | 2169 | unsigned long *msr_bitmap; |
| 2170 | 2170 | |
| 2171 | − if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { | |
| 2171 | + if (is_guest_mode(vcpu)) | |
| 2172 | + msr_bitmap = vmx_msr_bitmap_nested; | |
| 2173 | + else if (irqchip_in_kernel(vcpu->kvm) && | |
| 2174 | + apic_x2apic_mode(vcpu->arch.apic)) { | |
| 2172 | 2175 | if (is_long_mode(vcpu)) |
| 2173 | 2176 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; |
| 2174 | 2177 | else |
| @@ -9218,9 +9221,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) · 7043 unmodified lines | ||
| 9218 | 9221 | } |
| 9219 | 9222 | |
| 9220 | 9223 | if (cpu_has_vmx_msr_bitmap() && |
| 9221 | − exec_control & CPU_BASED_USE_MSR_BITMAPS && | |
| 9222 | − nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) { | |
| 9223 | − vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_nested)); | |
| 9224 | + exec_control & CPU_BASED_USE_MSR_BITMAPS) { | |
| 9225 | + nested_vmx_merge_msr_bitmap(vcpu, vmcs12); | |
| 9226 | + /* MSR_BITMAP will be set by following vmx_set_efer. */ | |
| 9224 | 9227 | } else |
| 9225 | 9228 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; |
| 9226 | 9229 | |
| @@ -2744,7 +2744,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 2743 unmodified lines | ||
| 2744 | 2744 | case KVM_CAP_USER_NMI: |
| 2745 | 2745 | case KVM_CAP_REINJECT_CONTROL: |
| 2746 | 2746 | case KVM_CAP_IRQ_INJECT_STATUS: |
| 2747 | − case KVM_CAP_IRQFD: | |
| 2748 | 2747 | case KVM_CAP_IOEVENTFD: |
| 2749 | 2748 | case KVM_CAP_IOEVENTFD_NO_LENGTH: |
| 2750 | 2749 | case KVM_CAP_PIT2: |
| @@ -513,31 +513,6 @@ void __init pcibios_set_cache_line_size(void) · 512 unmodified lines | ||
| 513 | 513 | } |
| 514 | 514 | } |
| 515 | 515 | |
| 516 | −/* | |
| 517 | − * Some device drivers assume dev->irq won't change after calling | |
| 518 | − * pci_disable_device(). So delay releasing of IRQ resource to driver | |
| 519 | − * unbinding time. Otherwise it will break PM subsystem and drivers | |
| 520 | − * like xen-pciback etc. | |
| 521 | − */ | |
| 522 | −static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, | |
| 523 | − void *data) | |
| 524 | −{ | |
| 525 | − struct pci_dev *dev = to_pci_dev(data); | |
| 526 | − | |
| 527 | − if (action != BUS_NOTIFY_UNBOUND_DRIVER) | |
| 528 | − return NOTIFY_DONE; | |
| 529 | − | |
| 530 | − if (pcibios_disable_irq) | |
| 531 | − pcibios_disable_irq(dev); | |
| 532 | − | |
| 533 | − return NOTIFY_OK; | |
| 534 | −} | |
| 535 | − | |
| 536 | −static struct notifier_block pci_irq_nb = { | |
| 537 | − .notifier_call = pci_irq_notifier, | |
| 538 | − .priority = INT_MIN, | |
| 539 | −}; | |
| 540 | − | |
| 541 | 516 | int __init pcibios_init(void) |
| 542 | 517 | { |
| 543 | 518 | if (!raw_pci_ops) { |
| @@ -550,9 +525,6 @@ int __init pcibios_init(void) · 6 unmodified lines | ||
| 550 | 525 | |
| 551 | 526 | if (pci_bf_sort >= pci_force_bf) |
| 552 | 527 | pci_sort_breadthfirst(); |
| 553 | − | |
| 554 | − bus_register_notifier(&pci_bus_type, &pci_irq_nb); | |
| 555 | − | |
| 556 | 528 | return 0; |
| 557 | 529 | } |
| 558 | 530 | |
| @@ -711,6 +683,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) · 152 unmodified lines | ||
| 711 | 683 | return 0; |
| 712 | 684 | } |
| 713 | 685 | |
| 686 | +void pcibios_disable_device (struct pci_dev *dev) | |
| 687 | +{ | |
| 688 | + if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | |
| 689 | + pcibios_disable_irq(dev); | |
| 690 | +} | |
| 691 | + | |
| 714 | 692 | int pci_ext_cfg_avail(void) |
| 715 | 693 | { |
| 716 | 694 | if (raw_pci_ext_ops) |
| @@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) · 233 unmodified lines | ||
| 234 | 234 | |
| 235 | 235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) |
| 236 | 236 | { |
| 237 | − if (dev->irq_managed && dev->irq > 0) { | |
| 237 | + if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && | |
| 238 | + dev->irq > 0) { | |
| 238 | 239 | mp_unmap_irq(dev->irq); |
| 239 | 240 | dev->irq_managed = 0; |
| 240 | − dev->irq = 0; | |
| 241 | 241 | } |
| 242 | 242 | } |
| 243 | 243 | |
| @@ -1256,9 +1256,22 @@ static int pirq_enable_irq(struct pci_dev *dev) · 1255 unmodified lines | ||
| 1256 | 1256 | return 0; |
| 1257 | 1257 | } |
| 1258 | 1258 | |
| 1259 | +bool mp_should_keep_irq(struct device *dev) | |
| 1260 | +{ | |
| 1261 | + if (dev->power.is_prepared) | |
| 1262 | + return true; | |
| 1263 | +#ifdef CONFIG_PM | |
| 1264 | + if (dev->power.runtime_status == RPM_SUSPENDING) | |
| 1265 | + return true; | |
| 1266 | +#endif | |
| 1267 | + | |
| 1268 | + return false; | |
| 1269 | +} | |
| 1270 | + | |
| 1259 | 1271 | static void pirq_disable_irq(struct pci_dev *dev) |
| 1260 | 1272 | { |
| 1261 | − if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) { | |
| 1273 | + if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && | |
| 1274 | + dev->irq_managed && dev->irq) { | |
| 1262 | 1275 | mp_unmap_irq(dev->irq); |
| 1263 | 1276 | dev->irq = 0; |
| 1264 | 1277 | dev->irq_managed = 0; |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | .text |
| 18 | 18 | .globl __kernel_sigreturn |
| 19 | 19 | .type __kernel_sigreturn,@function |
| 20 | + nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */ | |
| 20 | 21 | ALIGN |
| 21 | 22 | __kernel_sigreturn: |
| 22 | 23 | .LSTART_sigreturn: |
| @@ -563,7 +563,7 @@ static bool alloc_p2m(unsigned long pfn) · 562 unmodified lines | ||
| 563 | 563 | if (p2m_pfn == PFN_DOWN(__pa(p2m_missing))) |
| 564 | 564 | p2m_init(p2m); |
| 565 | 565 | else |
| 566 | − p2m_init_identity(p2m, pfn); | |
| 566 | + p2m_init_identity(p2m, pfn & ~(P2M_PER_PAGE - 1)); | |
| 567 | 567 | |
| 568 | 568 | spin_lock_irqsave(&p2m_update_lock, flags); |
| 569 | 569 | |
| @@ -65,6 +65,7 @@ struct lpss_private_data; · 64 unmodified lines | ||
| 65 | 65 | |
| 66 | 66 | struct lpss_device_desc { |
| 67 | 67 | unsigned int flags; |
| 68 | + const char *clk_con_id; | |
| 68 | 69 | unsigned int prv_offset; |
| 69 | 70 | size_t prv_size_override; |
| 70 | 71 | void (*setup)(struct lpss_private_data *pdata); |
| @@ -140,6 +141,7 @@ static struct lpss_device_desc lpt_i2c_dev_desc = { · 69 unmodified lines | ||
| 140 | 141 | |
| 141 | 142 | static struct lpss_device_desc lpt_uart_dev_desc = { |
| 142 | 143 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR, |
| 144 | + .clk_con_id = "baudclk", | |
| 143 | 145 | .prv_offset = 0x800, |
| 144 | 146 | .setup = lpss_uart_setup, |
| 145 | 147 | }; |
| @@ -156,6 +158,7 @@ static struct lpss_device_desc byt_pwm_dev_desc = { · 10 unmodified lines | ||
| 156 | 158 | |
| 157 | 159 | static struct lpss_device_desc byt_uart_dev_desc = { |
| 158 | 160 | .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, |
| 161 | + .clk_con_id = "baudclk", | |
| 159 | 162 | .prv_offset = 0x800, |
| 160 | 163 | .setup = lpss_uart_setup, |
| 161 | 164 | }; |
| @@ -313,7 +316,7 @@ out: · 151 unmodified lines | ||
| 313 | 316 | return PTR_ERR(clk); |
| 314 | 317 | |
| 315 | 318 | pdata->clk = clk; |
| 316 | − clk_register_clkdev(clk, NULL, devname); | |
| 319 | + clk_register_clkdev(clk, dev_desc->clk_con_id, devname); | |
| 317 | 320 | return 0; |
| 318 | 321 | } |
| 319 | 322 | |
| @@ -485,6 +485,14 @@ void acpi_pci_irq_disable(struct pci_dev *dev) · 484 unmodified lines | ||
| 485 | 485 | if (!pin || !dev->irq_managed || dev->irq <= 0) |
| 486 | 486 | return; |
| 487 | 487 | |
| 488 | + /* Keep IOAPIC pin configuration when suspending */ | |
| 489 | + if (dev->dev.power.is_prepared) | |
| 490 | + return; | |
| 491 | +#ifdef CONFIG_PM | |
| 492 | + if (dev->dev.power.runtime_status == RPM_SUSPENDING) | |
| 493 | + return; | |
| 494 | +#endif | |
| 495 | + | |
| 488 | 496 | entry = acpi_pci_irq_lookup(dev, pin); |
| 489 | 497 | if (!entry) |
| 490 | 498 | return; |
| @@ -505,6 +513,5 @@ void acpi_pci_irq_disable(struct pci_dev *dev) · 14 unmodified lines | ||
| 505 | 513 | if (gsi >= 0) { |
| 506 | 514 | acpi_unregister_gsi(gsi); |
| 507 | 515 | dev->irq_managed = 0; |
| 508 | − dev->irq = 0; | |
| 509 | 516 | } |
| 510 | 517 | } |
| @@ -869,6 +869,8 @@ try_offline_again: · 868 unmodified lines | ||
| 869 | 869 | */ |
| 870 | 870 | ata_msleep(ap, 1); |
| 871 | 871 | |
| 872 | + sata_set_spd(link); | |
| 873 | + | |
| 872 | 874 | /* |
| 873 | 875 | * Now, bring the host controller online again, this can take time |
| 874 | 876 | * as PHY reset and communication establishment, 1st D2H FIS and |
| @@ -307,7 +307,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, · 306 unmodified lines | ||
| 307 | 307 | if (pos == 0) { |
| 308 | 308 | memmove(blk + offset * map->cache_word_size, |
| 309 | 309 | blk, rbnode->blklen * map->cache_word_size); |
| 310 | − bitmap_shift_right(present, present, offset, blklen); | |
| 310 | + bitmap_shift_left(present, present, offset, blklen); | |
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | /* update the rbnode block, its size and the base register */ |
| @@ -608,7 +608,8 @@ static int regcache_sync_block_single(struct regmap *map, void *block, · 607 unmodified lines | ||
| 608 | 608 | for (i = start; i < end; i++) { |
| 609 | 609 | regtmp = block_base + (i * map->reg_stride); |
| 610 | 610 | |
| 611 | − if (!regcache_reg_present(cache_present, i)) | |
| 611 | + if (!regcache_reg_present(cache_present, i) || | |
| 612 | + !regmap_writeable(map, regtmp)) | |
| 612 | 613 | continue; |
| 613 | 614 | |
| 614 | 615 | val = regcache_get_val(map, block, i); |
| @@ -677,7 +678,8 @@ static int regcache_sync_block_raw(struct regmap *map, void *block, · 62 unmodified lines | ||
| 677 | 678 | for (i = start; i < end; i++) { |
| 678 | 679 | regtmp = block_base + (i * map->reg_stride); |
| 679 | 680 | |
| 680 | − if (!regcache_reg_present(cache_present, i)) { | |
| 681 | + if (!regcache_reg_present(cache_present, i) || | |
| 682 | + !regmap_writeable(map, regtmp)) { | |
| 681 | 683 | ret = regcache_sync_block_raw_flush(map, &data, |
| 682 | 684 | base, regtmp); |
| 683 | 685 | if (ret != 0) |
| @@ -499,7 +499,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, · 498 unmodified lines | ||
| 499 | 499 | goto err_alloc; |
| 500 | 500 | } |
| 501 | 501 | |
| 502 | − ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags, | |
| 502 | + ret = request_threaded_irq(irq, NULL, regmap_irq_thread, | |
| 503 | + irq_flags | IRQF_ONESHOT, | |
| 503 | 504 | chip->name, d); |
| 504 | 505 | if (ret != 0) { |
| 505 | 506 | dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n", |
| @@ -140,24 +140,24 @@ static int tpm_dev_add_device(struct tpm_chip *chip) · 139 unmodified lines | ||
| 140 | 140 | { |
| 141 | 141 | int rc; |
| 142 | 142 | |
| 143 | − rc = device_add(&chip->dev); | |
| 143 | + rc = cdev_add(&chip->cdev, chip->dev.devt, 1); | |
| 144 | 144 | if (rc) { |
| 145 | 145 | dev_err(&chip->dev, |
| 146 | − "unable to device_register() %s, major %d, minor %d, err=%d\n", | |
| 146 | + "unable to cdev_add() %s, major %d, minor %d, err=%d\n", | |
| 147 | 147 | chip->devname, MAJOR(chip->dev.devt), |
| 148 | 148 | MINOR(chip->dev.devt), rc); |
| 149 | 149 | |
| 150 | + device_unregister(&chip->dev); | |
| 150 | 151 | return rc; |
| 151 | 152 | } |
| 152 | 153 | |
| 153 | − rc = cdev_add(&chip->cdev, chip->dev.devt, 1); | |
| 154 | + rc = device_add(&chip->dev); | |
| 154 | 155 | if (rc) { |
| 155 | 156 | dev_err(&chip->dev, |
| 156 | − "unable to cdev_add() %s, major %d, minor %d, err=%d\n", | |
| 157 | + "unable to device_register() %s, major %d, minor %d, err=%d\n", | |
| 157 | 158 | chip->devname, MAJOR(chip->dev.devt), |
| 158 | 159 | MINOR(chip->dev.devt), rc); |
| 159 | 160 | |
| 160 | − device_unregister(&chip->dev); | |
| 161 | 161 | return rc; |
| 162 | 162 | } |
| 163 | 163 | |
| @@ -174,27 +174,17 @@ static void tpm_dev_del_device(struct tpm_chip *chip) · 10 unmodified lines | ||
| 174 | 174 | * tpm_chip_register() - create a character device for the TPM chip |
| 175 | 175 | * @chip: TPM chip to use. |
| 176 | 176 | * |
| 177 | − * Creates a character device for the TPM chip and adds sysfs interfaces for | |
| 178 | − * the device, PPI and TCPA. As the last step this function adds the | |
| 179 | − * chip to the list of TPM chips available for use. | |
| 177 | + * Creates a character device for the TPM chip and adds sysfs attributes for | |
| 178 | + * the device. As the last step this function adds the chip to the list of TPM | |
| 179 | + * chips available for in-kernel use. | |
| 180 | 180 | * |
| 181 | − * NOTE: This function should be only called after the chip initialization | |
| 182 | − * is complete. | |
| 183 | − * | |
| 184 | − * Called from tpm_<specific>.c probe function only for devices | |
| 185 | − * the driver has determined it should claim. Prior to calling | |
| 186 | − * this function the specific probe function has called pci_enable_device | |
| 187 | − * upon errant exit from this function specific probe function should call | |
| 188 | − * pci_disable_device | |
| 181 | + * This function should be only called after the chip initialization is | |
| 182 | + * complete. | |
| 189 | 183 | */ |
| 190 | 184 | int tpm_chip_register(struct tpm_chip *chip) |
| 191 | 185 | { |
| 192 | 186 | int rc; |
| 193 | 187 | |
| 194 | − rc = tpm_dev_add_device(chip); | |
| 195 | − if (rc) | |
| 196 | − return rc; | |
| 197 | − | |
| 198 | 188 | /* Populate sysfs for TPM1 devices. */ |
| 199 | 189 | if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { |
| 200 | 190 | rc = tpm_sysfs_add_device(chip); |
| @@ -208,6 +198,10 @@ int tpm_chip_register(struct tpm_chip *chip) · 7 unmodified lines | ||
| 208 | 198 | chip->bios_dir = tpm_bios_log_setup(chip->devname); |
| 209 | 199 | } |
| 210 | 200 | |
| 201 | + rc = tpm_dev_add_device(chip); | |
| 202 | + if (rc) | |
| 203 | + return rc; | |
| 204 | + | |
| 211 | 205 | /* Make the chip available. */ |
| 212 | 206 | spin_lock(&driver_lock); |
| 213 | 207 | list_add_rcu(&chip->list, &tpm_chip_list); |
| @@ -124,7 +124,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) · 123 unmodified lines | ||
| 124 | 124 | { |
| 125 | 125 | struct ibmvtpm_dev *ibmvtpm; |
| 126 | 126 | struct ibmvtpm_crq crq; |
| 127 | − u64 *word = (u64 *) &crq; | |
| 127 | + __be64 *word = (__be64 *)&crq; | |
| 128 | 128 | int rc; |
| 129 | 129 | |
| 130 | 130 | ibmvtpm = (struct ibmvtpm_dev *)TPM_VPRIV(chip); |
| @@ -145,11 +145,11 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) · 14 unmodified lines | ||
| 145 | 145 | memcpy((void *)ibmvtpm->rtce_buf, (void *)buf, count); |
| 146 | 146 | crq.valid = (u8)IBMVTPM_VALID_CMD; |
| 147 | 147 | crq.msg = (u8)VTPM_TPM_COMMAND; |
| 148 | − crq.len = (u16)count; | |
| 149 | − crq.data = ibmvtpm->rtce_dma_handle; | |
| 148 | + crq.len = cpu_to_be16(count); | |
| 149 | + crq.data = cpu_to_be32(ibmvtpm->rtce_dma_handle); | |
| 150 | 150 | |
| 151 | − rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), | |
| 152 | − cpu_to_be64(word[1])); | |
| 151 | + rc = ibmvtpm_send_crq(ibmvtpm->vdev, be64_to_cpu(word[0]), | |
| 152 | + be64_to_cpu(word[1])); | |
| 153 | 153 | if (rc != H_SUCCESS) { |
| 154 | 154 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); |
| 155 | 155 | rc = 0; |
| @@ -22,9 +22,9 @@ · 21 unmodified lines | ||
| 22 | 22 | struct ibmvtpm_crq { |
| 23 | 23 | u8 valid; |
| 24 | 24 | u8 msg; |
| 25 | − u16 len; | |
| 26 | − u32 data; | |
| 27 | − u64 reserved; | |
| 25 | + __be16 len; | |
| 26 | + __be32 data; | |
| 27 | + __be64 reserved; | |
| 28 | 28 | } __attribute__((packed, aligned(8))); |
| 29 | 29 | |
| 30 | 30 | struct ibmvtpm_crq_queue { |
| @@ -142,6 +142,7 @@ struct ports_device { · 141 unmodified lines | ||
| 142 | 142 | * notification |
| 143 | 143 | */ |
| 144 | 144 | struct work_struct control_work; |
| 145 | + struct work_struct config_work; | |
| 145 | 146 | |
| 146 | 147 | struct list_head ports; |
| 147 | 148 | |
| @@ -1837,10 +1838,21 @@ static void config_intr(struct virtio_device *vdev) · 1689 unmodified lines | ||
| 1837 | 1838 | |
| 1838 | 1839 | portdev = vdev->priv; |
| 1839 | 1840 | |
| 1841 | + if (!use_multiport(portdev)) | |
| 1842 | + schedule_work(&portdev->config_work); | |
| 1843 | +} | |
| 1844 | + | |
| 1845 | +static void config_work_handler(struct work_struct *work) | |
| 1846 | +{ | |
| 1847 | + struct ports_device *portdev; | |
| 1848 | + | |
| 1849 | + portdev = container_of(work, struct ports_device, control_work); | |
| 1840 | 1850 | if (!use_multiport(portdev)) { |
| 1851 | + struct virtio_device *vdev; | |
| 1841 | 1852 | struct port *port; |
| 1842 | 1853 | u16 rows, cols; |
| 1843 | 1854 | |
| 1855 | + vdev = portdev->vdev; | |
| 1844 | 1856 | virtio_cread(vdev, struct virtio_console_config, cols, &cols); |
| 1845 | 1857 | virtio_cread(vdev, struct virtio_console_config, rows, &rows); |
| 1846 | 1858 | |
| @@ -2040,12 +2052,14 @@ static int virtcons_probe(struct virtio_device *vdev) · 193 unmodified lines | ||
| 2040 | 2052 | |
| 2041 | 2053 | virtio_device_ready(portdev->vdev); |
| 2042 | 2054 | |
| 2055 | + INIT_WORK(&portdev->config_work, &config_work_handler); | |
| 2056 | + INIT_WORK(&portdev->control_work, &control_work_handler); | |
| 2057 | + | |
| 2043 | 2058 | if (multiport) { |
| 2044 | 2059 | unsigned int nr_added_bufs; |
| 2045 | 2060 | |
| 2046 | 2061 | spin_lock_init(&portdev->c_ivq_lock); |
| 2047 | 2062 | spin_lock_init(&portdev->c_ovq_lock); |
| 2048 | − INIT_WORK(&portdev->control_work, &control_work_handler); | |
| 2049 | 2063 | |
| 2050 | 2064 | nr_added_bufs = fill_queue(portdev->c_ivq, |
| 2051 | 2065 | &portdev->c_ivq_lock); |
| @@ -2113,6 +2127,8 @@ static void virtcons_remove(struct virtio_device *vdev) · 61 unmodified lines | ||
| 2113 | 2127 | /* Finish up work that's lined up */ |
| 2114 | 2128 | if (use_multiport(portdev)) |
| 2115 | 2129 | cancel_work_sync(&portdev->control_work); |
| 2130 | + else | |
| 2131 | + cancel_work_sync(&portdev->config_work); | |
| 2116 | 2132 | |
| 2117 | 2133 | list_for_each_entry_safe(port, port2, &portdev->ports, list) |
| 2118 | 2134 | unplug_port(port); |
| @@ -2164,6 +2180,7 @@ static int virtcons_freeze(struct virtio_device *vdev) · 45 unmodified lines | ||
| 2164 | 2180 | |
| 2165 | 2181 | virtqueue_disable_cb(portdev->c_ivq); |
| 2166 | 2182 | cancel_work_sync(&portdev->control_work); |
| 2183 | + cancel_work_sync(&portdev->config_work); | |
| 2167 | 2184 | /* |
| 2168 | 2185 | * Once more: if control_work_handler() was running, it would |
| 2169 | 2186 | * enable the cb as the last step. |
| @@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, · 143 unmodified lines | ||
| 144 | 144 | divider->flags); |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | −/* | |
| 148 | − * The reverse of DIV_ROUND_UP: The maximum number which | |
| 149 | − * divided by m is r | |
| 150 | − */ | |
| 151 | −#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1) | |
| 152 | − | |
| 153 | 147 | static bool _is_valid_table_div(const struct clk_div_table *table, |
| 154 | 148 | unsigned int div) |
| 155 | 149 | { |
| @@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table, · 69 unmodified lines | ||
| 225 | 219 | unsigned long parent_rate, unsigned long rate, |
| 226 | 220 | unsigned long flags) |
| 227 | 221 | { |
| 228 | − int up, down, div; | |
| 222 | + int up, down; | |
| 223 | + unsigned long up_rate, down_rate; | |
| 229 | 224 | |
| 230 | − up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate); | |
| 225 | + up = DIV_ROUND_UP(parent_rate, rate); | |
| 226 | + down = parent_rate / rate; | |
| 231 | 227 | |
| 232 | 228 | if (flags & CLK_DIVIDER_POWER_OF_TWO) { |
| 233 | − up = __roundup_pow_of_two(div); | |
| 234 | − down = __rounddown_pow_of_two(div); | |
| 229 | + up = __roundup_pow_of_two(up); | |
| 230 | + down = __rounddown_pow_of_two(down); | |
| 235 | 231 | } else if (table) { |
| 236 | − up = _round_up_table(table, div); | |
| 237 | − down = _round_down_table(table, div); | |
| 232 | + up = _round_up_table(table, up); | |
| 233 | + down = _round_down_table(table, down); | |
| 238 | 234 | } |
| 239 | 235 | |
| 240 | − return (up - div) <= (div - down) ? up : down; | |
| 236 | + up_rate = DIV_ROUND_UP(parent_rate, up); | |
| 237 | + down_rate = DIV_ROUND_UP(parent_rate, down); | |
| 238 | + | |
| 239 | + return (rate - up_rate) <= (down_rate - rate) ? up : down; | |
| 241 | 240 | } |
| 242 | 241 | |
| 243 | 242 | static int _div_round(const struct clk_div_table *table, |
| @@ -313,7 +312,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, · 69 unmodified lines | ||
| 313 | 312 | return i; |
| 314 | 313 | } |
| 315 | 314 | parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), |
| 316 | − MULT_ROUND_UP(rate, i)); | |
| 315 | + rate * i); | |
| 317 | 316 | now = DIV_ROUND_UP(parent_rate, i); |
| 318 | 317 | if (_is_best_div(rate, now, best, flags)) { |
| 319 | 318 | bestdiv = i; |
| @@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, · 33 unmodified lines | ||
| 353 | 352 | bestdiv = readl(divider->reg) >> divider->shift; |
| 354 | 353 | bestdiv &= div_mask(divider->width); |
| 355 | 354 | bestdiv = _get_div(divider->table, bestdiv, divider->flags); |
| 356 | − return bestdiv; | |
| 355 | + return DIV_ROUND_UP(*prate, bestdiv); | |
| 357 | 356 | } |
| 358 | 357 | |
| 359 | 358 | return divider_round_rate(hw, rate, prate, divider->table, |
| @@ -1350,7 +1350,6 @@ static unsigned long clk_core_get_rate(struct clk_core *clk) · 1349 unmodified lines | ||
| 1350 | 1350 | |
| 1351 | 1351 | return rate; |
| 1352 | 1352 | } |
| 1353 | −EXPORT_SYMBOL_GPL(clk_core_get_rate); | |
| 1354 | 1353 | |
| 1355 | 1354 | /** |
| 1356 | 1355 | * clk_get_rate - return the rate of clk |
| @@ -2170,6 +2169,32 @@ int clk_get_phase(struct clk *clk) · 813 unmodified lines | ||
| 2170 | 2169 | return clk_core_get_phase(clk->core); |
| 2171 | 2170 | } |
| 2172 | 2171 | |
| 2172 | +/** | |
| 2173 | + * clk_is_match - check if two clk's point to the same hardware clock | |
| 2174 | + * @p: clk compared against q | |
| 2175 | + * @q: clk compared against p | |
| 2176 | + * | |
| 2177 | + * Returns true if the two struct clk pointers both point to the same hardware | |
| 2178 | + * clock node. Put differently, returns true if struct clk *p and struct clk *q | |
| 2179 | + * share the same struct clk_core object. | |
| 2180 | + * | |
| 2181 | + * Returns false otherwise. Note that two NULL clks are treated as matching. | |
| 2182 | + */ | |
| 2183 | +bool clk_is_match(const struct clk *p, const struct clk *q) | |
| 2184 | +{ | |
| 2185 | + /* trivial case: identical struct clk's or both NULL */ | |
| 2186 | + if (p == q) | |
| 2187 | + return true; | |
| 2188 | + | |
| 2189 | + /* true if clk->core pointers match. Avoid derefing garbage */ | |
| 2190 | + if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q)) | |
| 2191 | + if (p->core == q->core) | |
| 2192 | + return true; | |
| 2193 | + | |
| 2194 | + return false; | |
| 2195 | +} | |
| 2196 | +EXPORT_SYMBOL_GPL(clk_is_match); | |
| 2197 | + | |
| 2173 | 2198 | /** |
| 2174 | 2199 | * __clk_init - initialize the data structures in a struct clk |
| 2175 | 2200 | * @dev: device initializing this clk, placeholder for now |
| @@ -48,6 +48,17 @@ static struct clk_pll pll3 = { · 47 unmodified lines | ||
| 48 | 48 | }, |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | +static struct clk_regmap pll4_vote = { | |
| 52 | + .enable_reg = 0x34c0, | |
| 53 | + .enable_mask = BIT(4), | |
| 54 | + .hw.init = &(struct clk_init_data){ | |
| 55 | + .name = "pll4_vote", | |
| 56 | + .parent_names = (const char *[]){ "pll4" }, | |
| 57 | + .num_parents = 1, | |
| 58 | + .ops = &clk_pll_vote_ops, | |
| 59 | + }, | |
| 60 | +}; | |
| 61 | + | |
| 51 | 62 | static struct clk_pll pll8 = { |
| 52 | 63 | .l_reg = 0x3144, |
| 53 | 64 | .m_reg = 0x3148, |
| @@ -3023,6 +3034,7 @@ static struct clk_branch rpm_msg_ram_h_clk = { · 2969 unmodified lines | ||
| 3023 | 3034 | |
| 3024 | 3035 | static struct clk_regmap *gcc_msm8960_clks[] = { |
| 3025 | 3036 | [PLL3] = &pll3.clkr, |
| 3037 | + [PLL4_VOTE] = &pll4_vote, | |
| 3026 | 3038 | [PLL8] = &pll8.clkr, |
| 3027 | 3039 | [PLL8_VOTE] = &pll8_vote, |
| 3028 | 3040 | [PLL14] = &pll14.clkr, |
| @@ -3247,6 +3259,7 @@ static const struct qcom_reset_map gcc_msm8960_resets[] = { · 218 unmodified lines | ||
| 3247 | 3259 | |
| 3248 | 3260 | static struct clk_regmap *gcc_apq8064_clks[] = { |
| 3249 | 3261 | [PLL3] = &pll3.clkr, |
| 3262 | + [PLL4_VOTE] = &pll4_vote, | |
| 3250 | 3263 | [PLL8] = &pll8.clkr, |
| 3251 | 3264 | [PLL8_VOTE] = &pll8_vote, |
| 3252 | 3265 | [PLL14] = &pll14.clkr, |
| @@ -462,7 +462,6 @@ static struct platform_driver lcc_ipq806x_driver = { · 461 unmodified lines | ||
| 462 | 462 | .remove = lcc_ipq806x_remove, |
| 463 | 463 | .driver = { |
| 464 | 464 | .name = "lcc-ipq806x", |
| 465 | − .owner = THIS_MODULE, | |
| 466 | 465 | .of_match_table = lcc_ipq806x_match_table, |
| 467 | 466 | }, |
| 468 | 467 | }; |
| @@ -417,8 +417,8 @@ static struct clk_rcg slimbus_src = { · 416 unmodified lines | ||
| 417 | 417 | .mnctr_en_bit = 8, |
| 418 | 418 | .mnctr_reset_bit = 7, |
| 419 | 419 | .mnctr_mode_shift = 5, |
| 420 | − .n_val_shift = 16, | |
| 421 | − .m_val_shift = 16, | |
| 420 | + .n_val_shift = 24, | |
| 421 | + .m_val_shift = 8, | |
| 422 | 422 | .width = 8, |
| 423 | 423 | }, |
| 424 | 424 | .p = { |
| @@ -547,7 +547,7 @@ static int lcc_msm8960_probe(struct platform_device *pdev) · 122 unmodified lines | ||
| 547 | 547 | return PTR_ERR(regmap); |
| 548 | 548 | |
| 549 | 549 | /* Use the correct frequency plan depending on speed of PLL4 */ |
| 550 | − val = regmap_read(regmap, 0x4, &val); | |
| 550 | + regmap_read(regmap, 0x4, &val); | |
| 551 | 551 | if (val == 0x12) { |
| 552 | 552 | slimbus_src.freq_tbl = clk_tbl_aif_osr_492; |
| 553 | 553 | mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492; |
| @@ -574,7 +574,6 @@ static struct platform_driver lcc_msm8960_driver = { · 20 unmodified lines | ||
| 574 | 574 | .remove = lcc_msm8960_remove, |
| 575 | 575 | .driver = { |
| 576 | 576 | .name = "lcc-msm8960", |
| 577 | − .owner = THIS_MODULE, | |
| 578 | 577 | .of_match_table = lcc_msm8960_match_table, |
| 579 | 578 | }, |
| 580 | 579 | }; |
| @@ -84,7 +84,7 @@ static int ti_fapll_enable(struct clk_hw *hw) · 83 unmodified lines | ||
| 84 | 84 | struct fapll_data *fd = to_fapll(hw); |
| 85 | 85 | u32 v = readl_relaxed(fd->base); |
| 86 | 86 | |
| 87 | − v |= (1 << FAPLL_MAIN_PLLEN); | |
| 87 | + v |= FAPLL_MAIN_PLLEN; | |
| 88 | 88 | writel_relaxed(v, fd->base); |
| 89 | 89 | |
| 90 | 90 | return 0; |
| @@ -95,7 +95,7 @@ static void ti_fapll_disable(struct clk_hw *hw) · 4 unmodified lines | ||
| 95 | 95 | struct fapll_data *fd = to_fapll(hw); |
| 96 | 96 | u32 v = readl_relaxed(fd->base); |
| 97 | 97 | |
| 98 | − v &= ~(1 << FAPLL_MAIN_PLLEN); | |
| 98 | + v &= ~FAPLL_MAIN_PLLEN; | |
| 99 | 99 | writel_relaxed(v, fd->base); |
| 100 | 100 | } |
| 101 | 101 | |
| @@ -104,7 +104,7 @@ static int ti_fapll_is_enabled(struct clk_hw *hw) · 2 unmodified lines | ||
| 104 | 104 | struct fapll_data *fd = to_fapll(hw); |
| 105 | 105 | u32 v = readl_relaxed(fd->base); |
| 106 | 106 | |
| 107 | − return v & (1 << FAPLL_MAIN_PLLEN); | |
| 107 | + return v & FAPLL_MAIN_PLLEN; | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw, |
| @@ -225,12 +225,12 @@ static int __init efm32_clockevent_init(struct device_node *np) · 224 unmodified lines | ||
| 225 | 225 | clock_event_ddata.base = base; |
| 226 | 226 | clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ); |
| 227 | 227 | |
| 228 | − setup_irq(irq, &efm32_clock_event_irq); | |
| 229 | − | |
| 230 | 228 | clockevents_config_and_register(&clock_event_ddata.evtdev, |
| 231 | 229 | DIV_ROUND_CLOSEST(rate, 1024), |
| 232 | 230 | 0xf, 0xffff); |
| 233 | 231 | |
| 232 | + setup_irq(irq, &efm32_clock_event_irq); | |
| 233 | + | |
| 234 | 234 | return 0; |
| 235 | 235 | |
| 236 | 236 | err_get_irq: |
| @@ -178,10 +178,6 @@ static void __init sun5i_timer_init(struct device_node *node) · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); |
| 180 | 180 | |
| 181 | − ret = setup_irq(irq, &sun5i_timer_irq); | |
| 182 | − if (ret) | |
| 183 | − pr_warn("failed to setup irq %d\n", irq); | |
| 184 | − | |
| 185 | 181 | /* Enable timer0 interrupt */ |
| 186 | 182 | val = readl(timer_base + TIMER_IRQ_EN_REG); |
| 187 | 183 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); |
| @@ -191,6 +187,10 @@ static void __init sun5i_timer_init(struct device_node *node) · 3 unmodified lines | ||
| 191 | 187 | |
| 192 | 188 | clockevents_config_and_register(&sun5i_clockevent, rate, |
| 193 | 189 | TIMER_SYNC_TICKS, 0xffffffff); |
| 190 | + | |
| 191 | + ret = setup_irq(irq, &sun5i_timer_irq); | |
| 192 | + if (ret) | |
| 193 | + pr_warn("failed to setup irq %d\n", irq); | |
| 194 | 194 | } |
| 195 | 195 | CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer", |
| 196 | 196 | sun5i_timer_init); |
| @@ -37,11 +37,11 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev, · 36 unmodified lines | ||
| 37 | 37 | deepidle = true; |
| 38 | 38 | |
| 39 | 39 | ret = mvebu_v7_cpu_suspend(deepidle); |
| 40 | + cpu_pm_exit(); | |
| 41 | + | |
| 40 | 42 | if (ret) |
| 41 | 43 | return ret; |
| 42 | 44 | |
| 43 | − cpu_pm_exit(); | |
| 44 | − | |
| 45 | 45 | return index; |
| 46 | 46 | } |
| 47 | 47 | |
| @@ -50,17 +50,17 @@ static struct cpuidle_driver armadaxp_idle_driver = { · 2 unmodified lines | ||
| 50 | 50 | .states[0] = ARM_CPUIDLE_WFI_STATE, |
| 51 | 51 | .states[1] = { |
| 52 | 52 | .enter = mvebu_v7_enter_idle, |
| 53 | − .exit_latency = 10, | |
| 53 | + .exit_latency = 100, | |
| 54 | 54 | .power_usage = 50, |
| 55 | − .target_residency = 100, | |
| 55 | + .target_residency = 1000, | |
| 56 | 56 | .name = "MV CPU IDLE", |
| 57 | 57 | .desc = "CPU power down", |
| 58 | 58 | }, |
| 59 | 59 | .states[2] = { |
| 60 | 60 | .enter = mvebu_v7_enter_idle, |
| 61 | − .exit_latency = 100, | |
| 61 | + .exit_latency = 1000, | |
| 62 | 62 | .power_usage = 5, |
| 63 | − .target_residency = 1000, | |
| 63 | + .target_residency = 10000, | |
| 64 | 64 | .flags = MVEBU_V7_FLAG_DEEP_IDLE, |
| 65 | 65 | .name = "MV CPU DEEP IDLE", |
| 66 | 66 | .desc = "CPU and L2 Fabric power down", |
| @@ -97,6 +97,12 @@ · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | #define DRIVER_NAME "pl08xdmac" |
| 99 | 99 | |
| 100 | +#define PL80X_DMA_BUSWIDTHS \ | |
| 101 | + BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ | |
| 102 | + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ | |
| 103 | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ | |
| 104 | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | |
| 105 | + | |
| 100 | 106 | static struct amba_driver pl08x_amba_driver; |
| 101 | 107 | struct pl08x_driver_data; |
| 102 | 108 | |
| @@ -2070,6 +2076,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 1967 unmodified lines | ||
| 2070 | 2076 | pl08x->memcpy.device_pause = pl08x_pause; |
| 2071 | 2077 | pl08x->memcpy.device_resume = pl08x_resume; |
| 2072 | 2078 | pl08x->memcpy.device_terminate_all = pl08x_terminate_all; |
| 2079 | + pl08x->memcpy.src_addr_widths = PL80X_DMA_BUSWIDTHS; | |
| 2080 | + pl08x->memcpy.dst_addr_widths = PL80X_DMA_BUSWIDTHS; | |
| 2081 | + pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM); | |
| 2082 | + pl08x->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; | |
| 2073 | 2083 | |
| 2074 | 2084 | /* Initialize slave engine */ |
| 2075 | 2085 | dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); |
| @@ -2086,6 +2096,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 10 unmodified lines | ||
| 2086 | 2096 | pl08x->slave.device_pause = pl08x_pause; |
| 2087 | 2097 | pl08x->slave.device_resume = pl08x_resume; |
| 2088 | 2098 | pl08x->slave.device_terminate_all = pl08x_terminate_all; |
| 2099 | + pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; | |
| 2100 | + pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; | |
| 2101 | + pl08x->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); | |
| 2102 | + pl08x->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; | |
| 2089 | 2103 | |
| 2090 | 2104 | /* Get the platform data */ |
| 2091 | 2105 | pl08x->pd = dev_get_platdata(&adev->dev); |
| @@ -238,93 +238,126 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) · 237 unmodified lines | ||
| 238 | 238 | } |
| 239 | 239 | |
| 240 | 240 | /* |
| 241 | − * atc_get_current_descriptors - | |
| 242 | − * locate the descriptor which equal to physical address in DSCR | |
| 243 | − * @atchan: the channel we want to start | |
| 244 | − * @dscr_addr: physical descriptor address in DSCR | |
| 241 | + * atc_get_desc_by_cookie - get the descriptor of a cookie | |
| 242 | + * @atchan: the DMA channel | |
| 243 | + * @cookie: the cookie to get the descriptor for | |
| 245 | 244 | */ |
| 246 | −static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan, | |
| 247 | − u32 dscr_addr) | |
| 245 | +static struct at_desc *atc_get_desc_by_cookie(struct at_dma_chan *atchan, | |
| 246 | + dma_cookie_t cookie) | |
| 248 | 247 | { |
| 249 | − struct at_desc *desc, *_desc, *child, *desc_cur = NULL; | |
| 248 | + struct at_desc *desc, *_desc; | |
| 250 | 249 | |
| 251 | − list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) { | |
| 252 | − if (desc->lli.dscr == dscr_addr) { | |
| 253 | − desc_cur = desc; | |
| 254 | − break; | |
| 255 | − } | |
| 250 | + list_for_each_entry_safe(desc, _desc, &atchan->queue, desc_node) { | |
| 251 | + if (desc->txd.cookie == cookie) | |
| 252 | + return desc; | |
| 253 | + } | |
| 256 | 254 | |
| 257 | − list_for_each_entry(child, &desc->tx_list, desc_node) { | |
| 258 | − if (child->lli.dscr == dscr_addr) { | |
| 259 | − desc_cur = child; | |
| 260 | − break; | |
| 261 | − } | |
| 262 | − } | |
| 255 | + list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) { | |
| 256 | + if (desc->txd.cookie == cookie) | |
| 257 | + return desc; | |
| 263 | 258 | } |
| 264 | 259 | |
| 265 | − return desc_cur; | |
| 260 | + return NULL; | |
| 266 | 261 | } |
| 267 | 262 | |
| 268 | −/* | |
| 269 | − * atc_get_bytes_left - | |
| 270 | − * Get the number of bytes residue in dma buffer, | |
| 271 | − * @chan: the channel we want to start | |
| 263 | +/** | |
| 264 | + * atc_calc_bytes_left - calculates the number of bytes left according to the | |
| 265 | + * value read from CTRLA. | |
| 266 | + * | |
| 267 | + * @current_len: the number of bytes left before reading CTRLA | |
| 268 | + * @ctrla: the value of CTRLA | |
| 269 | + * @desc: the descriptor containing the transfer width | |
| 270 | + */ | |
| 271 | +static inline int atc_calc_bytes_left(int current_len, u32 ctrla, | |
| 272 | + struct at_desc *desc) | |
| 273 | +{ | |
| 274 | + return current_len - ((ctrla & ATC_BTSIZE_MAX) << desc->tx_width); | |
| 275 | +} | |
| 276 | + | |
| 277 | +/** | |
| 278 | + * atc_calc_bytes_left_from_reg - calculates the number of bytes left according | |
| 279 | + * to the current value of CTRLA. | |
| 280 | + * | |
| 281 | + * @current_len: the number of bytes left before reading CTRLA | |
| 282 | + * @atchan: the channel to read CTRLA for | |
| 283 | + * @desc: the descriptor containing the transfer width | |
| 284 | + */ | |
| 285 | +static inline int atc_calc_bytes_left_from_reg(int current_len, | |
| 286 | + struct at_dma_chan *atchan, struct at_desc *desc) | |
| 287 | +{ | |
| 288 | + u32 ctrla = channel_readl(atchan, CTRLA); | |
| 289 | + | |
| 290 | + return atc_calc_bytes_left(current_len, ctrla, desc); | |
| 291 | +} | |
| 292 | + | |
| 293 | +/** | |
| 294 | + * atc_get_bytes_left - get the number of bytes residue for a cookie | |
| 295 | + * @chan: DMA channel | |
| 296 | + * @cookie: transaction identifier to check status of | |
| 272 | 297 | */ |
| 273 | −static int atc_get_bytes_left(struct dma_chan *chan) | |
| 298 | +static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie) | |
| 274 | 299 | { |
| 275 | 300 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
| 276 | − struct at_dma *atdma = to_at_dma(chan->device); | |
| 277 | − int chan_id = atchan->chan_common.chan_id; | |
| 278 | 301 | struct at_desc *desc_first = atc_first_active(atchan); |
| 279 | − struct at_desc *desc_cur; | |
| 280 | − int ret = 0, count = 0; | |
| 302 | + struct at_desc *desc; | |
| 303 | + int ret; | |
| 304 | + u32 ctrla, dscr; | |
| 281 | 305 | |
| 282 | 306 | /* |
| 283 | − * Initialize necessary values in the first time. | |
| 284 | − * remain_desc record remain desc length. | |
| 307 | + * If the cookie doesn't match to the currently running transfer then | |
| 308 | + * we can return the total length of the associated DMA transfer, | |
| 309 | + * because it is still queued. | |
| 285 | 310 | */ |
| 286 | − if (atchan->remain_desc == 0) | |
| 287 | − /* First descriptor embedds the transaction length */ | |
| 288 | − atchan->remain_desc = desc_first->len; | |
| 311 | + desc = atc_get_desc_by_cookie(atchan, cookie); | |
| 312 | + if (desc == NULL) | |
| 313 | + return -EINVAL; | |
| 314 | + else if (desc != desc_first) | |
| 315 | + return desc->total_len; | |
| 289 | 316 | |
| 290 | − /* | |
| 291 | − * This happens when current descriptor transfer complete. | |
| 292 | − * The residual buffer size should reduce current descriptor length. | |
| 293 | − */ | |
| 294 | − if (unlikely(test_bit(ATC_IS_BTC, &atchan->status))) { | |
| 295 | − clear_bit(ATC_IS_BTC, &atchan->status); | |
| 296 | − desc_cur = atc_get_current_descriptors(atchan, | |
| 297 | − channel_readl(atchan, DSCR)); | |
| 298 | − if (!desc_cur) { | |
| 299 | − ret = -EINVAL; | |
| 300 | − goto out; | |
| 301 | − } | |
| 317 | + /* cookie matches to the currently running transfer */ | |
| 318 | + ret = desc_first->total_len; | |
| 302 | 319 | |
| 303 | − count = (desc_cur->lli.ctrla & ATC_BTSIZE_MAX) | |
| 304 | − << desc_first->tx_width; | |
| 305 | − if (atchan->remain_desc < count) { | |
| 306 | − ret = -EINVAL; | |
| 307 | − goto out; | |
| 320 | + if (desc_first->lli.dscr) { | |
| 321 | + /* hardware linked list transfer */ | |
| 322 | + | |
| 323 | + /* | |
| 324 | + * Calculate the residue by removing the length of the child | |
| 325 | + * descriptors already transferred from the total length. | |
| 326 | + * To get the current child descriptor we can use the value of | |
| 327 | + * the channel's DSCR register and compare it against the value | |
| 328 | + * of the hardware linked list structure of each child | |
| 329 | + * descriptor. | |
| 330 | + */ | |
| 331 | + | |
| 332 | + ctrla = channel_readl(atchan, CTRLA); | |
| 333 | + rmb(); /* ensure CTRLA is read before DSCR */ | |
| 334 | + dscr = channel_readl(atchan, DSCR); | |
| 335 | + | |
| 336 | + /* for the first descriptor we can be more accurate */ | |
| 337 | + if (desc_first->lli.dscr == dscr) | |
| 338 | + return atc_calc_bytes_left(ret, ctrla, desc_first); | |
| 339 | + | |
| 340 | + ret -= desc_first->len; | |
| 341 | + list_for_each_entry(desc, &desc_first->tx_list, desc_node) { | |
| 342 | + if (desc->lli.dscr == dscr) | |
| 343 | + break; | |
| 344 | + | |
| 345 | + ret -= desc->len; | |
| 308 | 346 | } |
| 309 | 347 | |
| 310 | − atchan->remain_desc -= count; | |
| 311 | − ret = atchan->remain_desc; | |
| 312 | − } else { | |
| 313 | 348 | /* |
| 314 | − * Get residual bytes when current | |
| 315 | − * descriptor transfer in progress. | |
| 349 | + * For the last descriptor in the chain we can calculate | |
| 350 | + * the remaining bytes using the channel's register. | |
| 351 | + * Note that the transfer width of the first and last | |
| 352 | + * descriptor may differ. | |
| 316 | 353 | */ |
| 317 | − count = (channel_readl(atchan, CTRLA) & ATC_BTSIZE_MAX) | |
| 318 | − << (desc_first->tx_width); | |
| 319 | − ret = atchan->remain_desc - count; | |
| 354 | + if (!desc->lli.dscr) | |
| 355 | + ret = atc_calc_bytes_left_from_reg(ret, atchan, desc); | |
| 356 | + } else { | |
| 357 | + /* single transfer */ | |
| 358 | + ret = atc_calc_bytes_left_from_reg(ret, atchan, desc_first); | |
| 320 | 359 | } |
| 321 | − /* | |
| 322 | − * Check fifo empty. | |
| 323 | − */ | |
| 324 | − if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id))) | |
| 325 | − atc_issue_pending(chan); | |
| 326 | 360 | |
| 327 | −out: | |
| 328 | 361 | return ret; |
| 329 | 362 | } |
| 330 | 363 | |
| @@ -539,8 +572,6 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id) · 208 unmodified lines | ||
| 539 | 572 | /* Give information to tasklet */ |
| 540 | 573 | set_bit(ATC_IS_ERROR, &atchan->status); |
| 541 | 574 | } |
| 542 | − if (pending & AT_DMA_BTC(i)) | |
| 543 | − set_bit(ATC_IS_BTC, &atchan->status); | |
| 544 | 575 | tasklet_schedule(&atchan->tasklet); |
| 545 | 576 | ret = IRQ_HANDLED; |
| 546 | 577 | } |
| @@ -653,14 +684,18 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, · 106 unmodified lines | ||
| 653 | 684 | desc->lli.ctrlb = ctrlb; |
| 654 | 685 | |
| 655 | 686 | desc->txd.cookie = 0; |
| 687 | + desc->len = xfer_count << src_width; | |
| 656 | 688 | |
| 657 | 689 | atc_desc_chain(&first, &prev, desc); |
| 658 | 690 | } |
| 659 | 691 | |
| 660 | 692 | /* First descriptor of the chain embedds additional information */ |
| 661 | 693 | first->txd.cookie = -EBUSY; |
| 662 | − first->len = len; | |
| 694 | + first->total_len = len; | |
| 695 | + | |
| 696 | + /* set transfer width for the calculation of the residue */ | |
| 663 | 697 | first->tx_width = src_width; |
| 698 | + prev->tx_width = src_width; | |
| 664 | 699 | |
| 665 | 700 | /* set end-of-link to the last link descriptor of list*/ |
| 666 | 701 | set_desc_eol(desc); |
| @@ -752,6 +787,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 85 unmodified lines | ||
| 752 | 787 | | ATC_SRC_WIDTH(mem_width) |
| 753 | 788 | | len >> mem_width; |
| 754 | 789 | desc->lli.ctrlb = ctrlb; |
| 790 | + desc->len = len; | |
| 755 | 791 | |
| 756 | 792 | atc_desc_chain(&first, &prev, desc); |
| 757 | 793 | total_len += len; |
| @@ -792,6 +828,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 34 unmodified lines | ||
| 792 | 828 | | ATC_DST_WIDTH(mem_width) |
| 793 | 829 | | len >> reg_width; |
| 794 | 830 | desc->lli.ctrlb = ctrlb; |
| 831 | + desc->len = len; | |
| 795 | 832 | |
| 796 | 833 | atc_desc_chain(&first, &prev, desc); |
| 797 | 834 | total_len += len; |
| @@ -806,8 +843,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 8 unmodified lines | ||
| 806 | 843 | |
| 807 | 844 | /* First descriptor of the chain embedds additional information */ |
| 808 | 845 | first->txd.cookie = -EBUSY; |
| 809 | − first->len = total_len; | |
| 846 | + first->total_len = total_len; | |
| 847 | + | |
| 848 | + /* set transfer width for the calculation of the residue */ | |
| 810 | 849 | first->tx_width = reg_width; |
| 850 | + prev->tx_width = reg_width; | |
| 811 | 851 | |
| 812 | 852 | /* first link descriptor of list is responsible of flags */ |
| 813 | 853 | first->txd.flags = flags; /* client is in control of this ack */ |
| @@ -872,6 +912,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc, · 58 unmodified lines | ||
| 872 | 912 | | ATC_FC_MEM2PER |
| 873 | 913 | | ATC_SIF(atchan->mem_if) |
| 874 | 914 | | ATC_DIF(atchan->per_if); |
| 915 | + desc->len = period_len; | |
| 875 | 916 | break; |
| 876 | 917 | |
| 877 | 918 | case DMA_DEV_TO_MEM: |
| @@ -883,6 +924,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc, · 5 unmodified lines | ||
| 883 | 924 | | ATC_FC_PER2MEM |
| 884 | 925 | | ATC_SIF(atchan->per_if) |
| 885 | 926 | | ATC_DIF(atchan->mem_if); |
| 927 | + desc->len = period_len; | |
| 886 | 928 | break; |
| 887 | 929 | |
| 888 | 930 | default: |
| @@ -964,7 +1006,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, · 75 unmodified lines | ||
| 964 | 1006 | |
| 965 | 1007 | /* First descriptor of the chain embedds additional information */ |
| 966 | 1008 | first->txd.cookie = -EBUSY; |
| 967 | − first->len = buf_len; | |
| 1009 | + first->total_len = buf_len; | |
| 968 | 1010 | first->tx_width = reg_width; |
| 969 | 1011 | |
| 970 | 1012 | return &first->txd; |
| @@ -1118,7 +1160,7 @@ atc_tx_status(struct dma_chan *chan, · 147 unmodified lines | ||
| 1118 | 1160 | spin_lock_irqsave(&atchan->lock, flags); |
| 1119 | 1161 | |
| 1120 | 1162 | /* Get number of bytes left in the active transactions */ |
| 1121 | − bytes = atc_get_bytes_left(chan); | |
| 1163 | + bytes = atc_get_bytes_left(chan, cookie); | |
| 1122 | 1164 | |
| 1123 | 1165 | spin_unlock_irqrestore(&atchan->lock, flags); |
| 1124 | 1166 | |
| @@ -1214,7 +1256,6 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) · 89 unmodified lines | ||
| 1214 | 1256 | |
| 1215 | 1257 | spin_lock_irqsave(&atchan->lock, flags); |
| 1216 | 1258 | atchan->descs_allocated = i; |
| 1217 | − atchan->remain_desc = 0; | |
| 1218 | 1259 | list_splice(&tmp_list, &atchan->free_list); |
| 1219 | 1260 | dma_cookie_init(chan); |
| 1220 | 1261 | spin_unlock_irqrestore(&atchan->lock, flags); |
| @@ -1257,7 +1298,6 @@ static void atc_free_chan_resources(struct dma_chan *chan) · 36 unmodified lines | ||
| 1257 | 1298 | list_splice_init(&atchan->free_list, &list); |
| 1258 | 1299 | atchan->descs_allocated = 0; |
| 1259 | 1300 | atchan->status = 0; |
| 1260 | − atchan->remain_desc = 0; | |
| 1261 | 1301 | |
| 1262 | 1302 | dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); |
| 1263 | 1303 | } |
| @@ -181,8 +181,9 @@ struct at_lli { · 180 unmodified lines | ||
| 181 | 181 | * @at_lli: hardware lli structure |
| 182 | 182 | * @txd: support for the async_tx api |
| 183 | 183 | * @desc_node: node on the channed descriptors list |
| 184 | − * @len: total transaction bytecount | |
| 184 | + * @len: descriptor byte count | |
| 185 | 185 | * @tx_width: transfer width |
| 186 | + * @total_len: total transaction byte count | |
| 186 | 187 | */ |
| 187 | 188 | struct at_desc { |
| 188 | 189 | /* FIRST values the hardware uses */ |
| @@ -194,6 +195,7 @@ struct at_desc { · 5 unmodified lines | ||
| 194 | 195 | struct list_head desc_node; |
| 195 | 196 | size_t len; |
| 196 | 197 | u32 tx_width; |
| 198 | + size_t total_len; | |
| 197 | 199 | }; |
| 198 | 200 | |
| 199 | 201 | static inline struct at_desc * |
| @@ -213,7 +215,6 @@ txd_to_at_desc(struct dma_async_tx_descriptor *txd) · 13 unmodified lines | ||
| 213 | 215 | enum atc_status { |
| 214 | 216 | ATC_IS_ERROR = 0, |
| 215 | 217 | ATC_IS_PAUSED = 1, |
| 216 | − ATC_IS_BTC = 2, | |
| 217 | 218 | ATC_IS_CYCLIC = 24, |
| 218 | 219 | }; |
| 219 | 220 | |
| @@ -231,7 +232,6 @@ enum atc_status { · 11 unmodified lines | ||
| 231 | 232 | * @save_cfg: configuration register that is saved on suspend/resume cycle |
| 232 | 233 | * @save_dscr: for cyclic operations, preserve next descriptor address in |
| 233 | 234 | * the cyclic list on suspend/resume cycle |
| 234 | − * @remain_desc: to save remain desc length | |
| 235 | 235 | * @dma_sconfig: configuration for slave transfers, passed via |
| 236 | 236 | * .device_config |
| 237 | 237 | * @lock: serializes enqueue/dequeue operations to descriptors lists |
| @@ -251,7 +251,6 @@ struct at_dma_chan { · 13 unmodified lines | ||
| 251 | 251 | struct tasklet_struct tasklet; |
| 252 | 252 | u32 save_cfg; |
| 253 | 253 | u32 save_dscr; |
| 254 | − u32 remain_desc; | |
| 255 | 254 | struct dma_slave_config dma_sconfig; |
| 256 | 255 | |
| 257 | 256 | spinlock_t lock; |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include "internal.h" |
| 28 | 28 | |
| 29 | +#define DRV_NAME "dw_dmac" | |
| 30 | + | |
| 29 | 31 | static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, |
| 30 | 32 | struct of_dma *ofdma) |
| 31 | 33 | { |
| @@ -284,7 +286,7 @@ static struct platform_driver dw_driver = { · 252 unmodified lines | ||
| 284 | 286 | .remove = dw_remove, |
| 285 | 287 | .shutdown = dw_shutdown, |
| 286 | 288 | .driver = { |
| 287 | − .name = "dw_dmac", | |
| 289 | + .name = DRV_NAME, | |
| 288 | 290 | .pm = &dw_dev_pm_ops, |
| 289 | 291 | .of_match_table = of_match_ptr(dw_dma_of_id_table), |
| 290 | 292 | .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), |
| @@ -305,3 +307,4 @@ module_exit(dw_exit); · 14 unmodified lines | ||
| 305 | 307 | |
| 306 | 308 | MODULE_LICENSE("GPL v2"); |
| 307 | 309 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver"); |
| 310 | +MODULE_ALIAS("platform:" DRV_NAME); | |
| @@ -531,6 +531,10 @@ static int sdma_run_channel0(struct sdma_engine *sdma) · 530 unmodified lines | ||
| 531 | 531 | dev_err(sdma->dev, "Timeout waiting for CH0 ready\n"); |
| 532 | 532 | } |
| 533 | 533 | |
| 534 | + /* Set bits of CONFIG register with dynamic context switching */ | |
| 535 | + if (readl(sdma->regs + SDMA_H_CONFIG) == 0) | |
| 536 | + writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); | |
| 537 | + | |
| 534 | 538 | return ret ? 0 : -ETIMEDOUT; |
| 535 | 539 | } |
| 536 | 540 | |
| @@ -1394,9 +1398,6 @@ static int sdma_init(struct sdma_engine *sdma) · 857 unmodified lines | ||
| 1394 | 1398 | |
| 1395 | 1399 | writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR); |
| 1396 | 1400 | |
| 1397 | − /* Set bits of CONFIG register with given context switching mode */ | |
| 1398 | − writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); | |
| 1399 | − | |
| 1400 | 1401 | /* Initializes channel's priorities */ |
| 1401 | 1402 | sdma_set_channel_priority(&sdma->channel[0], 7); |
| 1402 | 1403 | |
| @@ -645,6 +645,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, · 644 unmodified lines | ||
| 645 | 645 | pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id); |
| 646 | 646 | pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id); |
| 647 | 647 | |
| 648 | + init_sdma_vm(dqm, q, qpd); | |
| 648 | 649 | retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, |
| 649 | 650 | &q->gart_mqd_addr, &q->properties); |
| 650 | 651 | if (retval != 0) { |
| @@ -652,7 +653,14 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, · 1 unmodified line | ||
| 652 | 653 | return retval; |
| 653 | 654 | } |
| 654 | 655 | |
| 655 | − init_sdma_vm(dqm, q, qpd); | |
| 656 | + retval = mqd->load_mqd(mqd, q->mqd, 0, | |
| 657 | + 0, NULL); | |
| 658 | + if (retval != 0) { | |
| 659 | + deallocate_sdma_queue(dqm, q->sdma_id); | |
| 660 | + mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); | |
| 661 | + return retval; | |
| 662 | + } | |
| 663 | + | |
| 656 | 664 | return 0; |
| 657 | 665 | } |
| 658 | 666 | |
| @@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, · 43 unmodified lines | ||
| 44 | 44 | BUG_ON(!kq || !dev); |
| 45 | 45 | BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ); |
| 46 | 46 | |
| 47 | − pr_debug("kfd: In func %s initializing queue type %d size %d\n", | |
| 47 | + pr_debug("amdkfd: In func %s initializing queue type %d size %d\n", | |
| 48 | 48 | __func__, KFD_QUEUE_TYPE_HIQ, queue_size); |
| 49 | 49 | |
| 50 | 50 | nop.opcode = IT_NOP; |
| @@ -69,12 +69,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev, · 18 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off); |
| 71 | 71 | |
| 72 | − if (prop.doorbell_ptr == NULL) | |
| 72 | + if (prop.doorbell_ptr == NULL) { | |
| 73 | + pr_err("amdkfd: error init doorbell"); | |
| 73 | 74 | goto err_get_kernel_doorbell; |
| 75 | + } | |
| 74 | 76 | |
| 75 | 77 | retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq); |
| 76 | − if (retval != 0) | |
| 78 | + if (retval != 0) { | |
| 79 | + pr_err("amdkfd: error init pq queues size (%d)\n", queue_size); | |
| 77 | 80 | goto err_pq_allocate_vidmem; |
| 81 | + } | |
| 78 | 82 | |
| 79 | 83 | kq->pq_kernel_addr = kq->pq->cpu_ptr; |
| 80 | 84 | kq->pq_gpu_addr = kq->pq->gpu_addr; |
| @@ -165,10 +169,8 @@ err_rptr_allocate_vidmem: · 84 unmodified lines | ||
| 165 | 169 | err_eop_allocate_vidmem: |
| 166 | 170 | kfd_gtt_sa_free(dev, kq->pq); |
| 167 | 171 | err_pq_allocate_vidmem: |
| 168 | − pr_err("kfd: error init pq\n"); | |
| 169 | 172 | kfd_release_kernel_doorbell(dev, prop.doorbell_ptr); |
| 170 | 173 | err_get_kernel_doorbell: |
| 171 | − pr_err("kfd: error init doorbell"); | |
| 172 | 174 | return false; |
| 173 | 175 | |
| 174 | 176 | } |
| @@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq) · 12 unmodified lines | ||
| 187 | 189 | else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ) |
| 188 | 190 | kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj); |
| 189 | 191 | |
| 192 | + kq->mqd->uninit_mqd(kq->mqd, kq->queue->mqd, kq->queue->mqd_mem_obj); | |
| 193 | + | |
| 190 | 194 | kfd_gtt_sa_free(kq->dev, kq->rptr_mem); |
| 191 | 195 | kfd_gtt_sa_free(kq->dev, kq->wptr_mem); |
| 192 | 196 | kq->ops_asic_specific.uninitialize(kq); |
| @@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq, · 18 unmodified lines | ||
| 211 | 215 | queue_address = (unsigned int *)kq->pq_kernel_addr; |
| 212 | 216 | queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t); |
| 213 | 217 | |
| 214 | − pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n", | |
| 218 | + pr_debug("amdkfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n", | |
| 215 | 219 | __func__, rptr, wptr, queue_address); |
| 216 | 220 | |
| 217 | 221 | available_size = (rptr - 1 - wptr + queue_size_dwords) % |
| @@ -296,7 +300,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev, · 78 unmodified lines | ||
| 296 | 300 | } |
| 297 | 301 | |
| 298 | 302 | if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) { |
| 299 | − pr_err("kfd: failed to init kernel queue\n"); | |
| 303 | + pr_err("amdkfd: failed to init kernel queue\n"); | |
| 300 | 304 | kfree(kq); |
| 301 | 305 | return NULL; |
| 302 | 306 | } |
| @@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) · 16 unmodified lines | ||
| 319 | 323 | |
| 320 | 324 | BUG_ON(!dev); |
| 321 | 325 | |
| 322 | − pr_err("kfd: starting kernel queue test\n"); | |
| 326 | + pr_err("amdkfd: starting kernel queue test\n"); | |
| 323 | 327 | |
| 324 | 328 | kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ); |
| 325 | 329 | BUG_ON(!kq); |
| @@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev) · 4 unmodified lines | ||
| 330 | 334 | buffer[i] = kq->nop_packet; |
| 331 | 335 | kq->ops.submit_packet(kq); |
| 332 | 336 | |
| 333 | − pr_err("kfd: ending kernel queue test\n"); | |
| 337 | + pr_err("amdkfd: ending kernel queue test\n"); | |
| 334 | 338 | } |
| 335 | 339 | |
| 336 | 340 | |
| @@ -43,9 +43,10 @@ · 42 unmodified lines | ||
| 43 | 43 | #include "drm_crtc_internal.h" |
| 44 | 44 | #include "drm_internal.h" |
| 45 | 45 | |
| 46 | −static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | |
| 47 | − struct drm_mode_fb_cmd2 *r, | |
| 48 | − struct drm_file *file_priv); | |
| 46 | +static struct drm_framebuffer * | |
| 47 | +internal_framebuffer_create(struct drm_device *dev, | |
| 48 | + struct drm_mode_fb_cmd2 *r, | |
| 49 | + struct drm_file *file_priv); | |
| 49 | 50 | |
| 50 | 51 | /* Avoid boilerplate. I'm tired of typing. */ |
| 51 | 52 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
| @@ -2908,13 +2909,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, · 2856 unmodified lines | ||
| 2908 | 2909 | */ |
| 2909 | 2910 | if (req->flags & DRM_MODE_CURSOR_BO) { |
| 2910 | 2911 | if (req->handle) { |
| 2911 | − fb = add_framebuffer_internal(dev, &fbreq, file_priv); | |
| 2912 | + fb = internal_framebuffer_create(dev, &fbreq, file_priv); | |
| 2912 | 2913 | if (IS_ERR(fb)) { |
| 2913 | 2914 | DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); |
| 2914 | 2915 | return PTR_ERR(fb); |
| 2915 | 2916 | } |
| 2916 | − | |
| 2917 | − drm_framebuffer_reference(fb); | |
| 2918 | 2917 | } else { |
| 2919 | 2918 | fb = NULL; |
| 2920 | 2919 | } |
| @@ -3267,9 +3266,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) · 346 unmodified lines | ||
| 3267 | 3266 | return 0; |
| 3268 | 3267 | } |
| 3269 | 3268 | |
| 3270 | −static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, | |
| 3271 | − struct drm_mode_fb_cmd2 *r, | |
| 3272 | − struct drm_file *file_priv) | |
| 3269 | +static struct drm_framebuffer * | |
| 3270 | +internal_framebuffer_create(struct drm_device *dev, | |
| 3271 | + struct drm_mode_fb_cmd2 *r, | |
| 3272 | + struct drm_file *file_priv) | |
| 3273 | 3273 | { |
| 3274 | 3274 | struct drm_mode_config *config = &dev->mode_config; |
| 3275 | 3275 | struct drm_framebuffer *fb; |
| @@ -3301,12 +3301,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, · 25 unmodified lines | ||
| 3301 | 3301 | return fb; |
| 3302 | 3302 | } |
| 3303 | 3303 | |
| 3304 | − mutex_lock(&file_priv->fbs_lock); | |
| 3305 | − r->fb_id = fb->base.id; | |
| 3306 | − list_add(&fb->filp_head, &file_priv->fbs); | |
| 3307 | − DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); | |
| 3308 | − mutex_unlock(&file_priv->fbs_lock); | |
| 3309 | − | |
| 3310 | 3304 | return fb; |
| 3311 | 3305 | } |
| 3312 | 3306 | |
| @@ -3328,15 +3322,24 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, · 15 unmodified lines | ||
| 3328 | 3322 | int drm_mode_addfb2(struct drm_device *dev, |
| 3329 | 3323 | void *data, struct drm_file *file_priv) |
| 3330 | 3324 | { |
| 3325 | + struct drm_mode_fb_cmd2 *r = data; | |
| 3331 | 3326 | struct drm_framebuffer *fb; |
| 3332 | 3327 | |
| 3333 | 3328 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 3334 | 3329 | return -EINVAL; |
| 3335 | 3330 | |
| 3336 | − fb = add_framebuffer_internal(dev, data, file_priv); | |
| 3331 | + fb = internal_framebuffer_create(dev, r, file_priv); | |
| 3337 | 3332 | if (IS_ERR(fb)) |
| 3338 | 3333 | return PTR_ERR(fb); |
| 3339 | 3334 | |
| 3335 | + /* Transfer ownership to the filp for reaping on close */ | |
| 3336 | + | |
| 3337 | + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); | |
| 3338 | + mutex_lock(&file_priv->fbs_lock); | |
| 3339 | + r->fb_id = fb->base.id; | |
| 3340 | + list_add(&fb->filp_head, &file_priv->fbs); | |
| 3341 | + mutex_unlock(&file_priv->fbs_lock); | |
| 3342 | + | |
| 3340 | 3343 | return 0; |
| 3341 | 3344 | } |
| 3342 | 3345 | |
| @@ -733,10 +733,14 @@ static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr, · 732 unmodified lines | ||
| 733 | 733 | struct drm_dp_sideband_msg_tx *txmsg) |
| 734 | 734 | { |
| 735 | 735 | bool ret; |
| 736 | − mutex_lock(&mgr->qlock); | |
| 736 | + | |
| 737 | + /* | |
| 738 | + * All updates to txmsg->state are protected by mgr->qlock, and the two | |
| 739 | + * cases we check here are terminal states. For those the barriers | |
| 740 | + * provided by the wake_up/wait_event pair are enough. | |
| 741 | + */ | |
| 737 | 742 | ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX || |
| 738 | 743 | txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT); |
| 739 | − mutex_unlock(&mgr->qlock); | |
| 740 | 744 | return ret; |
| 741 | 745 | } |
| 742 | 746 | |
| @@ -1363,12 +1367,13 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr, · 620 unmodified lines | ||
| 1363 | 1367 | return 0; |
| 1364 | 1368 | } |
| 1365 | 1369 | |
| 1366 | −/* must be called holding qlock */ | |
| 1367 | 1370 | static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) |
| 1368 | 1371 | { |
| 1369 | 1372 | struct drm_dp_sideband_msg_tx *txmsg; |
| 1370 | 1373 | int ret; |
| 1371 | 1374 | |
| 1375 | + WARN_ON(!mutex_is_locked(&mgr->qlock)); | |
| 1376 | + | |
| 1372 | 1377 | /* construct a chunk from the first msg in the tx_msg queue */ |
| 1373 | 1378 | if (list_empty(&mgr->tx_msg_downq)) { |
| 1374 | 1379 | mgr->tx_down_in_progress = false; |
| @@ -403,7 +403,7 @@ static int check_free_hole(u64 start, u64 end, u64 size, unsigned alignment) · 402 unmodified lines | ||
| 403 | 403 | unsigned rem; |
| 404 | 404 | |
| 405 | 405 | rem = do_div(tmp, alignment); |
| 406 | − if (tmp) | |
| 406 | + if (rem) | |
| 407 | 407 | start += alignment - rem; |
| 408 | 408 | } |
| 409 | 409 | |
| @@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | config DRM_EXYNOS_DP |
| 52 | 52 | bool "EXYNOS DRM DP driver support" |
| 53 | − depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) | |
| 53 | + depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) | |
| 54 | 54 | default DRM_EXYNOS |
| 55 | 55 | select DRM_PANEL |
| 56 | 56 | help |
| @@ -888,8 +888,8 @@ static int decon_probe(struct platform_device *pdev) · 887 unmodified lines | ||
| 888 | 888 | of_node_put(i80_if_timings); |
| 889 | 889 | |
| 890 | 890 | ctx->regs = of_iomap(dev->of_node, 0); |
| 891 | − if (IS_ERR(ctx->regs)) { | |
| 892 | − ret = PTR_ERR(ctx->regs); | |
| 891 | + if (!ctx->regs) { | |
| 892 | + ret = -ENOMEM; | |
| 893 | 893 | goto err_del_component; |
| 894 | 894 | } |
| 895 | 895 | |
| @@ -1,245 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2011 Samsung Electronics Co., Ltd. | |
| 3 | − * Authors: | |
| 4 | − * Inki Dae <inki.dae@samsung.com> | |
| 5 | − * Joonyoung Shim <jy0922.shim@samsung.com> | |
| 6 | − * Seung-Woo Kim <sw0312.kim@samsung.com> | |
| 7 | − * | |
| 8 | − * This program is free software; you can redistribute it and/or modify it | |
| 9 | − * under the terms of the GNU General Public License as published by the | |
| 10 | − * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | − * option) any later version. | |
| 12 | − */ | |
| 13 | − | |
| 14 | −#include <drm/drmP.h> | |
| 15 | −#include <drm/drm_crtc_helper.h> | |
| 16 | − | |
| 17 | −#include <drm/exynos_drm.h> | |
| 18 | −#include "exynos_drm_drv.h" | |
| 19 | −#include "exynos_drm_encoder.h" | |
| 20 | −#include "exynos_drm_connector.h" | |
| 21 | − | |
| 22 | −#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ | |
| 23 | − drm_connector) | |
| 24 | − | |
| 25 | −struct exynos_drm_connector { | |
| 26 | − struct drm_connector drm_connector; | |
| 27 | − uint32_t encoder_id; | |
| 28 | − struct exynos_drm_display *display; | |
| 29 | −}; | |
| 30 | − | |
| 31 | −static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |
| 32 | −{ | |
| 33 | − struct exynos_drm_connector *exynos_connector = | |
| 34 | − to_exynos_connector(connector); | |
| 35 | − struct exynos_drm_display *display = exynos_connector->display; | |
| 36 | − struct edid *edid = NULL; | |
| 37 | − unsigned int count = 0; | |
| 38 | − int ret; | |
| 39 | − | |
| 40 | − /* | |
| 41 | − * if get_edid() exists then get_edid() callback of hdmi side | |
| 42 | − * is called to get edid data through i2c interface else | |
| 43 | − * get timing from the FIMD driver(display controller). | |
| 44 | − * | |
| 45 | − * P.S. in case of lcd panel, count is always 1 if success | |
| 46 | − * because lcd panel has only one mode. | |
| 47 | − */ | |
| 48 | − if (display->ops->get_edid) { | |
| 49 | − edid = display->ops->get_edid(display, connector); | |
| 50 | − if (IS_ERR_OR_NULL(edid)) { | |
| 51 | − ret = PTR_ERR(edid); | |
| 52 | − edid = NULL; | |
| 53 | − DRM_ERROR("Panel operation get_edid failed %d\n", ret); | |
| 54 | − goto out; | |
| 55 | − } | |
| 56 | − | |
| 57 | − count = drm_add_edid_modes(connector, edid); | |
| 58 | − if (!count) { | |
| 59 | − DRM_ERROR("Add edid modes failed %d\n", count); | |
| 60 | − goto out; | |
| 61 | − } | |
| 62 | − | |
| 63 | − drm_mode_connector_update_edid_property(connector, edid); | |
| 64 | − } else { | |
| 65 | − struct exynos_drm_panel_info *panel; | |
| 66 | − struct drm_display_mode *mode = drm_mode_create(connector->dev); | |
| 67 | − if (!mode) { | |
| 68 | − DRM_ERROR("failed to create a new display mode.\n"); | |
| 69 | − return 0; | |
| 70 | − } | |
| 71 | − | |
| 72 | − if (display->ops->get_panel) | |
| 73 | − panel = display->ops->get_panel(display); | |
| 74 | − else { | |
| 75 | − drm_mode_destroy(connector->dev, mode); | |
| 76 | − return 0; | |
| 77 | − } | |
| 78 | − | |
| 79 | − drm_display_mode_from_videomode(&panel->vm, mode); | |
| 80 | − mode->width_mm = panel->width_mm; | |
| 81 | − mode->height_mm = panel->height_mm; | |
| 82 | − connector->display_info.width_mm = mode->width_mm; | |
| 83 | − connector->display_info.height_mm = mode->height_mm; | |
| 84 | − | |
| 85 | − mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | |
| 86 | − drm_mode_set_name(mode); | |
| 87 | − drm_mode_probed_add(connector, mode); | |
| 88 | − | |
| 89 | − count = 1; | |
| 90 | − } | |
| 91 | − | |
| 92 | −out: | |
| 93 | − kfree(edid); | |
| 94 | − return count; | |
| 95 | −} | |
| 96 | − | |
| 97 | −static int exynos_drm_connector_mode_valid(struct drm_connector *connector, | |
| 98 | − struct drm_display_mode *mode) | |
| 99 | −{ | |
| 100 | − struct exynos_drm_connector *exynos_connector = | |
| 101 | − to_exynos_connector(connector); | |
| 102 | − struct exynos_drm_display *display = exynos_connector->display; | |
| 103 | − int ret = MODE_BAD; | |
| 104 | − | |
| 105 | − DRM_DEBUG_KMS("%s\n", __FILE__); | |
| 106 | − | |
| 107 | − if (display->ops->check_mode) | |
| 108 | − if (!display->ops->check_mode(display, mode)) | |
| 109 | − ret = MODE_OK; | |
| 110 | − | |
| 111 | − return ret; | |
| 112 | −} | |
| 113 | − | |
| 114 | −static struct drm_encoder *exynos_drm_best_encoder( | |
| 115 | − struct drm_connector *connector) | |
| 116 | −{ | |
| 117 | − struct drm_device *dev = connector->dev; | |
| 118 | − struct exynos_drm_connector *exynos_connector = | |
| 119 | − to_exynos_connector(connector); | |
| 120 | − return drm_encoder_find(dev, exynos_connector->encoder_id); | |
| 121 | −} | |
| 122 | − | |
| 123 | −static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { | |
| 124 | − .get_modes = exynos_drm_connector_get_modes, | |
| 125 | − .mode_valid = exynos_drm_connector_mode_valid, | |
| 126 | − .best_encoder = exynos_drm_best_encoder, | |
| 127 | −}; | |
| 128 | − | |
| 129 | −static int exynos_drm_connector_fill_modes(struct drm_connector *connector, | |
| 130 | − unsigned int max_width, unsigned int max_height) | |
| 131 | −{ | |
| 132 | − struct exynos_drm_connector *exynos_connector = | |
| 133 | − to_exynos_connector(connector); | |
| 134 | − struct exynos_drm_display *display = exynos_connector->display; | |
| 135 | − unsigned int width, height; | |
| 136 | − | |
| 137 | − width = max_width; | |
| 138 | − height = max_height; | |
| 139 | − | |
| 140 | − /* | |
| 141 | − * if specific driver want to find desired_mode using maxmum | |
| 142 | − * resolution then get max width and height from that driver. | |
| 143 | − */ | |
| 144 | − if (display->ops->get_max_resol) | |
| 145 | − display->ops->get_max_resol(display, &width, &height); | |
| 146 | − | |
| 147 | − return drm_helper_probe_single_connector_modes(connector, width, | |
| 148 | − height); | |
| 149 | −} | |
| 150 | − | |
| 151 | −/* get detection status of display device. */ | |
| 152 | −static enum drm_connector_status | |
| 153 | −exynos_drm_connector_detect(struct drm_connector *connector, bool force) | |
| 154 | −{ | |
| 155 | − struct exynos_drm_connector *exynos_connector = | |
| 156 | − to_exynos_connector(connector); | |
| 157 | − struct exynos_drm_display *display = exynos_connector->display; | |
| 158 | − enum drm_connector_status status = connector_status_disconnected; | |
| 159 | − | |
| 160 | − if (display->ops->is_connected) { | |
| 161 | − if (display->ops->is_connected(display)) | |
| 162 | − status = connector_status_connected; | |
| 163 | − else | |
| 164 | − status = connector_status_disconnected; | |
| 165 | − } | |
| 166 | − | |
| 167 | − return status; | |
| 168 | −} | |
| 169 | − | |
| 170 | −static void exynos_drm_connector_destroy(struct drm_connector *connector) | |
| 171 | −{ | |
| 172 | − struct exynos_drm_connector *exynos_connector = | |
| 173 | − to_exynos_connector(connector); | |
| 174 | − | |
| 175 | − drm_connector_unregister(connector); | |
| 176 | − drm_connector_cleanup(connector); | |
| 177 | − kfree(exynos_connector); | |
| 178 | −} | |
| 179 | − | |
| 180 | −static struct drm_connector_funcs exynos_connector_funcs = { | |
| 181 | − .dpms = drm_helper_connector_dpms, | |
| 182 | − .fill_modes = exynos_drm_connector_fill_modes, | |
| 183 | − .detect = exynos_drm_connector_detect, | |
| 184 | − .destroy = exynos_drm_connector_destroy, | |
| 185 | −}; | |
| 186 | − | |
| 187 | −struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |
| 188 | − struct drm_encoder *encoder) | |
| 189 | −{ | |
| 190 | − struct exynos_drm_connector *exynos_connector; | |
| 191 | − struct exynos_drm_display *display = exynos_drm_get_display(encoder); | |
| 192 | − struct drm_connector *connector; | |
| 193 | − int type; | |
| 194 | − int err; | |
| 195 | − | |
| 196 | − exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL); | |
| 197 | − if (!exynos_connector) | |
| 198 | − return NULL; | |
| 199 | − | |
| 200 | − connector = &exynos_connector->drm_connector; | |
| 201 | − | |
| 202 | − switch (display->type) { | |
| 203 | − case EXYNOS_DISPLAY_TYPE_HDMI: | |
| 204 | − type = DRM_MODE_CONNECTOR_HDMIA; | |
| 205 | − connector->interlace_allowed = true; | |
| 206 | − connector->polled = DRM_CONNECTOR_POLL_HPD; | |
| 207 | − break; | |
| 208 | − case EXYNOS_DISPLAY_TYPE_VIDI: | |
| 209 | − type = DRM_MODE_CONNECTOR_VIRTUAL; | |
| 210 | − connector->polled = DRM_CONNECTOR_POLL_HPD; | |
| 211 | − break; | |
| 212 | − default: | |
| 213 | − type = DRM_MODE_CONNECTOR_Unknown; | |
| 214 | − break; | |
| 215 | − } | |
| 216 | − | |
| 217 | − drm_connector_init(dev, connector, &exynos_connector_funcs, type); | |
| 218 | − drm_connector_helper_add(connector, &exynos_connector_helper_funcs); | |
| 219 | − | |
| 220 | − err = drm_connector_register(connector); | |
| 221 | − if (err) | |
| 222 | − goto err_connector; | |
| 223 | − | |
| 224 | − exynos_connector->encoder_id = encoder->base.id; | |
| 225 | − exynos_connector->display = display; | |
| 226 | − connector->dpms = DRM_MODE_DPMS_OFF; | |
| 227 | − connector->encoder = encoder; | |
| 228 | − | |
| 229 | − err = drm_mode_connector_attach_encoder(connector, encoder); | |
| 230 | − if (err) { | |
| 231 | − DRM_ERROR("failed to attach a connector to a encoder\n"); | |
| 232 | − goto err_sysfs; | |
| 233 | − } | |
| 234 | − | |
| 235 | − DRM_DEBUG_KMS("connector has been created\n"); | |
| 236 | − | |
| 237 | − return connector; | |
| 238 | − | |
| 239 | −err_sysfs: | |
| 240 | − drm_connector_unregister(connector); | |
| 241 | −err_connector: | |
| 242 | − drm_connector_cleanup(connector); | |
| 243 | − kfree(exynos_connector); | |
| 244 | − return NULL; | |
| 245 | −} | |
| @@ -1,20 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2011 Samsung Electronics Co., Ltd. | |
| 3 | − * Authors: | |
| 4 | − * Inki Dae <inki.dae@samsung.com> | |
| 5 | − * Joonyoung Shim <jy0922.shim@samsung.com> | |
| 6 | − * Seung-Woo Kim <sw0312.kim@samsung.com> | |
| 7 | − * | |
| 8 | − * This program is free software; you can redistribute it and/or modify it | |
| 9 | − * under the terms of the GNU General Public License as published by the | |
| 10 | − * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | − * option) any later version. | |
| 12 | − */ | |
| 13 | − | |
| 14 | −#ifndef _EXYNOS_DRM_CONNECTOR_H_ | |
| 15 | −#define _EXYNOS_DRM_CONNECTOR_H_ | |
| 16 | − | |
| 17 | −struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, | |
| 18 | − struct drm_encoder *encoder); | |
| 19 | − | |
| 20 | −#endif | |
| @@ -284,14 +284,9 @@ static void fimd_clear_channel(struct fimd_context *ctx) · 283 unmodified lines | ||
| 284 | 284 | } |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | −static int fimd_ctx_initialize(struct fimd_context *ctx, | |
| 287 | +static int fimd_iommu_attach_devices(struct fimd_context *ctx, | |
| 288 | 288 | struct drm_device *drm_dev) |
| 289 | 289 | { |
| 290 | − struct exynos_drm_private *priv; | |
| 291 | − priv = drm_dev->dev_private; | |
| 292 | − | |
| 293 | − ctx->drm_dev = drm_dev; | |
| 294 | − ctx->pipe = priv->pipe++; | |
| 295 | 290 | |
| 296 | 291 | /* attach this sub driver to iommu mapping if supported. */ |
| 297 | 292 | if (is_drm_iommu_supported(ctx->drm_dev)) { |
| @@ -313,7 +308,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx, · 15 unmodified lines | ||
| 313 | 308 | return 0; |
| 314 | 309 | } |
| 315 | 310 | |
| 316 | −static void fimd_ctx_remove(struct fimd_context *ctx) | |
| 311 | +static void fimd_iommu_detach_devices(struct fimd_context *ctx) | |
| 317 | 312 | { |
| 318 | 313 | /* detach this sub driver from iommu mapping if supported. */ |
| 319 | 314 | if (is_drm_iommu_supported(ctx->drm_dev)) |
| @@ -1056,25 +1051,23 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) · 736 unmodified lines | ||
| 1056 | 1051 | { |
| 1057 | 1052 | struct fimd_context *ctx = dev_get_drvdata(dev); |
| 1058 | 1053 | struct drm_device *drm_dev = data; |
| 1054 | + struct exynos_drm_private *priv = drm_dev->dev_private; | |
| 1059 | 1055 | int ret; |
| 1060 | 1056 | |
| 1061 | − ret = fimd_ctx_initialize(ctx, drm_dev); | |
| 1062 | − if (ret) { | |
| 1063 | − DRM_ERROR("fimd_ctx_initialize failed.\n"); | |
| 1064 | − return ret; | |
| 1065 | − } | |
| 1057 | + ctx->drm_dev = drm_dev; | |
| 1058 | + ctx->pipe = priv->pipe++; | |
| 1066 | 1059 | |
| 1067 | 1060 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, |
| 1068 | 1061 | EXYNOS_DISPLAY_TYPE_LCD, |
| 1069 | 1062 | &fimd_crtc_ops, ctx); |
| 1070 | − if (IS_ERR(ctx->crtc)) { | |
| 1071 | − fimd_ctx_remove(ctx); | |
| 1072 | − return PTR_ERR(ctx->crtc); | |
| 1073 | − } | |
| 1074 | 1063 | |
| 1075 | 1064 | if (ctx->display) |
| 1076 | 1065 | exynos_drm_create_enc_conn(drm_dev, ctx->display); |
| 1077 | 1066 | |
| 1067 | + ret = fimd_iommu_attach_devices(ctx, drm_dev); | |
| 1068 | + if (ret) | |
| 1069 | + return ret; | |
| 1070 | + | |
| 1078 | 1071 | return 0; |
| 1079 | 1072 | |
| 1080 | 1073 | } |
| @@ -1086,10 +1079,10 @@ static void fimd_unbind(struct device *dev, struct device *master, · 5 unmodified lines | ||
| 1086 | 1079 | |
| 1087 | 1080 | fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); |
| 1088 | 1081 | |
| 1082 | + fimd_iommu_detach_devices(ctx); | |
| 1083 | + | |
| 1089 | 1084 | if (ctx->display) |
| 1090 | 1085 | exynos_dpi_remove(ctx->display); |
| 1091 | − | |
| 1092 | − fimd_ctx_remove(ctx); | |
| 1093 | 1086 | } |
| 1094 | 1087 | |
| 1095 | 1088 | static const struct component_ops fimd_component_ops = { |
| @@ -175,7 +175,7 @@ static int exynos_disable_plane(struct drm_plane *plane) · 174 unmodified lines | ||
| 175 | 175 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); |
| 176 | 176 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc); |
| 177 | 177 | |
| 178 | − if (exynos_crtc->ops->win_disable) | |
| 178 | + if (exynos_crtc && exynos_crtc->ops->win_disable) | |
| 179 | 179 | exynos_crtc->ops->win_disable(exynos_crtc, |
| 180 | 180 | exynos_plane->zpos); |
| 181 | 181 | |
| @@ -2936,9 +2936,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 2935 unmodified lines | ||
| 2936 | 2936 | req = obj->last_read_req; |
| 2937 | 2937 | |
| 2938 | 2938 | /* Do this after OLR check to make sure we make forward progress polling |
| 2939 | − * on this IOCTL with a timeout <=0 (like busy ioctl) | |
| 2939 | + * on this IOCTL with a timeout == 0 (like busy ioctl) | |
| 2940 | 2940 | */ |
| 2941 | − if (args->timeout_ns <= 0) { | |
| 2941 | + if (args->timeout_ns == 0) { | |
| 2942 | 2942 | ret = -ETIME; |
| 2943 | 2943 | goto out; |
| 2944 | 2944 | } |
| @@ -2948,7 +2948,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 3 unmodified lines | ||
| 2948 | 2948 | i915_gem_request_reference(req); |
| 2949 | 2949 | mutex_unlock(&dev->struct_mutex); |
| 2950 | 2950 | |
| 2951 | − ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns, | |
| 2951 | + ret = __i915_wait_request(req, reset_counter, true, | |
| 2952 | + args->timeout_ns > 0 ? &args->timeout_ns : NULL, | |
| 2952 | 2953 | file->driver_priv); |
| 2953 | 2954 | mutex_lock(&dev->struct_mutex); |
| 2954 | 2955 | i915_gem_request_unreference(req); |
| @@ -4792,6 +4793,9 @@ i915_gem_init_hw(struct drm_device *dev) · 1837 unmodified lines | ||
| 4792 | 4793 | if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) |
| 4793 | 4794 | return -EIO; |
| 4794 | 4795 | |
| 4796 | + /* Double layer security blanket, see i915_gem_init() */ | |
| 4797 | + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); | |
| 4798 | + | |
| 4795 | 4799 | if (dev_priv->ellc_size) |
| 4796 | 4800 | I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); |
| 4797 | 4801 | |
| @@ -4824,7 +4828,7 @@ i915_gem_init_hw(struct drm_device *dev) · 26 unmodified lines | ||
| 4824 | 4828 | for_each_ring(ring, dev_priv, i) { |
| 4825 | 4829 | ret = ring->init_hw(ring); |
| 4826 | 4830 | if (ret) |
| 4827 | − return ret; | |
| 4831 | + goto out; | |
| 4828 | 4832 | } |
| 4829 | 4833 | |
| 4830 | 4834 | for (i = 0; i < NUM_L3_SLICES(dev); i++) |
| @@ -4841,9 +4845,11 @@ i915_gem_init_hw(struct drm_device *dev) · 10 unmodified lines | ||
| 4841 | 4845 | DRM_ERROR("Context enable failed %d\n", ret); |
| 4842 | 4846 | i915_gem_cleanup_ringbuffer(dev); |
| 4843 | 4847 | |
| 4844 | − return ret; | |
| 4848 | + goto out; | |
| 4845 | 4849 | } |
| 4846 | 4850 | |
| 4851 | +out: | |
| 4852 | + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | |
| 4847 | 4853 | return ret; |
| 4848 | 4854 | } |
| 4849 | 4855 | |
| @@ -4877,6 +4883,14 @@ int i915_gem_init(struct drm_device *dev) · 27 unmodified lines | ||
| 4877 | 4883 | dev_priv->gt.stop_ring = intel_logical_ring_stop; |
| 4878 | 4884 | } |
| 4879 | 4885 | |
| 4886 | + /* This is just a security blanket to placate dragons. | |
| 4887 | + * On some systems, we very sporadically observe that the first TLBs | |
| 4888 | + * used by the CS may be stale, despite us poking the TLB reset. If | |
| 4889 | + * we hold the forcewake during initialisation these problems | |
| 4890 | + * just magically go away. | |
| 4891 | + */ | |
| 4892 | + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); | |
| 4893 | + | |
| 4880 | 4894 | ret = i915_gem_init_userptr(dev); |
| 4881 | 4895 | if (ret) |
| 4882 | 4896 | goto out_unlock; |
| @@ -4903,6 +4917,7 @@ int i915_gem_init(struct drm_device *dev) · 20 unmodified lines | ||
| 4903 | 4917 | } |
| 4904 | 4918 | |
| 4905 | 4919 | out_unlock: |
| 4920 | + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | |
| 4906 | 4921 | mutex_unlock(&dev->struct_mutex); |
| 4907 | 4922 | |
| 4908 | 4923 | return ret; |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <drm/i915_drm.h> |
| 38 | 38 | #include "i915_drv.h" |
| 39 | 39 | #include "i915_trace.h" |
| 40 | +#include <drm/drm_atomic.h> | |
| 40 | 41 | #include <drm/drm_atomic_helper.h> |
| 41 | 42 | #include <drm/drm_dp_helper.h> |
| 42 | 43 | #include <drm/drm_crtc_helper.h> |
| @@ -2416,6 +2417,14 @@ out_unref_obj: · 2373 unmodified lines | ||
| 2416 | 2417 | return false; |
| 2417 | 2418 | } |
| 2418 | 2419 | |
| 2420 | +/* Update plane->state->fb to match plane->fb after driver-internal updates */ | |
| 2421 | +static void | |
| 2422 | +update_state_fb(struct drm_plane *plane) | |
| 2423 | +{ | |
| 2424 | + if (plane->fb != plane->state->fb) | |
| 2425 | + drm_atomic_set_fb_for_plane(plane->state, plane->fb); | |
| 2426 | +} | |
| 2427 | + | |
| 2419 | 2428 | static void |
| 2420 | 2429 | intel_find_plane_obj(struct intel_crtc *intel_crtc, |
| 2421 | 2430 | struct intel_initial_plane_config *plane_config) |
| @@ -2462,6 +2471,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc, · 40 unmodified lines | ||
| 2462 | 2471 | break; |
| 2463 | 2472 | } |
| 2464 | 2473 | } |
| 2474 | + | |
| 2475 | + update_state_fb(intel_crtc->base.primary); | |
| 2465 | 2476 | } |
| 2466 | 2477 | |
| 2467 | 2478 | static void i9xx_update_primary_plane(struct drm_crtc *crtc, |
| @@ -6602,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, · 4134 unmodified lines | ||
| 6602 | 6613 | struct drm_framebuffer *fb; |
| 6603 | 6614 | struct intel_framebuffer *intel_fb; |
| 6604 | 6615 | |
| 6616 | + val = I915_READ(DSPCNTR(plane)); | |
| 6617 | + if (!(val & DISPLAY_PLANE_ENABLE)) | |
| 6618 | + return; | |
| 6619 | + | |
| 6605 | 6620 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
| 6606 | 6621 | if (!intel_fb) { |
| 6607 | 6622 | DRM_DEBUG_KMS("failed to alloc fb\n"); |
| @@ -6610,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, · 2 unmodified lines | ||
| 6610 | 6625 | |
| 6611 | 6626 | fb = &intel_fb->base; |
| 6612 | 6627 | |
| 6613 | − val = I915_READ(DSPCNTR(plane)); | |
| 6614 | − | |
| 6615 | 6628 | if (INTEL_INFO(dev)->gen >= 4) |
| 6616 | 6629 | if (val & DISPPLANE_TILED) |
| 6617 | 6630 | plane_config->tiling = I915_TILING_X; |
| @@ -6650,6 +6663,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, · 32 unmodified lines | ||
| 6650 | 6663 | plane_config->size); |
| 6651 | 6664 | |
| 6652 | 6665 | crtc->base.primary->fb = fb; |
| 6666 | + update_state_fb(crtc->base.primary); | |
| 6653 | 6667 | } |
| 6654 | 6668 | |
| 6655 | 6669 | static void chv_crtc_clock_get(struct intel_crtc *crtc, |
| @@ -7643,6 +7657,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, · 987 unmodified lines | ||
| 7643 | 7657 | fb = &intel_fb->base; |
| 7644 | 7658 | |
| 7645 | 7659 | val = I915_READ(PLANE_CTL(pipe, 0)); |
| 7660 | + if (!(val & PLANE_CTL_ENABLE)) | |
| 7661 | + goto error; | |
| 7662 | + | |
| 7646 | 7663 | if (val & PLANE_CTL_TILED_MASK) |
| 7647 | 7664 | plane_config->tiling = I915_TILING_X; |
| 7648 | 7665 | |
| @@ -7687,6 +7704,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, · 38 unmodified lines | ||
| 7687 | 7704 | plane_config->size); |
| 7688 | 7705 | |
| 7689 | 7706 | crtc->base.primary->fb = fb; |
| 7707 | + update_state_fb(crtc->base.primary); | |
| 7690 | 7708 | return; |
| 7691 | 7709 | |
| 7692 | 7710 | error: |
| @@ -7730,6 +7748,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, · 37 unmodified lines | ||
| 7730 | 7748 | struct drm_framebuffer *fb; |
| 7731 | 7749 | struct intel_framebuffer *intel_fb; |
| 7732 | 7750 | |
| 7751 | + val = I915_READ(DSPCNTR(pipe)); | |
| 7752 | + if (!(val & DISPLAY_PLANE_ENABLE)) | |
| 7753 | + return; | |
| 7754 | + | |
| 7733 | 7755 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
| 7734 | 7756 | if (!intel_fb) { |
| 7735 | 7757 | DRM_DEBUG_KMS("failed to alloc fb\n"); |
| @@ -7738,8 +7760,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, · 2 unmodified lines | ||
| 7738 | 7760 | |
| 7739 | 7761 | fb = &intel_fb->base; |
| 7740 | 7762 | |
| 7741 | − val = I915_READ(DSPCNTR(pipe)); | |
| 7742 | − | |
| 7743 | 7763 | if (INTEL_INFO(dev)->gen >= 4) |
| 7744 | 7764 | if (val & DISPPLANE_TILED) |
| 7745 | 7765 | plane_config->tiling = I915_TILING_X; |
| @@ -7778,6 +7798,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, · 32 unmodified lines | ||
| 7778 | 7798 | plane_config->size); |
| 7779 | 7799 | |
| 7780 | 7800 | crtc->base.primary->fb = fb; |
| 7801 | + update_state_fb(crtc->base.primary); | |
| 7781 | 7802 | } |
| 7782 | 7803 | |
| 7783 | 7804 | static bool ironlake_get_pipe_config(struct intel_crtc *crtc, |
| @@ -9716,7 +9737,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) · 1932 unmodified lines | ||
| 9716 | 9737 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
| 9717 | 9738 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 9718 | 9739 | |
| 9719 | − WARN_ON(!in_irq()); | |
| 9740 | + WARN_ON(!in_interrupt()); | |
| 9720 | 9741 | |
| 9721 | 9742 | if (crtc == NULL) |
| 9722 | 9743 | return; |
| @@ -9816,6 +9837,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, · 93 unmodified lines | ||
| 9816 | 9837 | drm_gem_object_reference(&obj->base); |
| 9817 | 9838 | |
| 9818 | 9839 | crtc->primary->fb = fb; |
| 9840 | + update_state_fb(crtc->primary); | |
| 9819 | 9841 | |
| 9820 | 9842 | work->pending_flip_obj = obj; |
| 9821 | 9843 | |
| @@ -9884,6 +9906,7 @@ cleanup_unpin: · 62 unmodified lines | ||
| 9884 | 9906 | cleanup_pending: |
| 9885 | 9907 | atomic_dec(&intel_crtc->unpin_work_count); |
| 9886 | 9908 | crtc->primary->fb = old_fb; |
| 9909 | + update_state_fb(crtc->primary); | |
| 9887 | 9910 | drm_gem_object_unreference(&work->old_fb_obj->base); |
| 9888 | 9911 | drm_gem_object_unreference(&obj->base); |
| 9889 | 9912 | mutex_unlock(&dev->struct_mutex); |
| @@ -13718,6 +13741,7 @@ void intel_modeset_gem_init(struct drm_device *dev) · 3828 unmodified lines | ||
| 13718 | 13741 | to_intel_crtc(c)->pipe); |
| 13719 | 13742 | drm_framebuffer_unreference(c->primary->fb); |
| 13720 | 13743 | c->primary->fb = NULL; |
| 13744 | + update_state_fb(c->primary); | |
| 13721 | 13745 | } |
| 13722 | 13746 | } |
| 13723 | 13747 | mutex_unlock(&dev->struct_mutex); |
| @@ -1048,8 +1048,14 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev) · 1047 unmodified lines | ||
| 1048 | 1048 | |
| 1049 | 1049 | /* We need to init first for ECOBUS access and then |
| 1050 | 1050 | * determine later if we want to reinit, in case of MT access is |
| 1051 | − * not working | |
| 1051 | + * not working. In this stage we don't know which flavour this | |
| 1052 | + * ivb is, so it is better to reset also the gen6 fw registers | |
| 1053 | + * before the ecobus check. | |
| 1052 | 1054 | */ |
| 1055 | + | |
| 1056 | + __raw_i915_write32(dev_priv, FORCEWAKE, 0); | |
| 1057 | + __raw_posting_read(dev_priv, ECOBUS); | |
| 1058 | + | |
| 1053 | 1059 | fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, |
| 1054 | 1060 | FORCEWAKE_MT, FORCEWAKE_MT_ACK); |
| 1055 | 1061 | |
| @@ -340,11 +340,13 @@ nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine, · 339 unmodified lines | ||
| 340 | 340 | |
| 341 | 341 | /* switch mmio to cpu's native endianness */ |
| 342 | 342 | #ifndef __BIG_ENDIAN |
| 343 | − if (ioread32_native(map + 0x000004) != 0x00000000) | |
| 343 | + if (ioread32_native(map + 0x000004) != 0x00000000) { | |
| 344 | 344 | #else |
| 345 | − if (ioread32_native(map + 0x000004) == 0x00000000) | |
| 345 | + if (ioread32_native(map + 0x000004) == 0x00000000) { | |
| 346 | 346 | #endif |
| 347 | 347 | iowrite32_native(0x01000001, map + 0x000004); |
| 348 | + ioread32_native(map); | |
| 349 | + } | |
| 348 | 350 | |
| 349 | 351 | /* read boot0 and strapping information */ |
| 350 | 352 | boot0 = ioread32_native(map + 0x000000); |
| @@ -140,6 +140,49 @@ gm100_identify(struct nvkm_device *device) · 139 unmodified lines | ||
| 140 | 140 | device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass; |
| 141 | 141 | device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass; |
| 142 | 142 | device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass; |
| 143 | +#endif | |
| 144 | + break; | |
| 145 | + case 0x126: | |
| 146 | + device->cname = "GM206"; | |
| 147 | + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass; | |
| 148 | + device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass; | |
| 149 | + device->oclass[NVDEV_SUBDEV_I2C ] = gm204_i2c_oclass; | |
| 150 | + device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass; | |
| 151 | +#if 0 | |
| 152 | + /* looks to be some non-trivial changes */ | |
| 153 | + device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass; | |
| 154 | + /* priv ring says no to 0x10eb14 writes */ | |
| 155 | + device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass; | |
| 156 | +#endif | |
| 157 | + device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | |
| 158 | + device->oclass[NVDEV_SUBDEV_DEVINIT] = gm204_devinit_oclass; | |
| 159 | + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; | |
| 160 | + device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass; | |
| 161 | + device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; | |
| 162 | + device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass; | |
| 163 | + device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass; | |
| 164 | + device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass; | |
| 165 | + device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | |
| 166 | + device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass; | |
| 167 | + device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass; | |
| 168 | + device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass; | |
| 169 | +#if 0 | |
| 170 | + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | |
| 171 | +#endif | |
| 172 | + device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass; | |
| 173 | +#if 0 | |
| 174 | + device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass; | |
| 175 | + device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass; | |
| 176 | + device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass; | |
| 177 | +#endif | |
| 178 | + device->oclass[NVDEV_ENGINE_DISP ] = gm204_disp_oclass; | |
| 179 | +#if 0 | |
| 180 | + device->oclass[NVDEV_ENGINE_CE0 ] = &gm204_ce0_oclass; | |
| 181 | + device->oclass[NVDEV_ENGINE_CE1 ] = &gm204_ce1_oclass; | |
| 182 | + device->oclass[NVDEV_ENGINE_CE2 ] = &gm204_ce2_oclass; | |
| 183 | + device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass; | |
| 184 | + device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass; | |
| 185 | + device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass; | |
| 143 | 186 | #endif |
| 144 | 187 | break; |
| 145 | 188 | default: |
| @@ -502,72 +502,57 @@ nv04_fifo_intr(struct nvkm_subdev *subdev) · 501 unmodified lines | ||
| 502 | 502 | { |
| 503 | 503 | struct nvkm_device *device = nv_device(subdev); |
| 504 | 504 | struct nv04_fifo_priv *priv = (void *)subdev; |
| 505 | − uint32_t status, reassign; | |
| 506 | − int cnt = 0; | |
| 505 | + u32 mask = nv_rd32(priv, NV03_PFIFO_INTR_EN_0); | |
| 506 | + u32 stat = nv_rd32(priv, NV03_PFIFO_INTR_0) & mask; | |
| 507 | + u32 reassign, chid, get, sem; | |
| 507 | 508 | |
| 508 | 509 | reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1; |
| 509 | − while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { | |
| 510 | − uint32_t chid, get; | |
| 511 | − | |
| 512 | − nv_wr32(priv, NV03_PFIFO_CACHES, 0); | |
| 513 | − | |
| 514 | − chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max; | |
| 515 | − get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET); | |
| 510 | + nv_wr32(priv, NV03_PFIFO_CACHES, 0); | |
| 516 | 511 | |
| 517 | − if (status & NV_PFIFO_INTR_CACHE_ERROR) { | |
| 518 | − nv04_fifo_cache_error(device, priv, chid, get); | |
| 519 | − status &= ~NV_PFIFO_INTR_CACHE_ERROR; | |
| 520 | − } | |
| 512 | + chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max; | |
| 513 | + get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET); | |
| 521 | 514 | |
| 522 | − if (status & NV_PFIFO_INTR_DMA_PUSHER) { | |
| 523 | − nv04_fifo_dma_pusher(device, priv, chid); | |
| 524 | − status &= ~NV_PFIFO_INTR_DMA_PUSHER; | |
| 525 | − } | |
| 515 | + if (stat & NV_PFIFO_INTR_CACHE_ERROR) { | |
| 516 | + nv04_fifo_cache_error(device, priv, chid, get); | |
| 517 | + stat &= ~NV_PFIFO_INTR_CACHE_ERROR; | |
| 518 | + } | |
| 526 | 519 | |
| 527 | − if (status & NV_PFIFO_INTR_SEMAPHORE) { | |
| 528 | − uint32_t sem; | |
| 520 | + if (stat & NV_PFIFO_INTR_DMA_PUSHER) { | |
| 521 | + nv04_fifo_dma_pusher(device, priv, chid); | |
| 522 | + stat &= ~NV_PFIFO_INTR_DMA_PUSHER; | |
| 523 | + } | |
| 529 | 524 | |
| 530 | − status &= ~NV_PFIFO_INTR_SEMAPHORE; | |
| 531 | − nv_wr32(priv, NV03_PFIFO_INTR_0, | |
| 532 | − NV_PFIFO_INTR_SEMAPHORE); | |
| 525 | + if (stat & NV_PFIFO_INTR_SEMAPHORE) { | |
| 526 | + stat &= ~NV_PFIFO_INTR_SEMAPHORE; | |
| 527 | + nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_SEMAPHORE); | |
| 533 | 528 | |
| 534 | − sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE); | |
| 535 | − nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); | |
| 529 | + sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE); | |
| 530 | + nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); | |
| 536 | 531 | |
| 537 | − nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4); | |
| 538 | − nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); | |
| 539 | − } | |
| 532 | + nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4); | |
| 533 | + nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); | |
| 534 | + } | |
| 540 | 535 | |
| 541 | − if (device->card_type == NV_50) { | |
| 542 | − if (status & 0x00000010) { | |
| 543 | − status &= ~0x00000010; | |
| 544 | − nv_wr32(priv, 0x002100, 0x00000010); | |
| 545 | − } | |
| 546 | − | |
| 547 | − if (status & 0x40000000) { | |
| 548 | − nv_wr32(priv, 0x002100, 0x40000000); | |
| 549 | − nvkm_fifo_uevent(&priv->base); | |
| 550 | − status &= ~0x40000000; | |
| 551 | − } | |
| 536 | + if (device->card_type == NV_50) { | |
| 537 | + if (stat & 0x00000010) { | |
| 538 | + stat &= ~0x00000010; | |
| 539 | + nv_wr32(priv, 0x002100, 0x00000010); | |
| 552 | 540 | } |
| 553 | 541 | |
| 554 | − if (status) { | |
| 555 | − nv_warn(priv, "unknown intr 0x%08x, ch %d\n", | |
| 556 | − status, chid); | |
| 557 | − nv_wr32(priv, NV03_PFIFO_INTR_0, status); | |
| 558 | − status = 0; | |
| 542 | + if (stat & 0x40000000) { | |
| 543 | + nv_wr32(priv, 0x002100, 0x40000000); | |
| 544 | + nvkm_fifo_uevent(&priv->base); | |
| 545 | + stat &= ~0x40000000; | |
| 559 | 546 | } |
| 560 | − | |
| 561 | − nv_wr32(priv, NV03_PFIFO_CACHES, reassign); | |
| 562 | 547 | } |
| 563 | 548 | |
| 564 | − if (status) { | |
| 565 | − nv_error(priv, "still angry after %d spins, halt\n", cnt); | |
| 566 | − nv_wr32(priv, 0x002140, 0); | |
| 567 | − nv_wr32(priv, 0x000140, 0); | |
| 549 | + if (stat) { | |
| 550 | + nv_warn(priv, "unknown intr 0x%08x\n", stat); | |
| 551 | + nv_mask(priv, NV03_PFIFO_INTR_EN_0, stat, 0x00000000); | |
| 552 | + nv_wr32(priv, NV03_PFIFO_INTR_0, stat); | |
| 568 | 553 | } |
| 569 | 554 | |
| 570 | − nv_wr32(priv, 0x000100, 0x00000100); | |
| 555 | + nv_wr32(priv, NV03_PFIFO_CACHES, reassign); | |
| 571 | 556 | } |
| 572 | 557 | |
| 573 | 558 | static int |
| @@ -1032,9 +1032,9 @@ gf100_grctx_generate_bundle(struct gf100_grctx *info) · 1031 unmodified lines | ||
| 1032 | 1032 | const int s = 8; |
| 1033 | 1033 | const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); |
| 1034 | 1034 | mmio_refn(info, 0x408004, 0x00000000, s, b); |
| 1035 | − mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 1035 | + mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s)); | |
| 1036 | 1036 | mmio_refn(info, 0x418808, 0x00000000, s, b); |
| 1037 | − mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 1037 | + mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s)); | |
| 1038 | 1038 | } |
| 1039 | 1039 | |
| 1040 | 1040 | void |
| @@ -851,9 +851,9 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info) · 850 unmodified lines | ||
| 851 | 851 | const int s = 8; |
| 852 | 852 | const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); |
| 853 | 853 | mmio_refn(info, 0x408004, 0x00000000, s, b); |
| 854 | − mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 854 | + mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s)); | |
| 855 | 855 | mmio_refn(info, 0x418808, 0x00000000, s, b); |
| 856 | − mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 856 | + mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s)); | |
| 857 | 857 | mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit); |
| 858 | 858 | } |
| 859 | 859 | |
| @@ -871,9 +871,9 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info) · 870 unmodified lines | ||
| 871 | 871 | const int s = 8; |
| 872 | 872 | const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); |
| 873 | 873 | mmio_refn(info, 0x408004, 0x00000000, s, b); |
| 874 | − mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 874 | + mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s)); | |
| 875 | 875 | mmio_refn(info, 0x418e24, 0x00000000, s, b); |
| 876 | − mmio_refn(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s), 0, b); | |
| 876 | + mmio_wr32(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s)); | |
| 877 | 877 | mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit); |
| 878 | 878 | } |
| 879 | 879 | |
| @@ -74,7 +74,11 @@ dcb_i2c_parse(struct nvkm_bios *bios, u8 idx, struct dcb_i2c_entry *info) · 73 unmodified lines | ||
| 74 | 74 | u16 ent = dcb_i2c_entry(bios, idx, &ver, &len); |
| 75 | 75 | if (ent) { |
| 76 | 76 | if (ver >= 0x41) { |
| 77 | − if (!(nv_ro32(bios, ent) & 0x80000000)) | |
| 77 | + u32 ent_value = nv_ro32(bios, ent); | |
| 78 | + u8 i2c_port = (ent_value >> 27) & 0x1f; | |
| 79 | + u8 dpaux_port = (ent_value >> 22) & 0x1f; | |
| 80 | + /* value 0x1f means unused according to DCB 4.x spec */ | |
| 81 | + if (i2c_port == 0x1f && dpaux_port == 0x1f) | |
| 78 | 82 | info->type = DCB_I2C_UNUSED; |
| 79 | 83 | else |
| 80 | 84 | info->type = DCB_I2C_PMGR; |
| @@ -1030,37 +1030,59 @@ static inline bool radeon_test_signaled(struct radeon_fence *fence) · 1029 unmodified lines | ||
| 1030 | 1030 | return test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags); |
| 1031 | 1031 | } |
| 1032 | 1032 | |
| 1033 | +struct radeon_wait_cb { | |
| 1034 | + struct fence_cb base; | |
| 1035 | + struct task_struct *task; | |
| 1036 | +}; | |
| 1037 | + | |
| 1038 | +static void | |
| 1039 | +radeon_fence_wait_cb(struct fence *fence, struct fence_cb *cb) | |
| 1040 | +{ | |
| 1041 | + struct radeon_wait_cb *wait = | |
| 1042 | + container_of(cb, struct radeon_wait_cb, base); | |
| 1043 | + | |
| 1044 | + wake_up_process(wait->task); | |
| 1045 | +} | |
| 1046 | + | |
| 1033 | 1047 | static signed long radeon_fence_default_wait(struct fence *f, bool intr, |
| 1034 | 1048 | signed long t) |
| 1035 | 1049 | { |
| 1036 | 1050 | struct radeon_fence *fence = to_radeon_fence(f); |
| 1037 | 1051 | struct radeon_device *rdev = fence->rdev; |
| 1038 | − bool signaled; | |
| 1052 | + struct radeon_wait_cb cb; | |
| 1039 | 1053 | |
| 1040 | − fence_enable_sw_signaling(&fence->base); | |
| 1054 | + cb.task = current; | |
| 1041 | 1055 | |
| 1042 | − /* | |
| 1043 | − * This function has to return -EDEADLK, but cannot hold | |
| 1044 | − * exclusive_lock during the wait because some callers | |
| 1045 | − * may already hold it. This means checking needs_reset without | |
| 1046 | − * lock, and not fiddling with any gpu internals. | |
| 1047 | − * | |
| 1048 | − * The callback installed with fence_enable_sw_signaling will | |
| 1049 | − * run before our wait_event_*timeout call, so we will see | |
| 1050 | − * both the signaled fence and the changes to needs_reset. | |
| 1051 | − */ | |
| 1056 | + if (fence_add_callback(f, &cb.base, radeon_fence_wait_cb)) | |
| 1057 | + return t; | |
| 1058 | + | |
| 1059 | + while (t > 0) { | |
| 1060 | + if (intr) | |
| 1061 | + set_current_state(TASK_INTERRUPTIBLE); | |
| 1062 | + else | |
| 1063 | + set_current_state(TASK_UNINTERRUPTIBLE); | |
| 1064 | + | |
| 1065 | + /* | |
| 1066 | + * radeon_test_signaled must be called after | |
| 1067 | + * set_current_state to prevent a race with wake_up_process | |
| 1068 | + */ | |
| 1069 | + if (radeon_test_signaled(fence)) | |
| 1070 | + break; | |
| 1071 | + | |
| 1072 | + if (rdev->needs_reset) { | |
| 1073 | + t = -EDEADLK; | |
| 1074 | + break; | |
| 1075 | + } | |
| 1076 | + | |
| 1077 | + t = schedule_timeout(t); | |
| 1078 | + | |
| 1079 | + if (t > 0 && intr && signal_pending(current)) | |
| 1080 | + t = -ERESTARTSYS; | |
| 1081 | + } | |
| 1082 | + | |
| 1083 | + __set_current_state(TASK_RUNNING); | |
| 1084 | + fence_remove_callback(f, &cb.base); | |
| 1052 | 1085 | |
| 1053 | − if (intr) | |
| 1054 | − t = wait_event_interruptible_timeout(rdev->fence_queue, | |
| 1055 | − ((signaled = radeon_test_signaled(fence)) || | |
| 1056 | − rdev->needs_reset), t); | |
| 1057 | − else | |
| 1058 | − t = wait_event_timeout(rdev->fence_queue, | |
| 1059 | − ((signaled = radeon_test_signaled(fence)) || | |
| 1060 | − rdev->needs_reset), t); | |
| 1061 | − | |
| 1062 | − if (t > 0 && !signaled) | |
| 1063 | − return -EDEADLK; | |
| 1064 | 1086 | return t; |
| 1065 | 1087 | } |
| 1066 | 1088 | |
| @@ -153,7 +153,7 @@ void radeon_kfd_device_init(struct radeon_device *rdev) · 152 unmodified lines | ||
| 153 | 153 | .compute_vmid_bitmap = 0xFF00, |
| 154 | 154 | |
| 155 | 155 | .first_compute_pipe = 1, |
| 156 | − .compute_pipe_count = 8 - 1, | |
| 156 | + .compute_pipe_count = 4 - 1, | |
| 157 | 157 | }; |
| 158 | 158 | |
| 159 | 159 | radeon_doorbell_get_kfd_info(rdev, |
| @@ -173,17 +173,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) · 172 unmodified lines | ||
| 173 | 173 | else |
| 174 | 174 | rbo->placements[i].lpfn = 0; |
| 175 | 175 | } |
| 176 | − | |
| 177 | − /* | |
| 178 | − * Use two-ended allocation depending on the buffer size to | |
| 179 | − * improve fragmentation quality. | |
| 180 | − * 512kb was measured as the most optimal number. | |
| 181 | − */ | |
| 182 | − if (rbo->tbo.mem.size > 512 * 1024) { | |
| 183 | − for (i = 0; i < c; i++) { | |
| 184 | − rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN; | |
| 185 | − } | |
| 186 | − } | |
| 187 | 176 | } |
| 188 | 177 | |
| 189 | 178 | int radeon_bo_create(struct radeon_device *rdev, |
| @@ -7130,8 +7130,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) · 7129 unmodified lines | ||
| 7130 | 7130 | WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); |
| 7131 | 7131 | |
| 7132 | 7132 | if (!vclk || !dclk) { |
| 7133 | − /* keep the Bypass mode, put PLL to sleep */ | |
| 7134 | − WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); | |
| 7133 | + /* keep the Bypass mode */ | |
| 7135 | 7134 | return 0; |
| 7136 | 7135 | } |
| 7137 | 7136 | |
| @@ -7147,8 +7146,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) · 9 unmodified lines | ||
| 7147 | 7146 | /* set VCO_MODE to 1 */ |
| 7148 | 7147 | WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK); |
| 7149 | 7148 | |
| 7150 | − /* toggle UPLL_SLEEP to 1 then back to 0 */ | |
| 7151 | − WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); | |
| 7149 | + /* disable sleep mode */ | |
| 7152 | 7150 | WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK); |
| 7153 | 7151 | |
| 7154 | 7152 | /* deassert UPLL_RESET */ |
| @@ -725,32 +725,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 724 unmodified lines | ||
| 725 | 725 | goto out_err1; |
| 726 | 726 | } |
| 727 | 727 | |
| 728 | − ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, | |
| 729 | − (dev_priv->vram_size >> PAGE_SHIFT)); | |
| 730 | − if (unlikely(ret != 0)) { | |
| 731 | − DRM_ERROR("Failed initializing memory manager for VRAM.\n"); | |
| 732 | − goto out_err2; | |
| 733 | − } | |
| 734 | − | |
| 735 | − dev_priv->has_gmr = true; | |
| 736 | − if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) || | |
| 737 | − refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, | |
| 738 | − VMW_PL_GMR) != 0) { | |
| 739 | − DRM_INFO("No GMR memory available. " | |
| 740 | − "Graphics memory resources are very limited.\n"); | |
| 741 | − dev_priv->has_gmr = false; | |
| 742 | − } | |
| 743 | − | |
| 744 | − if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { | |
| 745 | − dev_priv->has_mob = true; | |
| 746 | − if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB, | |
| 747 | − VMW_PL_MOB) != 0) { | |
| 748 | − DRM_INFO("No MOB memory available. " | |
| 749 | − "3D will be disabled.\n"); | |
| 750 | − dev_priv->has_mob = false; | |
| 751 | − } | |
| 752 | − } | |
| 753 | − | |
| 754 | 728 | dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start, |
| 755 | 729 | dev_priv->mmio_size); |
| 756 | 730 | |
| @@ -813,6 +787,33 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 56 unmodified lines | ||
| 813 | 787 | goto out_no_fman; |
| 814 | 788 | } |
| 815 | 789 | |
| 790 | + | |
| 791 | + ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, | |
| 792 | + (dev_priv->vram_size >> PAGE_SHIFT)); | |
| 793 | + if (unlikely(ret != 0)) { | |
| 794 | + DRM_ERROR("Failed initializing memory manager for VRAM.\n"); | |
| 795 | + goto out_no_vram; | |
| 796 | + } | |
| 797 | + | |
| 798 | + dev_priv->has_gmr = true; | |
| 799 | + if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) || | |
| 800 | + refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, | |
| 801 | + VMW_PL_GMR) != 0) { | |
| 802 | + DRM_INFO("No GMR memory available. " | |
| 803 | + "Graphics memory resources are very limited.\n"); | |
| 804 | + dev_priv->has_gmr = false; | |
| 805 | + } | |
| 806 | + | |
| 807 | + if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { | |
| 808 | + dev_priv->has_mob = true; | |
| 809 | + if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB, | |
| 810 | + VMW_PL_MOB) != 0) { | |
| 811 | + DRM_INFO("No MOB memory available. " | |
| 812 | + "3D will be disabled.\n"); | |
| 813 | + dev_priv->has_mob = false; | |
| 814 | + } | |
| 815 | + } | |
| 816 | + | |
| 816 | 817 | vmw_kms_save_vga(dev_priv); |
| 817 | 818 | |
| 818 | 819 | /* Start kms and overlay systems, needs fifo. */ |
| @@ -838,6 +839,12 @@ out_no_fifo: · 19 unmodified lines | ||
| 838 | 839 | vmw_kms_close(dev_priv); |
| 839 | 840 | out_no_kms: |
| 840 | 841 | vmw_kms_restore_vga(dev_priv); |
| 842 | + if (dev_priv->has_mob) | |
| 843 | + (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); | |
| 844 | + if (dev_priv->has_gmr) | |
| 845 | + (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | |
| 846 | + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | |
| 847 | +out_no_vram: | |
| 841 | 848 | vmw_fence_manager_takedown(dev_priv->fman); |
| 842 | 849 | out_no_fman: |
| 843 | 850 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
| @@ -853,12 +860,6 @@ out_err4: · 9 unmodified lines | ||
| 853 | 860 | iounmap(dev_priv->mmio_virt); |
| 854 | 861 | out_err3: |
| 855 | 862 | arch_phys_wc_del(dev_priv->mmio_mtrr); |
| 856 | − if (dev_priv->has_mob) | |
| 857 | − (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); | |
| 858 | − if (dev_priv->has_gmr) | |
| 859 | − (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | |
| 860 | − (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | |
| 861 | −out_err2: | |
| 862 | 863 | (void)ttm_bo_device_release(&dev_priv->bdev); |
| 863 | 864 | out_err1: |
| 864 | 865 | vmw_ttm_global_release(dev_priv); |
| @@ -887,6 +888,13 @@ static int vmw_driver_unload(struct drm_device *dev) · 22 unmodified lines | ||
| 887 | 888 | } |
| 888 | 889 | vmw_kms_close(dev_priv); |
| 889 | 890 | vmw_overlay_close(dev_priv); |
| 891 | + | |
| 892 | + if (dev_priv->has_mob) | |
| 893 | + (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); | |
| 894 | + if (dev_priv->has_gmr) | |
| 895 | + (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | |
| 896 | + (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | |
| 897 | + | |
| 890 | 898 | vmw_fence_manager_takedown(dev_priv->fman); |
| 891 | 899 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
| 892 | 900 | drm_irq_uninstall(dev_priv->dev); |
| @@ -898,11 +906,6 @@ static int vmw_driver_unload(struct drm_device *dev) · 5 unmodified lines | ||
| 898 | 906 | ttm_object_device_release(&dev_priv->tdev); |
| 899 | 907 | iounmap(dev_priv->mmio_virt); |
| 900 | 908 | arch_phys_wc_del(dev_priv->mmio_mtrr); |
| 901 | − if (dev_priv->has_mob) | |
| 902 | − (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); | |
| 903 | − if (dev_priv->has_gmr) | |
| 904 | − (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | |
| 905 | − (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | |
| 906 | 909 | (void)ttm_bo_device_release(&dev_priv->bdev); |
| 907 | 910 | vmw_ttm_global_release(dev_priv); |
| 908 | 911 | |
| @@ -1235,6 +1238,7 @@ static void vmw_remove(struct pci_dev *pdev) · 326 unmodified lines | ||
| 1235 | 1238 | { |
| 1236 | 1239 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1237 | 1240 | |
| 1241 | + pci_disable_device(pdev); | |
| 1238 | 1242 | drm_put_dev(dev); |
| 1239 | 1243 | } |
| 1240 | 1244 | |
| @@ -890,7 +890,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, · 889 unmodified lines | ||
| 890 | 890 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
| 891 | 891 | if (unlikely(ret != 0)) { |
| 892 | 892 | DRM_ERROR("Could not find or use MOB buffer.\n"); |
| 893 | − return -EINVAL; | |
| 893 | + ret = -EINVAL; | |
| 894 | + goto out_no_reloc; | |
| 894 | 895 | } |
| 895 | 896 | bo = &vmw_bo->base; |
| 896 | 897 | |
| @@ -914,7 +915,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, · 17 unmodified lines | ||
| 914 | 915 | |
| 915 | 916 | out_no_reloc: |
| 916 | 917 | vmw_dmabuf_unreference(&vmw_bo); |
| 917 | − vmw_bo_p = NULL; | |
| 918 | + *vmw_bo_p = NULL; | |
| 918 | 919 | return ret; |
| 919 | 920 | } |
| 920 | 921 | |
| @@ -951,7 +952,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, · 30 unmodified lines | ||
| 951 | 952 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
| 952 | 953 | if (unlikely(ret != 0)) { |
| 953 | 954 | DRM_ERROR("Could not find or use GMR region.\n"); |
| 954 | − return -EINVAL; | |
| 955 | + ret = -EINVAL; | |
| 956 | + goto out_no_reloc; | |
| 955 | 957 | } |
| 956 | 958 | bo = &vmw_bo->base; |
| 957 | 959 | |
| @@ -974,7 +976,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, · 16 unmodified lines | ||
| 974 | 976 | |
| 975 | 977 | out_no_reloc: |
| 976 | 978 | vmw_dmabuf_unreference(&vmw_bo); |
| 977 | − vmw_bo_p = NULL; | |
| 979 | + *vmw_bo_p = NULL; | |
| 978 | 980 | return ret; |
| 979 | 981 | } |
| 980 | 982 | |
| @@ -2780,13 +2782,11 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, · 1799 unmodified lines | ||
| 2780 | 2782 | NULL, arg->command_size, arg->throttle_us, |
| 2781 | 2783 | (void __user *)(unsigned long)arg->fence_rep, |
| 2782 | 2784 | NULL); |
| 2783 | − | |
| 2785 | + ttm_read_unlock(&dev_priv->reservation_sem); | |
| 2784 | 2786 | if (unlikely(ret != 0)) |
| 2785 | − goto out_unlock; | |
| 2787 | + return ret; | |
| 2786 | 2788 | |
| 2787 | 2789 | vmw_kms_cursor_post_execbuf(dev_priv); |
| 2788 | 2790 | |
| 2789 | −out_unlock: | |
| 2790 | − ttm_read_unlock(&dev_priv->reservation_sem); | |
| 2791 | − return ret; | |
| 2791 | + return 0; | |
| 2792 | 2792 | } |
| @@ -2033,23 +2033,17 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 2032 unmodified lines | ||
| 2033 | 2033 | int i; |
| 2034 | 2034 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 2035 | 2035 | |
| 2036 | − ret = ttm_read_lock(&dev_priv->reservation_sem, true); | |
| 2037 | − if (unlikely(ret != 0)) | |
| 2038 | − return ret; | |
| 2039 | − | |
| 2040 | 2036 | if (!arg->num_outputs) { |
| 2041 | 2037 | struct drm_vmw_rect def_rect = {0, 0, 800, 600}; |
| 2042 | 2038 | vmw_du_update_layout(dev_priv, 1, &def_rect); |
| 2043 | − goto out_unlock; | |
| 2039 | + return 0; | |
| 2044 | 2040 | } |
| 2045 | 2041 | |
| 2046 | 2042 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| 2047 | 2043 | rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect), |
| 2048 | 2044 | GFP_KERNEL); |
| 2049 | − if (unlikely(!rects)) { | |
| 2050 | − ret = -ENOMEM; | |
| 2051 | − goto out_unlock; | |
| 2052 | − } | |
| 2045 | + if (unlikely(!rects)) | |
| 2046 | + return -ENOMEM; | |
| 2053 | 2047 | |
| 2054 | 2048 | user_rects = (void __user *)(unsigned long)arg->rects; |
| 2055 | 2049 | ret = copy_from_user(rects, user_rects, rects_size); |
| @@ -2074,7 +2068,5 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 18 unmodified lines | ||
| 2074 | 2068 | |
| 2075 | 2069 | out_free: |
| 2076 | 2070 | kfree(rects); |
| 2077 | −out_unlock: | |
| 2078 | − ttm_read_unlock(&dev_priv->reservation_sem); | |
| 2079 | 2071 | return ret; |
| 2080 | 2072 | } |
| @@ -1959,6 +1959,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 1958 unmodified lines | ||
| 1959 | 1959 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, |
| 1960 | 1960 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, |
| 1961 | 1961 | { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, |
| 1962 | + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) }, | |
| 1962 | 1963 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
| 1963 | 1964 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
| 1964 | 1965 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
| @@ -586,6 +586,7 @@ · 585 unmodified lines | ||
| 586 | 586 | #define USB_VENDOR_ID_LOGITECH 0x046d |
| 587 | 587 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
| 588 | 588 | #define USB_DEVICE_ID_LOGITECH_T651 0xb00c |
| 589 | +#define USB_DEVICE_ID_LOGITECH_C077 0xc007 | |
| 589 | 590 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
| 590 | 591 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
| 591 | 592 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f |
| @@ -898,6 +899,7 @@ · 306 unmodified lines | ||
| 898 | 899 | #define USB_VENDOR_ID_TIVO 0x150a |
| 899 | 900 | #define USB_DEVICE_ID_TIVO_SLIDE_BT 0x1200 |
| 900 | 901 | #define USB_DEVICE_ID_TIVO_SLIDE 0x1201 |
| 902 | +#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203 | |
| 901 | 903 | |
| 902 | 904 | #define USB_VENDOR_ID_TOPSEED 0x0766 |
| 903 | 905 | #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 |
| @@ -64,6 +64,7 @@ static const struct hid_device_id tivo_devices[] = { · 63 unmodified lines | ||
| 64 | 64 | /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ |
| 65 | 65 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, |
| 66 | 66 | { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, |
| 67 | + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) }, | |
| 67 | 68 | { } |
| 68 | 69 | }; |
| 69 | 70 | MODULE_DEVICE_TABLE(hid, tivo_devices); |
| @@ -78,6 +78,7 @@ static const struct hid_blacklist { · 77 unmodified lines | ||
| 78 | 78 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
| 79 | 79 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, |
| 80 | 80 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
| 81 | + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, | |
| 81 | 82 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
| 82 | 83 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, |
| 83 | 84 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS }, |
| @@ -551,9 +551,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) · 550 unmodified lines | ||
| 551 | 551 | (features->type == CINTIQ && !(data[1] & 0x40))) |
| 552 | 552 | return 1; |
| 553 | 553 | |
| 554 | − if (features->quirks & WACOM_QUIRK_MULTI_INPUT) | |
| 554 | + if (wacom->shared) { | |
| 555 | 555 | wacom->shared->stylus_in_proximity = true; |
| 556 | 556 | |
| 557 | + if (wacom->shared->touch_down) | |
| 558 | + return 1; | |
| 559 | + } | |
| 560 | + | |
| 557 | 561 | /* in Range while exiting */ |
| 558 | 562 | if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) { |
| 559 | 563 | input_report_key(input, BTN_TOUCH, 0); |
| @@ -1043,27 +1047,28 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) · 483 unmodified lines | ||
| 1043 | 1047 | struct input_dev *input = wacom->input; |
| 1044 | 1048 | unsigned char *data = wacom->data; |
| 1045 | 1049 | int i; |
| 1046 | − int current_num_contacts = 0; | |
| 1050 | + int current_num_contacts = data[61]; | |
| 1047 | 1051 | int contacts_to_send = 0; |
| 1048 | 1052 | int num_contacts_left = 4; /* maximum contacts per packet */ |
| 1049 | 1053 | int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; |
| 1050 | 1054 | int y_offset = 2; |
| 1055 | + static int contact_with_no_pen_down_count = 0; | |
| 1051 | 1056 | |
| 1052 | 1057 | if (wacom->features.type == WACOM_27QHDT) { |
| 1053 | 1058 | current_num_contacts = data[63]; |
| 1054 | 1059 | num_contacts_left = 10; |
| 1055 | 1060 | byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET; |
| 1056 | 1061 | y_offset = 0; |
| 1057 | − } else { | |
| 1058 | − current_num_contacts = data[61]; | |
| 1059 | 1062 | } |
| 1060 | 1063 | |
| 1061 | 1064 | /* |
| 1062 | 1065 | * First packet resets the counter since only the first |
| 1063 | 1066 | * packet in series will have non-zero current_num_contacts. |
| 1064 | 1067 | */ |
| 1065 | − if (current_num_contacts) | |
| 1068 | + if (current_num_contacts) { | |
| 1066 | 1069 | wacom->num_contacts_left = current_num_contacts; |
| 1070 | + contact_with_no_pen_down_count = 0; | |
| 1071 | + } | |
| 1067 | 1072 | |
| 1068 | 1073 | contacts_to_send = min(num_contacts_left, wacom->num_contacts_left); |
| 1069 | 1074 | |
| @@ -1096,15 +1101,16 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) · 26 unmodified lines | ||
| 1096 | 1101 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); |
| 1097 | 1102 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); |
| 1098 | 1103 | } |
| 1104 | + contact_with_no_pen_down_count++; | |
| 1099 | 1105 | } |
| 1100 | 1106 | } |
| 1101 | 1107 | input_mt_report_pointer_emulation(input, true); |
| 1102 | 1108 | |
| 1103 | 1109 | wacom->num_contacts_left -= contacts_to_send; |
| 1104 | − if (wacom->num_contacts_left <= 0) | |
| 1110 | + if (wacom->num_contacts_left <= 0) { | |
| 1105 | 1111 | wacom->num_contacts_left = 0; |
| 1106 | − | |
| 1107 | − wacom->shared->touch_down = (wacom->num_contacts_left > 0); | |
| 1112 | + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | |
| 1113 | + } | |
| 1108 | 1114 | return 1; |
| 1109 | 1115 | } |
| 1110 | 1116 | |
| @@ -1116,6 +1122,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) · 5 unmodified lines | ||
| 1116 | 1122 | int current_num_contacts = data[2]; |
| 1117 | 1123 | int contacts_to_send = 0; |
| 1118 | 1124 | int x_offset = 0; |
| 1125 | + static int contact_with_no_pen_down_count = 0; | |
| 1119 | 1126 | |
| 1120 | 1127 | /* MTTPC does not support Height and Width */ |
| 1121 | 1128 | if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B) |
| @@ -1125,8 +1132,10 @@ static int wacom_mt_touch(struct wacom_wac *wacom) · 3 unmodified lines | ||
| 1125 | 1132 | * First packet resets the counter since only the first |
| 1126 | 1133 | * packet in series will have non-zero current_num_contacts. |
| 1127 | 1134 | */ |
| 1128 | − if (current_num_contacts) | |
| 1135 | + if (current_num_contacts) { | |
| 1129 | 1136 | wacom->num_contacts_left = current_num_contacts; |
| 1137 | + contact_with_no_pen_down_count = 0; | |
| 1138 | + } | |
| 1130 | 1139 | |
| 1131 | 1140 | /* There are at most 5 contacts per packet */ |
| 1132 | 1141 | contacts_to_send = min(5, wacom->num_contacts_left); |
| @@ -1147,15 +1156,16 @@ static int wacom_mt_touch(struct wacom_wac *wacom) · 14 unmodified lines | ||
| 1147 | 1156 | int y = get_unaligned_le16(&data[offset + x_offset + 9]); |
| 1148 | 1157 | input_report_abs(input, ABS_MT_POSITION_X, x); |
| 1149 | 1158 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
| 1159 | + contact_with_no_pen_down_count++; | |
| 1150 | 1160 | } |
| 1151 | 1161 | } |
| 1152 | 1162 | input_mt_report_pointer_emulation(input, true); |
| 1153 | 1163 | |
| 1154 | 1164 | wacom->num_contacts_left -= contacts_to_send; |
| 1155 | − if (wacom->num_contacts_left < 0) | |
| 1165 | + if (wacom->num_contacts_left <= 0) { | |
| 1156 | 1166 | wacom->num_contacts_left = 0; |
| 1157 | − | |
| 1158 | − wacom->shared->touch_down = (wacom->num_contacts_left > 0); | |
| 1167 | + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | |
| 1168 | + } | |
| 1159 | 1169 | return 1; |
| 1160 | 1170 | } |
| 1161 | 1171 | |
| @@ -1193,29 +1203,25 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) · 31 unmodified lines | ||
| 1193 | 1203 | { |
| 1194 | 1204 | unsigned char *data = wacom->data; |
| 1195 | 1205 | struct input_dev *input = wacom->input; |
| 1196 | − bool prox; | |
| 1206 | + bool prox = !wacom->shared->stylus_in_proximity; | |
| 1197 | 1207 | int x = 0, y = 0; |
| 1198 | 1208 | |
| 1199 | 1209 | if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) |
| 1200 | 1210 | return 0; |
| 1201 | 1211 | |
| 1202 | − if (!wacom->shared->stylus_in_proximity) { | |
| 1203 | − if (len == WACOM_PKGLEN_TPC1FG) { | |
| 1204 | − prox = data[0] & 0x01; | |
| 1205 | − x = get_unaligned_le16(&data[1]); | |
| 1206 | − y = get_unaligned_le16(&data[3]); | |
| 1207 | − } else if (len == WACOM_PKGLEN_TPC1FG_B) { | |
| 1208 | − prox = data[2] & 0x01; | |
| 1209 | − x = get_unaligned_le16(&data[3]); | |
| 1210 | − y = get_unaligned_le16(&data[5]); | |
| 1211 | − } else { | |
| 1212 | − prox = data[1] & 0x01; | |
| 1213 | − x = le16_to_cpup((__le16 *)&data[2]); | |
| 1214 | − y = le16_to_cpup((__le16 *)&data[4]); | |
| 1215 | − } | |
| 1216 | − } else | |
| 1217 | − /* force touch out when pen is in prox */ | |
| 1218 | − prox = 0; | |
| 1212 | + if (len == WACOM_PKGLEN_TPC1FG) { | |
| 1213 | + prox = prox && (data[0] & 0x01); | |
| 1214 | + x = get_unaligned_le16(&data[1]); | |
| 1215 | + y = get_unaligned_le16(&data[3]); | |
| 1216 | + } else if (len == WACOM_PKGLEN_TPC1FG_B) { | |
| 1217 | + prox = prox && (data[2] & 0x01); | |
| 1218 | + x = get_unaligned_le16(&data[3]); | |
| 1219 | + y = get_unaligned_le16(&data[5]); | |
| 1220 | + } else { | |
| 1221 | + prox = prox && (data[1] & 0x01); | |
| 1222 | + x = le16_to_cpup((__le16 *)&data[2]); | |
| 1223 | + y = le16_to_cpup((__le16 *)&data[4]); | |
| 1224 | + } | |
| 1219 | 1225 | |
| 1220 | 1226 | if (prox) { |
| 1221 | 1227 | input_report_abs(input, ABS_X, x); |
| @@ -1613,6 +1619,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) · 391 unmodified lines | ||
| 1613 | 1619 | struct input_dev *pad_input = wacom->pad_input; |
| 1614 | 1620 | unsigned char *data = wacom->data; |
| 1615 | 1621 | int i; |
| 1622 | + int contact_with_no_pen_down_count = 0; | |
| 1616 | 1623 | |
| 1617 | 1624 | if (data[0] != 0x02) |
| 1618 | 1625 | return 0; |
| @@ -1640,6 +1647,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) · 21 unmodified lines | ||
| 1640 | 1647 | } |
| 1641 | 1648 | input_report_abs(input, ABS_MT_POSITION_X, x); |
| 1642 | 1649 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
| 1650 | + contact_with_no_pen_down_count++; | |
| 1643 | 1651 | } |
| 1644 | 1652 | } |
| 1645 | 1653 | |
| @@ -1649,11 +1657,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) · 3 unmodified lines | ||
| 1649 | 1657 | input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0); |
| 1650 | 1658 | input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0); |
| 1651 | 1659 | input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0); |
| 1660 | + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | |
| 1652 | 1661 | |
| 1653 | 1662 | return 1; |
| 1654 | 1663 | } |
| 1655 | 1664 | |
| 1656 | −static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | |
| 1665 | +static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count) | |
| 1657 | 1666 | { |
| 1658 | 1667 | struct wacom_features *features = &wacom->features; |
| 1659 | 1668 | struct input_dev *input = wacom->input; |
| @@ -1661,7 +1670,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) · 1 unmodified line | ||
| 1661 | 1670 | int slot = input_mt_get_slot_by_key(input, data[0]); |
| 1662 | 1671 | |
| 1663 | 1672 | if (slot < 0) |
| 1664 | − return; | |
| 1673 | + return 0; | |
| 1665 | 1674 | |
| 1666 | 1675 | touch = touch && !wacom->shared->stylus_in_proximity; |
| 1667 | 1676 | |
| @@ -1693,7 +1702,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) · 25 unmodified lines | ||
| 1693 | 1702 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
| 1694 | 1703 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, width); |
| 1695 | 1704 | input_report_abs(input, ABS_MT_TOUCH_MINOR, height); |
| 1705 | + last_touch_count++; | |
| 1696 | 1706 | } |
| 1707 | + return last_touch_count; | |
| 1697 | 1708 | } |
| 1698 | 1709 | |
| 1699 | 1710 | static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) |
| @@ -1718,6 +1729,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) · 18 unmodified lines | ||
| 1718 | 1729 | unsigned char *data = wacom->data; |
| 1719 | 1730 | int count = data[1] & 0x07; |
| 1720 | 1731 | int i; |
| 1732 | + int contact_with_no_pen_down_count = 0; | |
| 1721 | 1733 | |
| 1722 | 1734 | if (data[0] != 0x02) |
| 1723 | 1735 | return 0; |
| @@ -1728,12 +1740,15 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) · 4 unmodified lines | ||
| 1728 | 1740 | int msg_id = data[offset]; |
| 1729 | 1741 | |
| 1730 | 1742 | if (msg_id >= 2 && msg_id <= 17) |
| 1731 | − wacom_bpt3_touch_msg(wacom, data + offset); | |
| 1743 | + contact_with_no_pen_down_count = | |
| 1744 | + wacom_bpt3_touch_msg(wacom, data + offset, | |
| 1745 | + contact_with_no_pen_down_count); | |
| 1732 | 1746 | else if (msg_id == 128) |
| 1733 | 1747 | wacom_bpt3_button_msg(wacom, data + offset); |
| 1734 | 1748 | |
| 1735 | 1749 | } |
| 1736 | 1750 | input_mt_report_pointer_emulation(input, true); |
| 1751 | + wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | |
| 1737 | 1752 | |
| 1738 | 1753 | return 1; |
| 1739 | 1754 | } |
| @@ -1759,6 +1774,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) · 19 unmodified lines | ||
| 1759 | 1774 | return 0; |
| 1760 | 1775 | } |
| 1761 | 1776 | |
| 1777 | + if (wacom->shared->touch_down) | |
| 1778 | + return 0; | |
| 1779 | + | |
| 1762 | 1780 | prox = (data[1] & 0x20) == 0x20; |
| 1763 | 1781 | |
| 1764 | 1782 | /* |
| @@ -679,9 +679,6 @@ static int i2c_device_remove(struct device *dev) · 678 unmodified lines | ||
| 679 | 679 | status = driver->remove(client); |
| 680 | 680 | } |
| 681 | 681 | |
| 682 | − if (dev->of_node) | |
| 683 | − irq_dispose_mapping(client->irq); | |
| 684 | − | |
| 685 | 682 | dev_pm_domain_detach(&client->dev, true); |
| 686 | 683 | return status; |
| 687 | 684 | } |
| @@ -1793,11 +1793,11 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) · 1792 unmodified lines | ||
| 1793 | 1793 | tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN, |
| 1794 | 1794 | IDETAPE_DSC_RW_MAX); |
| 1795 | 1795 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " |
| 1796 | − "%lums tDSC%s\n", | |
| 1796 | + "%ums tDSC%s\n", | |
| 1797 | 1797 | drive->name, tape->name, *(u16 *)&tape->caps[14], |
| 1798 | 1798 | (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, |
| 1799 | 1799 | tape->buffer_size / 1024, |
| 1800 | − tape->best_dsc_rw_freq * 1000 / HZ, | |
| 1800 | + jiffies_to_msecs(tape->best_dsc_rw_freq), | |
| 1801 | 1801 | (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : ""); |
| 1802 | 1802 | |
| 1803 | 1803 | ide_proc_register_driver(drive, tape->driver); |
| @@ -64,6 +64,14 @@ enum { · 63 unmodified lines | ||
| 64 | 64 | #define GUID_TBL_BLK_NUM_ENTRIES 8 |
| 65 | 65 | #define GUID_TBL_BLK_SIZE (GUID_TBL_ENTRY_SIZE * GUID_TBL_BLK_NUM_ENTRIES) |
| 66 | 66 | |
| 67 | +/* Counters should be saturate once they reach their maximum value */ | |
| 68 | +#define ASSIGN_32BIT_COUNTER(counter, value) do {\ | |
| 69 | + if ((value) > U32_MAX) \ | |
| 70 | + counter = cpu_to_be32(U32_MAX); \ | |
| 71 | + else \ | |
| 72 | + counter = cpu_to_be32(value); \ | |
| 73 | +} while (0) | |
| 74 | + | |
| 67 | 75 | struct mlx4_mad_rcv_buf { |
| 68 | 76 | struct ib_grh grh; |
| 69 | 77 | u8 payload[256]; |
| @@ -806,10 +814,14 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, · 736 unmodified lines | ||
| 806 | 814 | static void edit_counter(struct mlx4_counter *cnt, |
| 807 | 815 | struct ib_pma_portcounters *pma_cnt) |
| 808 | 816 | { |
| 809 | − pma_cnt->port_xmit_data = cpu_to_be32((be64_to_cpu(cnt->tx_bytes)>>2)); | |
| 810 | − pma_cnt->port_rcv_data = cpu_to_be32((be64_to_cpu(cnt->rx_bytes)>>2)); | |
| 811 | − pma_cnt->port_xmit_packets = cpu_to_be32(be64_to_cpu(cnt->tx_frames)); | |
| 812 | − pma_cnt->port_rcv_packets = cpu_to_be32(be64_to_cpu(cnt->rx_frames)); | |
| 817 | + ASSIGN_32BIT_COUNTER(pma_cnt->port_xmit_data, | |
| 818 | + (be64_to_cpu(cnt->tx_bytes) >> 2)); | |
| 819 | + ASSIGN_32BIT_COUNTER(pma_cnt->port_rcv_data, | |
| 820 | + (be64_to_cpu(cnt->rx_bytes) >> 2)); | |
| 821 | + ASSIGN_32BIT_COUNTER(pma_cnt->port_xmit_packets, | |
| 822 | + be64_to_cpu(cnt->tx_frames)); | |
| 823 | + ASSIGN_32BIT_COUNTER(pma_cnt->port_rcv_packets, | |
| 824 | + be64_to_cpu(cnt->rx_frames)); | |
| 813 | 825 | } |
| 814 | 826 | |
| 815 | 827 | static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, |
| @@ -2697,8 +2697,12 @@ static void handle_bonded_port_state_event(struct work_struct *work) · 2696 unmodified lines | ||
| 2697 | 2697 | spin_lock_bh(&ibdev->iboe.lock); |
| 2698 | 2698 | for (i = 0; i < MLX4_MAX_PORTS; ++i) { |
| 2699 | 2699 | struct net_device *curr_netdev = ibdev->iboe.netdevs[i]; |
| 2700 | + enum ib_port_state curr_port_state; | |
| 2700 | 2701 | |
| 2701 | − enum ib_port_state curr_port_state = | |
| 2702 | + if (!curr_netdev) | |
| 2703 | + continue; | |
| 2704 | + | |
| 2705 | + curr_port_state = | |
| 2702 | 2706 | (netif_running(curr_netdev) && |
| 2703 | 2707 | netif_carrier_ok(curr_netdev)) ? |
| 2704 | 2708 | IB_PORT_ACTIVE : IB_PORT_DOWN; |
| @@ -411,9 +411,9 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) · 410 unmodified lines | ||
| 411 | 411 | |
| 412 | 412 | input_set_drvdata(input, keypad); |
| 413 | 413 | |
| 414 | − error = request_threaded_irq(irq, NULL, | |
| 415 | − tc3589x_keypad_irq, plat->irqtype, | |
| 416 | − "tc3589x-keypad", keypad); | |
| 414 | + error = request_threaded_irq(irq, NULL, tc3589x_keypad_irq, | |
| 415 | + plat->irqtype | IRQF_ONESHOT, | |
| 416 | + "tc3589x-keypad", keypad); | |
| 417 | 417 | if (error < 0) { |
| 418 | 418 | dev_err(&pdev->dev, |
| 419 | 419 | "Could not allocate irq %d,error %d\n", |
| @@ -187,6 +187,7 @@ static int mma8450_probe(struct i2c_client *c, · 186 unmodified lines | ||
| 187 | 187 | idev->private = m; |
| 188 | 188 | idev->input->name = MMA8450_DRV_NAME; |
| 189 | 189 | idev->input->id.bustype = BUS_I2C; |
| 190 | + idev->input->dev.parent = &c->dev; | |
| 190 | 191 | idev->poll = mma8450_poll; |
| 191 | 192 | idev->poll_interval = POLL_INTERVAL; |
| 192 | 193 | idev->poll_interval_max = POLL_INTERVAL_MAX; |
| @@ -2605,8 +2605,10 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) · 2604 unmodified lines | ||
| 2605 | 2605 | return -ENOMEM; |
| 2606 | 2606 | |
| 2607 | 2607 | error = alps_identify(psmouse, priv); |
| 2608 | − if (error) | |
| 2608 | + if (error) { | |
| 2609 | + kfree(priv); | |
| 2609 | 2610 | return error; |
| 2611 | + } | |
| 2610 | 2612 | |
| 2611 | 2613 | if (set_properties) { |
| 2612 | 2614 | psmouse->vendor = "ALPS"; |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/input/mt.h> |
| 21 | 21 | #include <linux/module.h> |
| 22 | 22 | #include <linux/slab.h> |
| 23 | −#include <linux/unaligned/access_ok.h> | |
| 23 | +#include <asm/unaligned.h> | |
| 24 | 24 | #include "cyapa.h" |
| 25 | 25 | |
| 26 | 26 | |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/mutex.h> |
| 18 | 18 | #include <linux/completion.h> |
| 19 | 19 | #include <linux/slab.h> |
| 20 | −#include <linux/unaligned/access_ok.h> | |
| 20 | +#include <asm/unaligned.h> | |
| 21 | 21 | #include <linux/crc-itu-t.h> |
| 22 | 22 | #include "cyapa.h" |
| 23 | 23 | |
| @@ -1926,7 +1926,7 @@ static int cyapa_gen5_read_idac_data(struct cyapa *cyapa, · 1902 unmodified lines | ||
| 1926 | 1926 | electrodes_tx = cyapa->electrodes_x; |
| 1927 | 1927 | max_element_cnt = ((cyapa->aligned_electrodes_rx + 7) & |
| 1928 | 1928 | ~7u) * electrodes_tx; |
| 1929 | − } else if (idac_data_type == GEN5_RETRIEVE_SELF_CAP_PWC_DATA) { | |
| 1929 | + } else { | |
| 1930 | 1930 | offset = 2; |
| 1931 | 1931 | max_element_cnt = cyapa->electrodes_x + |
| 1932 | 1932 | cyapa->electrodes_y; |
| @@ -67,9 +67,6 @@ static void focaltech_reset(struct psmouse *psmouse) · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | #define FOC_MAX_FINGERS 5 |
| 69 | 69 | |
| 70 | −#define FOC_MAX_X 2431 | |
| 71 | −#define FOC_MAX_Y 1663 | |
| 72 | − | |
| 73 | 70 | /* |
| 74 | 71 | * Current state of a single finger on the touchpad. |
| 75 | 72 | */ |
| @@ -129,9 +126,17 @@ static void focaltech_report_state(struct psmouse *psmouse) · 53 unmodified lines | ||
| 129 | 126 | input_mt_slot(dev, i); |
| 130 | 127 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); |
| 131 | 128 | if (active) { |
| 132 | − input_report_abs(dev, ABS_MT_POSITION_X, finger->x); | |
| 129 | + unsigned int clamped_x, clamped_y; | |
| 130 | + /* | |
| 131 | + * The touchpad might report invalid data, so we clamp | |
| 132 | + * the resulting values so that we do not confuse | |
| 133 | + * userspace. | |
| 134 | + */ | |
| 135 | + clamped_x = clamp(finger->x, 0U, priv->x_max); | |
| 136 | + clamped_y = clamp(finger->y, 0U, priv->y_max); | |
| 137 | + input_report_abs(dev, ABS_MT_POSITION_X, clamped_x); | |
| 133 | 138 | input_report_abs(dev, ABS_MT_POSITION_Y, |
| 134 | − FOC_MAX_Y - finger->y); | |
| 139 | + priv->y_max - clamped_y); | |
| 135 | 140 | } |
| 136 | 141 | } |
| 137 | 142 | input_mt_report_pointer_emulation(dev, true); |
| @@ -180,16 +185,6 @@ static void focaltech_process_abs_packet(struct psmouse *psmouse, · 42 unmodified lines | ||
| 180 | 185 | |
| 181 | 186 | state->pressed = (packet[0] >> 4) & 1; |
| 182 | 187 | |
| 183 | − /* | |
| 184 | − * packet[5] contains some kind of tool size in the most | |
| 185 | − * significant nibble. 0xff is a special value (latching) that | |
| 186 | − * signals a large contact area. | |
| 187 | − */ | |
| 188 | − if (packet[5] == 0xff) { | |
| 189 | − state->fingers[finger].valid = false; | |
| 190 | − return; | |
| 191 | − } | |
| 192 | − | |
| 193 | 188 | state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2]; |
| 194 | 189 | state->fingers[finger].y = (packet[3] << 8) | packet[4]; |
| 195 | 190 | state->fingers[finger].valid = true; |
| @@ -381,6 +376,23 @@ static int focaltech_read_size(struct psmouse *psmouse) · 185 unmodified lines | ||
| 381 | 376 | |
| 382 | 377 | return 0; |
| 383 | 378 | } |
| 379 | + | |
| 380 | +void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution) | |
| 381 | +{ | |
| 382 | + /* not supported yet */ | |
| 383 | +} | |
| 384 | + | |
| 385 | +static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate) | |
| 386 | +{ | |
| 387 | + /* not supported yet */ | |
| 388 | +} | |
| 389 | + | |
| 390 | +static void focaltech_set_scale(struct psmouse *psmouse, | |
| 391 | + enum psmouse_scale scale) | |
| 392 | +{ | |
| 393 | + /* not supported yet */ | |
| 394 | +} | |
| 395 | + | |
| 384 | 396 | int focaltech_init(struct psmouse *psmouse) |
| 385 | 397 | { |
| 386 | 398 | struct focaltech_data *priv; |
| @@ -415,6 +427,14 @@ int focaltech_init(struct psmouse *psmouse) · 28 unmodified lines | ||
| 415 | 427 | psmouse->cleanup = focaltech_reset; |
| 416 | 428 | /* resync is not supported yet */ |
| 417 | 429 | psmouse->resync_time = 0; |
| 430 | + /* | |
| 431 | + * rate/resolution/scale changes are not supported yet, and | |
| 432 | + * the generic implementations of these functions seem to | |
| 433 | + * confuse some touchpads | |
| 434 | + */ | |
| 435 | + psmouse->set_resolution = focaltech_set_resolution; | |
| 436 | + psmouse->set_rate = focaltech_set_rate; | |
| 437 | + psmouse->set_scale = focaltech_set_scale; | |
| 418 | 438 | |
| 419 | 439 | return 0; |
| 420 | 440 | |
| @@ -453,6 +453,17 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) · 452 unmodified lines | ||
| 453 | 453 | psmouse->rate = r; |
| 454 | 454 | } |
| 455 | 455 | |
| 456 | +/* | |
| 457 | + * Here we set the mouse scaling. | |
| 458 | + */ | |
| 459 | + | |
| 460 | +static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) | |
| 461 | +{ | |
| 462 | + ps2_command(&psmouse->ps2dev, NULL, | |
| 463 | + scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 : | |
| 464 | + PSMOUSE_CMD_SETSCALE11); | |
| 465 | +} | |
| 466 | + | |
| 456 | 467 | /* |
| 457 | 468 | * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. |
| 458 | 469 | */ |
| @@ -689,6 +700,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) · 230 unmodified lines | ||
| 689 | 700 | |
| 690 | 701 | psmouse->set_rate = psmouse_set_rate; |
| 691 | 702 | psmouse->set_resolution = psmouse_set_resolution; |
| 703 | + psmouse->set_scale = psmouse_set_scale; | |
| 692 | 704 | psmouse->poll = psmouse_poll; |
| 693 | 705 | psmouse->protocol_handler = psmouse_process_byte; |
| 694 | 706 | psmouse->pktsize = 3; |
| @@ -1160,7 +1172,7 @@ static void psmouse_initialize(struct psmouse *psmouse) · 465 unmodified lines | ||
| 1160 | 1172 | if (psmouse_max_proto != PSMOUSE_PS2) { |
| 1161 | 1173 | psmouse->set_rate(psmouse, psmouse->rate); |
| 1162 | 1174 | psmouse->set_resolution(psmouse, psmouse->resolution); |
| 1163 | − ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); | |
| 1175 | + psmouse->set_scale(psmouse, PSMOUSE_SCALE11); | |
| 1164 | 1176 | } |
| 1165 | 1177 | } |
| 1166 | 1178 | |
| @@ -36,6 +36,11 @@ typedef enum { · 35 unmodified lines | ||
| 36 | 36 | PSMOUSE_FULL_PACKET |
| 37 | 37 | } psmouse_ret_t; |
| 38 | 38 | |
| 39 | +enum psmouse_scale { | |
| 40 | + PSMOUSE_SCALE11, | |
| 41 | + PSMOUSE_SCALE21 | |
| 42 | +}; | |
| 43 | + | |
| 39 | 44 | struct psmouse { |
| 40 | 45 | void *private; |
| 41 | 46 | struct input_dev *dev; |
| @@ -67,6 +72,7 @@ struct psmouse { · 25 unmodified lines | ||
| 67 | 72 | psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); |
| 68 | 73 | void (*set_rate)(struct psmouse *psmouse, unsigned int rate); |
| 69 | 74 | void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); |
| 75 | + void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale); | |
| 70 | 76 | |
| 71 | 77 | int (*reconnect)(struct psmouse *psmouse); |
| 72 | 78 | void (*disconnect)(struct psmouse *psmouse); |
| @@ -67,9 +67,6 @@ · 66 unmodified lines | ||
| 67 | 67 | #define X_MAX_POSITIVE 8176 |
| 68 | 68 | #define Y_MAX_POSITIVE 8176 |
| 69 | 69 | |
| 70 | −/* maximum ABS_MT_POSITION displacement (in mm) */ | |
| 71 | −#define DMAX 10 | |
| 72 | − | |
| 73 | 70 | /***************************************************************************** |
| 74 | 71 | * Stuff we need even when we do not want native Synaptics support |
| 75 | 72 | ****************************************************************************/ |
| @@ -123,32 +120,41 @@ void synaptics_reset(struct psmouse *psmouse) · 47 unmodified lines | ||
| 123 | 120 | |
| 124 | 121 | static bool cr48_profile_sensor; |
| 125 | 122 | |
| 123 | +#define ANY_BOARD_ID 0 | |
| 126 | 124 | struct min_max_quirk { |
| 127 | 125 | const char * const *pnp_ids; |
| 126 | + struct { | |
| 127 | + unsigned long int min, max; | |
| 128 | + } board_id; | |
| 128 | 129 | int x_min, x_max, y_min, y_max; |
| 129 | 130 | }; |
| 130 | 131 | |
| 131 | 132 | static const struct min_max_quirk min_max_pnpid_table[] = { |
| 132 | 133 | { |
| 133 | 134 | (const char * const []){"LEN0033", NULL}, |
| 135 | + {ANY_BOARD_ID, ANY_BOARD_ID}, | |
| 134 | 136 | 1024, 5052, 2258, 4832 |
| 135 | 137 | }, |
| 136 | 138 | { |
| 137 | − (const char * const []){"LEN0035", "LEN0042", NULL}, | |
| 139 | + (const char * const []){"LEN0042", NULL}, | |
| 140 | + {ANY_BOARD_ID, ANY_BOARD_ID}, | |
| 138 | 141 | 1232, 5710, 1156, 4696 |
| 139 | 142 | }, |
| 140 | 143 | { |
| 141 | 144 | (const char * const []){"LEN0034", "LEN0036", "LEN0037", |
| 142 | 145 | "LEN0039", "LEN2002", "LEN2004", |
| 143 | 146 | NULL}, |
| 147 | + {ANY_BOARD_ID, 2961}, | |
| 144 | 148 | 1024, 5112, 2024, 4832 |
| 145 | 149 | }, |
| 146 | 150 | { |
| 147 | 151 | (const char * const []){"LEN2001", NULL}, |
| 152 | + {ANY_BOARD_ID, ANY_BOARD_ID}, | |
| 148 | 153 | 1024, 5022, 2508, 4832 |
| 149 | 154 | }, |
| 150 | 155 | { |
| 151 | 156 | (const char * const []){"LEN2006", NULL}, |
| 157 | + {ANY_BOARD_ID, ANY_BOARD_ID}, | |
| 152 | 158 | 1264, 5675, 1171, 4688 |
| 153 | 159 | }, |
| 154 | 160 | { } |
| @@ -175,9 +181,7 @@ static const char * const topbuttonpad_pnp_ids[] = { · 20 unmodified lines | ||
| 175 | 181 | "LEN0041", |
| 176 | 182 | "LEN0042", /* Yoga */ |
| 177 | 183 | "LEN0045", |
| 178 | − "LEN0046", | |
| 179 | 184 | "LEN0047", |
| 180 | − "LEN0048", | |
| 181 | 185 | "LEN0049", |
| 182 | 186 | "LEN2000", |
| 183 | 187 | "LEN2001", /* Edge E431 */ |
| @@ -235,18 +239,39 @@ static int synaptics_model_id(struct psmouse *psmouse) · 51 unmodified lines | ||
| 235 | 239 | return 0; |
| 236 | 240 | } |
| 237 | 241 | |
| 242 | +static int synaptics_more_extended_queries(struct psmouse *psmouse) | |
| 243 | +{ | |
| 244 | + struct synaptics_data *priv = psmouse->private; | |
| 245 | + unsigned char buf[3]; | |
| 246 | + | |
| 247 | + if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf)) | |
| 248 | + return -1; | |
| 249 | + | |
| 250 | + priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2]; | |
| 251 | + | |
| 252 | + return 0; | |
| 253 | +} | |
| 254 | + | |
| 238 | 255 | /* |
| 239 | − * Read the board id from the touchpad | |
| 256 | + * Read the board id and the "More Extended Queries" from the touchpad | |
| 240 | 257 | * The board id is encoded in the "QUERY MODES" response |
| 241 | 258 | */ |
| 242 | −static int synaptics_board_id(struct psmouse *psmouse) | |
| 259 | +static int synaptics_query_modes(struct psmouse *psmouse) | |
| 243 | 260 | { |
| 244 | 261 | struct synaptics_data *priv = psmouse->private; |
| 245 | 262 | unsigned char bid[3]; |
| 246 | 263 | |
| 264 | + /* firmwares prior 7.5 have no board_id encoded */ | |
| 265 | + if (SYN_ID_FULL(priv->identity) < 0x705) | |
| 266 | + return 0; | |
| 267 | + | |
| 247 | 268 | if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) |
| 248 | 269 | return -1; |
| 249 | 270 | priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; |
| 271 | + | |
| 272 | + if (SYN_MEXT_CAP_BIT(bid[0])) | |
| 273 | + return synaptics_more_extended_queries(psmouse); | |
| 274 | + | |
| 250 | 275 | return 0; |
| 251 | 276 | } |
| 252 | 277 | |
| @@ -346,7 +371,6 @@ static int synaptics_resolution(struct psmouse *psmouse) · 93 unmodified lines | ||
| 346 | 371 | { |
| 347 | 372 | struct synaptics_data *priv = psmouse->private; |
| 348 | 373 | unsigned char resp[3]; |
| 349 | − int i; | |
| 350 | 374 | |
| 351 | 375 | if (SYN_ID_MAJOR(priv->identity) < 4) |
| 352 | 376 | return 0; |
| @@ -358,17 +382,6 @@ static int synaptics_resolution(struct psmouse *psmouse) · 5 unmodified lines | ||
| 358 | 382 | } |
| 359 | 383 | } |
| 360 | 384 | |
| 361 | − for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { | |
| 362 | − if (psmouse_matches_pnp_id(psmouse, | |
| 363 | − min_max_pnpid_table[i].pnp_ids)) { | |
| 364 | − priv->x_min = min_max_pnpid_table[i].x_min; | |
| 365 | − priv->x_max = min_max_pnpid_table[i].x_max; | |
| 366 | − priv->y_min = min_max_pnpid_table[i].y_min; | |
| 367 | − priv->y_max = min_max_pnpid_table[i].y_max; | |
| 368 | − return 0; | |
| 369 | − } | |
| 370 | − } | |
| 371 | − | |
| 372 | 385 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
| 373 | 386 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
| 374 | 387 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
| @@ -377,23 +390,69 @@ static int synaptics_resolution(struct psmouse *psmouse) · 2 unmodified lines | ||
| 377 | 390 | } else { |
| 378 | 391 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
| 379 | 392 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
| 393 | + psmouse_info(psmouse, | |
| 394 | + "queried max coordinates: x [..%d], y [..%d]\n", | |
| 395 | + priv->x_max, priv->y_max); | |
| 380 | 396 | } |
| 381 | 397 | } |
| 382 | 398 | |
| 383 | − if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | |
| 384 | − SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | |
| 399 | + if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) && | |
| 400 | + (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 || | |
| 401 | + /* | |
| 402 | + * Firmware v8.1 does not report proper number of extended | |
| 403 | + * capabilities, but has been proven to report correct min | |
| 404 | + * coordinates. | |
| 405 | + */ | |
| 406 | + SYN_ID_FULL(priv->identity) == 0x801)) { | |
| 385 | 407 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { |
| 386 | 408 | psmouse_warn(psmouse, |
| 387 | 409 | "device claims to have min coordinates query, but I'm not able to read it.\n"); |
| 388 | 410 | } else { |
| 389 | 411 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
| 390 | 412 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
| 413 | + psmouse_info(psmouse, | |
| 414 | + "queried min coordinates: x [%d..], y [%d..]\n", | |
| 415 | + priv->x_min, priv->y_min); | |
| 391 | 416 | } |
| 392 | 417 | } |
| 393 | 418 | |
| 394 | 419 | return 0; |
| 395 | 420 | } |
| 396 | 421 | |
| 422 | +/* | |
| 423 | + * Apply quirk(s) if the hardware matches | |
| 424 | + */ | |
| 425 | + | |
| 426 | +static void synaptics_apply_quirks(struct psmouse *psmouse) | |
| 427 | +{ | |
| 428 | + struct synaptics_data *priv = psmouse->private; | |
| 429 | + int i; | |
| 430 | + | |
| 431 | + for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { | |
| 432 | + if (!psmouse_matches_pnp_id(psmouse, | |
| 433 | + min_max_pnpid_table[i].pnp_ids)) | |
| 434 | + continue; | |
| 435 | + | |
| 436 | + if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID && | |
| 437 | + priv->board_id < min_max_pnpid_table[i].board_id.min) | |
| 438 | + continue; | |
| 439 | + | |
| 440 | + if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID && | |
| 441 | + priv->board_id > min_max_pnpid_table[i].board_id.max) | |
| 442 | + continue; | |
| 443 | + | |
| 444 | + priv->x_min = min_max_pnpid_table[i].x_min; | |
| 445 | + priv->x_max = min_max_pnpid_table[i].x_max; | |
| 446 | + priv->y_min = min_max_pnpid_table[i].y_min; | |
| 447 | + priv->y_max = min_max_pnpid_table[i].y_max; | |
| 448 | + psmouse_info(psmouse, | |
| 449 | + "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", | |
| 450 | + priv->x_min, priv->x_max, | |
| 451 | + priv->y_min, priv->y_max); | |
| 452 | + break; | |
| 453 | + } | |
| 454 | +} | |
| 455 | + | |
| 397 | 456 | static int synaptics_query_hardware(struct psmouse *psmouse) |
| 398 | 457 | { |
| 399 | 458 | if (synaptics_identify(psmouse)) |
| @@ -402,13 +461,15 @@ static int synaptics_query_hardware(struct psmouse *psmouse) · 2 unmodified lines | ||
| 402 | 461 | return -1; |
| 403 | 462 | if (synaptics_firmware_id(psmouse)) |
| 404 | 463 | return -1; |
| 405 | − if (synaptics_board_id(psmouse)) | |
| 464 | + if (synaptics_query_modes(psmouse)) | |
| 406 | 465 | return -1; |
| 407 | 466 | if (synaptics_capability(psmouse)) |
| 408 | 467 | return -1; |
| 409 | 468 | if (synaptics_resolution(psmouse)) |
| 410 | 469 | return -1; |
| 411 | 470 | |
| 471 | + synaptics_apply_quirks(psmouse); | |
| 472 | + | |
| 412 | 473 | return 0; |
| 413 | 474 | } |
| 414 | 475 | |
| @@ -516,18 +577,22 @@ static int synaptics_is_pt_packet(unsigned char *buf) · 101 unmodified lines | ||
| 516 | 577 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
| 517 | 578 | } |
| 518 | 579 | |
| 519 | −static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) | |
| 580 | +static void synaptics_pass_pt_packet(struct psmouse *psmouse, | |
| 581 | + struct serio *ptport, | |
| 582 | + unsigned char *packet) | |
| 520 | 583 | { |
| 584 | + struct synaptics_data *priv = psmouse->private; | |
| 521 | 585 | struct psmouse *child = serio_get_drvdata(ptport); |
| 522 | 586 | |
| 523 | 587 | if (child && child->state == PSMOUSE_ACTIVATED) { |
| 524 | − serio_interrupt(ptport, packet[1], 0); | |
| 588 | + serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0); | |
| 525 | 589 | serio_interrupt(ptport, packet[4], 0); |
| 526 | 590 | serio_interrupt(ptport, packet[5], 0); |
| 527 | 591 | if (child->pktsize == 4) |
| 528 | 592 | serio_interrupt(ptport, packet[2], 0); |
| 529 | − } else | |
| 593 | + } else { | |
| 530 | 594 | serio_interrupt(ptport, packet[1], 0); |
| 595 | + } | |
| 531 | 596 | } |
| 532 | 597 | |
| 533 | 598 | static void synaptics_pt_activate(struct psmouse *psmouse) |
| @@ -605,6 +670,18 @@ static void synaptics_parse_agm(const unsigned char buf[], · 71 unmodified lines | ||
| 605 | 670 | } |
| 606 | 671 | } |
| 607 | 672 | |
| 673 | +static void synaptics_parse_ext_buttons(const unsigned char buf[], | |
| 674 | + struct synaptics_data *priv, | |
| 675 | + struct synaptics_hw_state *hw) | |
| 676 | +{ | |
| 677 | + unsigned int ext_bits = | |
| 678 | + (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; | |
| 679 | + unsigned int ext_mask = GENMASK(ext_bits - 1, 0); | |
| 680 | + | |
| 681 | + hw->ext_buttons = buf[4] & ext_mask; | |
| 682 | + hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits; | |
| 683 | +} | |
| 684 | + | |
| 608 | 685 | static bool is_forcepad; |
| 609 | 686 | |
| 610 | 687 | static int synaptics_parse_hw_state(const unsigned char buf[], |
| @@ -691,28 +768,9 @@ static int synaptics_parse_hw_state(const unsigned char buf[], · 80 unmodified lines | ||
| 691 | 768 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
| 692 | 769 | } |
| 693 | 770 | |
| 694 | − if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | |
| 771 | + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 && | |
| 695 | 772 | ((buf[0] ^ buf[3]) & 0x02)) { |
| 696 | − switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | |
| 697 | − default: | |
| 698 | − /* | |
| 699 | − * if nExtBtn is greater than 8 it should be | |
| 700 | − * considered invalid and treated as 0 | |
| 701 | − */ | |
| 702 | − break; | |
| 703 | − case 8: | |
| 704 | − hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0; | |
| 705 | − hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0; | |
| 706 | − case 6: | |
| 707 | − hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0; | |
| 708 | − hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0; | |
| 709 | − case 4: | |
| 710 | − hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0; | |
| 711 | − hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0; | |
| 712 | − case 2: | |
| 713 | − hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0; | |
| 714 | − hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0; | |
| 715 | − } | |
| 773 | + synaptics_parse_ext_buttons(buf, priv, hw); | |
| 716 | 774 | } |
| 717 | 775 | } else { |
| 718 | 776 | hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); |
| @@ -774,12 +832,54 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, · 55 unmodified lines | ||
| 774 | 832 | } |
| 775 | 833 | } |
| 776 | 834 | |
| 835 | +static void synaptics_report_ext_buttons(struct psmouse *psmouse, | |
| 836 | + const struct synaptics_hw_state *hw) | |
| 837 | +{ | |
| 838 | + struct input_dev *dev = psmouse->dev; | |
| 839 | + struct synaptics_data *priv = psmouse->private; | |
| 840 | + int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; | |
| 841 | + char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| 842 | + int i; | |
| 843 | + | |
| 844 | + if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | |
| 845 | + return; | |
| 846 | + | |
| 847 | + /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ | |
| 848 | + if (SYN_ID_FULL(priv->identity) == 0x801 && | |
| 849 | + !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) | |
| 850 | + return; | |
| 851 | + | |
| 852 | + if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) { | |
| 853 | + for (i = 0; i < ext_bits; i++) { | |
| 854 | + input_report_key(dev, BTN_0 + 2 * i, | |
| 855 | + hw->ext_buttons & (1 << i)); | |
| 856 | + input_report_key(dev, BTN_1 + 2 * i, | |
| 857 | + hw->ext_buttons & (1 << (i + ext_bits))); | |
| 858 | + } | |
| 859 | + return; | |
| 860 | + } | |
| 861 | + | |
| 862 | + /* | |
| 863 | + * This generation of touchpads has the trackstick buttons | |
| 864 | + * physically wired to the touchpad. Re-route them through | |
| 865 | + * the pass-through interface. | |
| 866 | + */ | |
| 867 | + if (!priv->pt_port) | |
| 868 | + return; | |
| 869 | + | |
| 870 | + /* The trackstick expects at most 3 buttons */ | |
| 871 | + priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) | | |
| 872 | + SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 | | |
| 873 | + SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2; | |
| 874 | + | |
| 875 | + synaptics_pass_pt_packet(psmouse, priv->pt_port, buf); | |
| 876 | +} | |
| 877 | + | |
| 777 | 878 | static void synaptics_report_buttons(struct psmouse *psmouse, |
| 778 | 879 | const struct synaptics_hw_state *hw) |
| 779 | 880 | { |
| 780 | 881 | struct input_dev *dev = psmouse->dev; |
| 781 | 882 | struct synaptics_data *priv = psmouse->private; |
| 782 | − int i; | |
| 783 | 883 | |
| 784 | 884 | input_report_key(dev, BTN_LEFT, hw->left); |
| 785 | 885 | input_report_key(dev, BTN_RIGHT, hw->right); |
| @@ -792,8 +892,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse, · 6 unmodified lines | ||
| 792 | 892 | input_report_key(dev, BTN_BACK, hw->down); |
| 793 | 893 | } |
| 794 | 894 | |
| 795 | − for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | |
| 796 | − input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); | |
| 895 | + synaptics_report_ext_buttons(psmouse, hw); | |
| 797 | 896 | } |
| 798 | 897 | |
| 799 | 898 | static void synaptics_report_mt_data(struct psmouse *psmouse, |
| @@ -813,7 +912,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, · 13 unmodified lines | ||
| 813 | 912 | pos[i].y = synaptics_invert_y(hw[i]->y); |
| 814 | 913 | } |
| 815 | 914 | |
| 816 | − input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->x_res); | |
| 915 | + input_mt_assign_slots(dev, slot, pos, nsemi, 0); | |
| 817 | 916 | |
| 818 | 917 | for (i = 0; i < nsemi; i++) { |
| 819 | 918 | input_mt_slot(dev, slot[i]); |
| @@ -1014,7 +1113,8 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) · 194 unmodified lines | ||
| 1014 | 1113 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
| 1015 | 1114 | synaptics_is_pt_packet(psmouse->packet)) { |
| 1016 | 1115 | if (priv->pt_port) |
| 1017 | − synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | |
| 1116 | + synaptics_pass_pt_packet(psmouse, priv->pt_port, | |
| 1117 | + psmouse->packet); | |
| 1018 | 1118 | } else |
| 1019 | 1119 | synaptics_process_packet(psmouse); |
| 1020 | 1120 | |
| @@ -1116,8 +1216,9 @@ static void set_input_params(struct psmouse *psmouse, · 95 unmodified lines | ||
| 1116 | 1216 | __set_bit(BTN_BACK, dev->keybit); |
| 1117 | 1217 | } |
| 1118 | 1218 | |
| 1119 | − for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | |
| 1120 | − __set_bit(BTN_0 + i, dev->keybit); | |
| 1219 | + if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) | |
| 1220 | + for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | |
| 1221 | + __set_bit(BTN_0 + i, dev->keybit); | |
| 1121 | 1222 | |
| 1122 | 1223 | __clear_bit(EV_REL, dev->evbit); |
| 1123 | 1224 | __clear_bit(REL_X, dev->relbit); |
| @@ -1125,7 +1226,8 @@ static void set_input_params(struct psmouse *psmouse, · 1 unmodified line | ||
| 1125 | 1226 | |
| 1126 | 1227 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
| 1127 | 1228 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
| 1128 | − if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids)) | |
| 1229 | + if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && | |
| 1230 | + !SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) | |
| 1129 | 1231 | __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); |
| 1130 | 1232 | /* Clickpads report only left button */ |
| 1131 | 1233 | __clear_bit(BTN_RIGHT, dev->keybit); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #define SYN_QUE_EXT_CAPAB_0C 0x0c |
| 23 | 23 | #define SYN_QUE_EXT_MAX_COORDS 0x0d |
| 24 | 24 | #define SYN_QUE_EXT_MIN_COORDS 0x0f |
| 25 | +#define SYN_QUE_MEXT_CAPAB_10 0x10 | |
| 25 | 26 | |
| 26 | 27 | /* synatics modes */ |
| 27 | 28 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) |
| @@ -53,6 +54,7 @@ · 25 unmodified lines | ||
| 53 | 54 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
| 54 | 55 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
| 55 | 56 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) |
| 57 | +#define SYN_MEXT_CAP_BIT(m) ((m) & (1 << 1)) | |
| 56 | 58 | |
| 57 | 59 | /* |
| 58 | 60 | * The following describes response for the 0x0c query. |
| @@ -89,6 +91,30 @@ · 30 unmodified lines | ||
| 89 | 91 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
| 90 | 92 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) |
| 91 | 93 | |
| 94 | +/* | |
| 95 | + * The following descibes response for the 0x10 query. | |
| 96 | + * | |
| 97 | + * byte mask name meaning | |
| 98 | + * ---- ---- ------- ------------ | |
| 99 | + * 1 0x01 ext buttons are stick buttons exported in the extended | |
| 100 | + * capability are actually meant to be used | |
| 101 | + * by the tracktick (pass-through). | |
| 102 | + * 1 0x02 SecurePad the touchpad is a SecurePad, so it | |
| 103 | + * contains a built-in fingerprint reader. | |
| 104 | + * 1 0xe0 more ext count how many more extented queries are | |
| 105 | + * available after this one. | |
| 106 | + * 2 0xff SecurePad width the width of the SecurePad fingerprint | |
| 107 | + * reader. | |
| 108 | + * 3 0xff SecurePad height the height of the SecurePad fingerprint | |
| 109 | + * reader. | |
| 110 | + */ | |
| 111 | +#define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000) | |
| 112 | +#define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000) | |
| 113 | + | |
| 114 | +#define SYN_CAP_EXT_BUTTON_STICK_L(eb) (!!((eb) & 0x01)) | |
| 115 | +#define SYN_CAP_EXT_BUTTON_STICK_M(eb) (!!((eb) & 0x02)) | |
| 116 | +#define SYN_CAP_EXT_BUTTON_STICK_R(eb) (!!((eb) & 0x04)) | |
| 117 | + | |
| 92 | 118 | /* synaptics modes query bits */ |
| 93 | 119 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
| 94 | 120 | #define SYN_MODE_RATE(m) ((m) & (1 << 6)) |
| @@ -143,6 +169,7 @@ struct synaptics_data { · 48 unmodified lines | ||
| 143 | 169 | unsigned long int capabilities; /* Capabilities */ |
| 144 | 170 | unsigned long int ext_cap; /* Extended Capabilities */ |
| 145 | 171 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ |
| 172 | + unsigned long int ext_cap_10; /* Ext Caps from 0x10 query */ | |
| 146 | 173 | unsigned long int identity; /* Identification */ |
| 147 | 174 | unsigned int x_res, y_res; /* X/Y resolution in units/mm */ |
| 148 | 175 | unsigned int x_max, y_max; /* Max coordinates (from FW) */ |
| @@ -156,6 +183,7 @@ struct synaptics_data { · 7 unmodified lines | ||
| 156 | 183 | bool disable_gesture; /* disable gestures */ |
| 157 | 184 | |
| 158 | 185 | struct serio *pt_port; /* Pass-through serio port */ |
| 186 | + unsigned char pt_buttons; /* Pass-through buttons */ | |
| 159 | 187 | |
| 160 | 188 | /* |
| 161 | 189 | * Last received Advanced Gesture Mode (AGM) packet. An AGM packet |
| @@ -943,6 +943,7 @@ config TOUCHSCREEN_SUN4I · 942 unmodified lines | ||
| 943 | 943 | tristate "Allwinner sun4i resistive touchscreen controller support" |
| 944 | 944 | depends on ARCH_SUNXI || COMPILE_TEST |
| 945 | 945 | depends on HWMON |
| 946 | + depends on THERMAL || !THERMAL_OF | |
| 946 | 947 | help |
| 947 | 948 | This selects support for the resistive touchscreen controller |
| 948 | 949 | found on Allwinner sunxi SoCs. |
| @@ -23,6 +23,7 @@ config IOMMU_IO_PGTABLE · 22 unmodified lines | ||
| 23 | 23 | config IOMMU_IO_PGTABLE_LPAE |
| 24 | 24 | bool "ARMv7/v8 Long Descriptor Format" |
| 25 | 25 | select IOMMU_IO_PGTABLE |
| 26 | + depends on ARM || ARM64 || COMPILE_TEST | |
| 26 | 27 | help |
| 27 | 28 | Enable support for the ARM long descriptor pagetable format. |
| 28 | 29 | This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page |
| @@ -63,6 +64,7 @@ config MSM_IOMMU · 34 unmodified lines | ||
| 63 | 64 | bool "MSM IOMMU Support" |
| 64 | 65 | depends on ARM |
| 65 | 66 | depends on ARCH_MSM8X60 || ARCH_MSM8960 || COMPILE_TEST |
| 67 | + depends on BROKEN | |
| 66 | 68 | select IOMMU_API |
| 67 | 69 | help |
| 68 | 70 | Support for the IOMMUs found on certain Qualcomm SOCs. |
| @@ -1186,8 +1186,15 @@ static const struct iommu_ops exynos_iommu_ops = { · 1185 unmodified lines | ||
| 1186 | 1186 | |
| 1187 | 1187 | static int __init exynos_iommu_init(void) |
| 1188 | 1188 | { |
| 1189 | + struct device_node *np; | |
| 1189 | 1190 | int ret; |
| 1190 | 1191 | |
| 1192 | + np = of_find_matching_node(NULL, sysmmu_of_match); | |
| 1193 | + if (!np) | |
| 1194 | + return 0; | |
| 1195 | + | |
| 1196 | + of_node_put(np); | |
| 1197 | + | |
| 1191 | 1198 | lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table", |
| 1192 | 1199 | LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL); |
| 1193 | 1200 | if (!lv2table_kmem_cache) { |
| @@ -56,7 +56,8 @@ · 55 unmodified lines | ||
| 56 | 56 | ((((d)->levels - ((l) - ARM_LPAE_START_LVL(d) + 1)) \ |
| 57 | 57 | * (d)->bits_per_level) + (d)->pg_shift) |
| 58 | 58 | |
| 59 | −#define ARM_LPAE_PAGES_PER_PGD(d) ((d)->pgd_size >> (d)->pg_shift) | |
| 59 | +#define ARM_LPAE_PAGES_PER_PGD(d) \ | |
| 60 | + DIV_ROUND_UP((d)->pgd_size, 1UL << (d)->pg_shift) | |
| 60 | 61 | |
| 61 | 62 | /* |
| 62 | 63 | * Calculate the index at level l used to map virtual address a using the |
| @@ -66,7 +67,7 @@ · 3 unmodified lines | ||
| 66 | 67 | ((l) == ARM_LPAE_START_LVL(d) ? ilog2(ARM_LPAE_PAGES_PER_PGD(d)) : 0) |
| 67 | 68 | |
| 68 | 69 | #define ARM_LPAE_LVL_IDX(a,l,d) \ |
| 69 | − (((a) >> ARM_LPAE_LVL_SHIFT(l,d)) & \ | |
| 70 | + (((u64)(a) >> ARM_LPAE_LVL_SHIFT(l,d)) & \ | |
| 70 | 71 | ((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1)) |
| 71 | 72 | |
| 72 | 73 | /* Calculate the block/page mapping size at level l for pagetable in d. */ |
| @@ -1376,6 +1376,13 @@ static int __init omap_iommu_init(void) · 1375 unmodified lines | ||
| 1376 | 1376 | struct kmem_cache *p; |
| 1377 | 1377 | const unsigned long flags = SLAB_HWCACHE_ALIGN; |
| 1378 | 1378 | size_t align = 1 << 10; /* L2 pagetable alignement */ |
| 1379 | + struct device_node *np; | |
| 1380 | + | |
| 1381 | + np = of_find_matching_node(NULL, omap_iommu_of_match); | |
| 1382 | + if (!np) | |
| 1383 | + return 0; | |
| 1384 | + | |
| 1385 | + of_node_put(np); | |
| 1379 | 1386 | |
| 1380 | 1387 | p = kmem_cache_create("iopte_cache", IOPTE_TABLE_SIZE, align, flags, |
| 1381 | 1388 | iopte_cachep_ctor); |
| @@ -1015,8 +1015,15 @@ static struct platform_driver rk_iommu_driver = { · 1014 unmodified lines | ||
| 1015 | 1015 | |
| 1016 | 1016 | static int __init rk_iommu_init(void) |
| 1017 | 1017 | { |
| 1018 | + struct device_node *np; | |
| 1018 | 1019 | int ret; |
| 1019 | 1020 | |
| 1021 | + np = of_find_matching_node(NULL, rk_iommu_dt_ids); | |
| 1022 | + if (!np) | |
| 1023 | + return 0; | |
| 1024 | + | |
| 1025 | + of_node_put(np); | |
| 1026 | + | |
| 1020 | 1027 | ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops); |
| 1021 | 1028 | if (ret) |
| 1022 | 1029 | return ret; |
| @@ -69,6 +69,7 @@ static void __iomem *per_cpu_int_base; · 68 unmodified lines | ||
| 69 | 69 | static void __iomem *main_int_base; |
| 70 | 70 | static struct irq_domain *armada_370_xp_mpic_domain; |
| 71 | 71 | static u32 doorbell_mask_reg; |
| 72 | +static int parent_irq; | |
| 72 | 73 | #ifdef CONFIG_PCI_MSI |
| 73 | 74 | static struct irq_domain *armada_370_xp_msi_domain; |
| 74 | 75 | static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); |
| @@ -356,6 +357,7 @@ static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, · 281 unmodified lines | ||
| 356 | 357 | { |
| 357 | 358 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) |
| 358 | 359 | armada_xp_mpic_smp_cpu_init(); |
| 360 | + | |
| 359 | 361 | return NOTIFY_OK; |
| 360 | 362 | } |
| 361 | 363 | |
| @@ -364,6 +366,20 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = { · 2 unmodified lines | ||
| 364 | 366 | .priority = 100, |
| 365 | 367 | }; |
| 366 | 368 | |
| 369 | +static int mpic_cascaded_secondary_init(struct notifier_block *nfb, | |
| 370 | + unsigned long action, void *hcpu) | |
| 371 | +{ | |
| 372 | + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) | |
| 373 | + enable_percpu_irq(parent_irq, IRQ_TYPE_NONE); | |
| 374 | + | |
| 375 | + return NOTIFY_OK; | |
| 376 | +} | |
| 377 | + | |
| 378 | +static struct notifier_block mpic_cascaded_cpu_notifier = { | |
| 379 | + .notifier_call = mpic_cascaded_secondary_init, | |
| 380 | + .priority = 100, | |
| 381 | +}; | |
| 382 | + | |
| 367 | 383 | #endif /* CONFIG_SMP */ |
| 368 | 384 | |
| 369 | 385 | static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { |
| @@ -539,7 +555,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, · 169 unmodified lines | ||
| 539 | 555 | struct device_node *parent) |
| 540 | 556 | { |
| 541 | 557 | struct resource main_int_res, per_cpu_int_res; |
| 542 | − int parent_irq, nr_irqs, i; | |
| 558 | + int nr_irqs, i; | |
| 543 | 559 | u32 control; |
| 544 | 560 | |
| 545 | 561 | BUG_ON(of_address_to_resource(node, 0, &main_int_res)); |
| @@ -587,6 +603,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, · 41 unmodified lines | ||
| 587 | 603 | register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier); |
| 588 | 604 | #endif |
| 589 | 605 | } else { |
| 606 | +#ifdef CONFIG_SMP | |
| 607 | + register_cpu_notifier(&mpic_cascaded_cpu_notifier); | |
| 608 | +#endif | |
| 590 | 609 | irq_set_chained_handler(parent_irq, |
| 591 | 610 | armada_370_xp_mpic_handle_cascade_irq); |
| 592 | 611 | } |
| @@ -416,13 +416,14 @@ static void its_send_single_command(struct its_node *its, · 415 unmodified lines | ||
| 416 | 416 | { |
| 417 | 417 | struct its_cmd_block *cmd, *sync_cmd, *next_cmd; |
| 418 | 418 | struct its_collection *sync_col; |
| 419 | + unsigned long flags; | |
| 419 | 420 | |
| 420 | − raw_spin_lock(&its->lock); | |
| 421 | + raw_spin_lock_irqsave(&its->lock, flags); | |
| 421 | 422 | |
| 422 | 423 | cmd = its_allocate_entry(its); |
| 423 | 424 | if (!cmd) { /* We're soooooo screewed... */ |
| 424 | 425 | pr_err_ratelimited("ITS can't allocate, dropping command\n"); |
| 425 | − raw_spin_unlock(&its->lock); | |
| 426 | + raw_spin_unlock_irqrestore(&its->lock, flags); | |
| 426 | 427 | return; |
| 427 | 428 | } |
| 428 | 429 | sync_col = builder(cmd, desc); |
| @@ -442,7 +443,7 @@ static void its_send_single_command(struct its_node *its, · 13 unmodified lines | ||
| 442 | 443 | |
| 443 | 444 | post: |
| 444 | 445 | next_cmd = its_post_commands(its); |
| 445 | − raw_spin_unlock(&its->lock); | |
| 446 | + raw_spin_unlock_irqrestore(&its->lock, flags); | |
| 446 | 447 | |
| 447 | 448 | its_wait_for_range_completion(its, cmd, next_cmd); |
| 448 | 449 | } |
| @@ -799,21 +800,43 @@ static int its_alloc_tables(struct its_node *its) · 350 unmodified lines | ||
| 799 | 800 | { |
| 800 | 801 | int err; |
| 801 | 802 | int i; |
| 802 | − int psz = PAGE_SIZE; | |
| 803 | + int psz = SZ_64K; | |
| 803 | 804 | u64 shr = GITS_BASER_InnerShareable; |
| 804 | 805 | |
| 805 | 806 | for (i = 0; i < GITS_BASER_NR_REGS; i++) { |
| 806 | 807 | u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); |
| 807 | 808 | u64 type = GITS_BASER_TYPE(val); |
| 808 | 809 | u64 entry_size = GITS_BASER_ENTRY_SIZE(val); |
| 810 | + int order = get_order(psz); | |
| 811 | + int alloc_size; | |
| 809 | 812 | u64 tmp; |
| 810 | 813 | void *base; |
| 811 | 814 | |
| 812 | 815 | if (type == GITS_BASER_TYPE_NONE) |
| 813 | 816 | continue; |
| 814 | 817 | |
| 815 | − /* We're lazy and only allocate a single page for now */ | |
| 816 | − base = (void *)get_zeroed_page(GFP_KERNEL); | |
| 818 | + /* | |
| 819 | + * Allocate as many entries as required to fit the | |
| 820 | + * range of device IDs that the ITS can grok... The ID | |
| 821 | + * space being incredibly sparse, this results in a | |
| 822 | + * massive waste of memory. | |
| 823 | + * | |
| 824 | + * For other tables, only allocate a single page. | |
| 825 | + */ | |
| 826 | + if (type == GITS_BASER_TYPE_DEVICE) { | |
| 827 | + u64 typer = readq_relaxed(its->base + GITS_TYPER); | |
| 828 | + u32 ids = GITS_TYPER_DEVBITS(typer); | |
| 829 | + | |
| 830 | + order = get_order((1UL << ids) * entry_size); | |
| 831 | + if (order >= MAX_ORDER) { | |
| 832 | + order = MAX_ORDER - 1; | |
| 833 | + pr_warn("%s: Device Table too large, reduce its page order to %u\n", | |
| 834 | + its->msi_chip.of_node->full_name, order); | |
| 835 | + } | |
| 836 | + } | |
| 837 | + | |
| 838 | + alloc_size = (1 << order) * PAGE_SIZE; | |
| 839 | + base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | |
| 817 | 840 | if (!base) { |
| 818 | 841 | err = -ENOMEM; |
| 819 | 842 | goto out_free; |
| @@ -841,7 +864,7 @@ retry_baser: · 21 unmodified lines | ||
| 841 | 864 | break; |
| 842 | 865 | } |
| 843 | 866 | |
| 844 | − val |= (PAGE_SIZE / psz) - 1; | |
| 867 | + val |= (alloc_size / psz) - 1; | |
| 845 | 868 | |
| 846 | 869 | writeq_relaxed(val, its->base + GITS_BASER + i * 8); |
| 847 | 870 | tmp = readq_relaxed(its->base + GITS_BASER + i * 8); |
| @@ -882,7 +905,7 @@ retry_baser: · 34 unmodified lines | ||
| 882 | 905 | } |
| 883 | 906 | |
| 884 | 907 | pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n", |
| 885 | − (int)(PAGE_SIZE / entry_size), | |
| 908 | + (int)(alloc_size / entry_size), | |
| 886 | 909 | its_base_type_string[type], |
| 887 | 910 | (unsigned long)virt_to_phys(base), |
| 888 | 911 | psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT); |
| @@ -1020,8 +1043,9 @@ static void its_cpu_init_collection(void) · 131 unmodified lines | ||
| 1020 | 1043 | static struct its_device *its_find_device(struct its_node *its, u32 dev_id) |
| 1021 | 1044 | { |
| 1022 | 1045 | struct its_device *its_dev = NULL, *tmp; |
| 1046 | + unsigned long flags; | |
| 1023 | 1047 | |
| 1024 | − raw_spin_lock(&its->lock); | |
| 1048 | + raw_spin_lock_irqsave(&its->lock, flags); | |
| 1025 | 1049 | |
| 1026 | 1050 | list_for_each_entry(tmp, &its->its_device_list, entry) { |
| 1027 | 1051 | if (tmp->device_id == dev_id) { |
| @@ -1030,7 +1054,7 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id) · 2 unmodified lines | ||
| 1030 | 1054 | } |
| 1031 | 1055 | } |
| 1032 | 1056 | |
| 1033 | − raw_spin_unlock(&its->lock); | |
| 1057 | + raw_spin_unlock_irqrestore(&its->lock, flags); | |
| 1034 | 1058 | |
| 1035 | 1059 | return its_dev; |
| 1036 | 1060 | } |
| @@ -1040,6 +1064,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 3 unmodified lines | ||
| 1040 | 1064 | { |
| 1041 | 1065 | struct its_device *dev; |
| 1042 | 1066 | unsigned long *lpi_map; |
| 1067 | + unsigned long flags; | |
| 1043 | 1068 | void *itt; |
| 1044 | 1069 | int lpi_base; |
| 1045 | 1070 | int nr_lpis; |
| @@ -1056,7 +1081,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 10 unmodified lines | ||
| 1056 | 1081 | nr_ites = max(2UL, roundup_pow_of_two(nvecs)); |
| 1057 | 1082 | sz = nr_ites * its->ite_size; |
| 1058 | 1083 | sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; |
| 1059 | − itt = kmalloc(sz, GFP_KERNEL); | |
| 1084 | + itt = kzalloc(sz, GFP_KERNEL); | |
| 1060 | 1085 | lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis); |
| 1061 | 1086 | |
| 1062 | 1087 | if (!dev || !itt || !lpi_map) { |
| @@ -1075,9 +1100,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 12 unmodified lines | ||
| 1075 | 1100 | dev->device_id = dev_id; |
| 1076 | 1101 | INIT_LIST_HEAD(&dev->entry); |
| 1077 | 1102 | |
| 1078 | − raw_spin_lock(&its->lock); | |
| 1103 | + raw_spin_lock_irqsave(&its->lock, flags); | |
| 1079 | 1104 | list_add(&dev->entry, &its->its_device_list); |
| 1080 | − raw_spin_unlock(&its->lock); | |
| 1105 | + raw_spin_unlock_irqrestore(&its->lock, flags); | |
| 1081 | 1106 | |
| 1082 | 1107 | /* Bind the device to the first possible CPU */ |
| 1083 | 1108 | cpu = cpumask_first(cpu_online_mask); |
| @@ -1091,9 +1116,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, · 7 unmodified lines | ||
| 1091 | 1116 | |
| 1092 | 1117 | static void its_free_device(struct its_device *its_dev) |
| 1093 | 1118 | { |
| 1094 | − raw_spin_lock(&its_dev->its->lock); | |
| 1119 | + unsigned long flags; | |
| 1120 | + | |
| 1121 | + raw_spin_lock_irqsave(&its_dev->its->lock, flags); | |
| 1095 | 1122 | list_del(&its_dev->entry); |
| 1096 | − raw_spin_unlock(&its_dev->its->lock); | |
| 1123 | + raw_spin_unlock_irqrestore(&its_dev->its->lock, flags); | |
| 1097 | 1124 | kfree(its_dev->itt); |
| 1098 | 1125 | kfree(its_dev); |
| 1099 | 1126 | } |
| @@ -1112,31 +1139,69 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq) · 12 unmodified lines | ||
| 1112 | 1139 | return 0; |
| 1113 | 1140 | } |
| 1114 | 1141 | |
| 1142 | +struct its_pci_alias { | |
| 1143 | + struct pci_dev *pdev; | |
| 1144 | + u32 dev_id; | |
| 1145 | + u32 count; | |
| 1146 | +}; | |
| 1147 | + | |
| 1148 | +static int its_pci_msi_vec_count(struct pci_dev *pdev) | |
| 1149 | +{ | |
| 1150 | + int msi, msix; | |
| 1151 | + | |
| 1152 | + msi = max(pci_msi_vec_count(pdev), 0); | |
| 1153 | + msix = max(pci_msix_vec_count(pdev), 0); | |
| 1154 | + | |
| 1155 | + return max(msi, msix); | |
| 1156 | +} | |
| 1157 | + | |
| 1158 | +static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) | |
| 1159 | +{ | |
| 1160 | + struct its_pci_alias *dev_alias = data; | |
| 1161 | + | |
| 1162 | + dev_alias->dev_id = alias; | |
| 1163 | + if (pdev != dev_alias->pdev) | |
| 1164 | + dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); | |
| 1165 | + | |
| 1166 | + return 0; | |
| 1167 | +} | |
| 1168 | + | |
| 1115 | 1169 | static int its_msi_prepare(struct irq_domain *domain, struct device *dev, |
| 1116 | 1170 | int nvec, msi_alloc_info_t *info) |
| 1117 | 1171 | { |
| 1118 | 1172 | struct pci_dev *pdev; |
| 1119 | 1173 | struct its_node *its; |
| 1120 | − u32 dev_id; | |
| 1121 | 1174 | struct its_device *its_dev; |
| 1175 | + struct its_pci_alias dev_alias; | |
| 1122 | 1176 | |
| 1123 | 1177 | if (!dev_is_pci(dev)) |
| 1124 | 1178 | return -EINVAL; |
| 1125 | 1179 | |
| 1126 | 1180 | pdev = to_pci_dev(dev); |
| 1127 | − dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn); | |
| 1181 | + dev_alias.pdev = pdev; | |
| 1182 | + dev_alias.count = nvec; | |
| 1183 | + | |
| 1184 | + pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias); | |
| 1128 | 1185 | its = domain->parent->host_data; |
| 1129 | 1186 | |
| 1130 | − its_dev = its_find_device(its, dev_id); | |
| 1131 | − if (WARN_ON(its_dev)) | |
| 1132 | − return -EINVAL; | |
| 1187 | + its_dev = its_find_device(its, dev_alias.dev_id); | |
| 1188 | + if (its_dev) { | |
| 1189 | + /* | |
| 1190 | + * We already have seen this ID, probably through | |
| 1191 | + * another alias (PCI bridge of some sort). No need to | |
| 1192 | + * create the device. | |
| 1193 | + */ | |
| 1194 | + dev_dbg(dev, "Reusing ITT for devID %x\n", dev_alias.dev_id); | |
| 1195 | + goto out; | |
| 1196 | + } | |
| 1133 | 1197 | |
| 1134 | − its_dev = its_create_device(its, dev_id, nvec); | |
| 1198 | + its_dev = its_create_device(its, dev_alias.dev_id, dev_alias.count); | |
| 1135 | 1199 | if (!its_dev) |
| 1136 | 1200 | return -ENOMEM; |
| 1137 | 1201 | |
| 1138 | − dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec)); | |
| 1139 | − | |
| 1202 | + dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", | |
| 1203 | + dev_alias.count, ilog2(dev_alias.count)); | |
| 1204 | +out: | |
| 1140 | 1205 | info->scratchpad[0].ptr = its_dev; |
| 1141 | 1206 | info->scratchpad[1].ptr = dev; |
| 1142 | 1207 | return 0; |
| @@ -1255,6 +1320,34 @@ static const struct irq_domain_ops its_domain_ops = { · 112 unmodified lines | ||
| 1255 | 1320 | .deactivate = its_irq_domain_deactivate, |
| 1256 | 1321 | }; |
| 1257 | 1322 | |
| 1323 | +static int its_force_quiescent(void __iomem *base) | |
| 1324 | +{ | |
| 1325 | + u32 count = 1000000; /* 1s */ | |
| 1326 | + u32 val; | |
| 1327 | + | |
| 1328 | + val = readl_relaxed(base + GITS_CTLR); | |
| 1329 | + if (val & GITS_CTLR_QUIESCENT) | |
| 1330 | + return 0; | |
| 1331 | + | |
| 1332 | + /* Disable the generation of all interrupts to this ITS */ | |
| 1333 | + val &= ~GITS_CTLR_ENABLE; | |
| 1334 | + writel_relaxed(val, base + GITS_CTLR); | |
| 1335 | + | |
| 1336 | + /* Poll GITS_CTLR and wait until ITS becomes quiescent */ | |
| 1337 | + while (1) { | |
| 1338 | + val = readl_relaxed(base + GITS_CTLR); | |
| 1339 | + if (val & GITS_CTLR_QUIESCENT) | |
| 1340 | + return 0; | |
| 1341 | + | |
| 1342 | + count--; | |
| 1343 | + if (!count) | |
| 1344 | + return -EBUSY; | |
| 1345 | + | |
| 1346 | + cpu_relax(); | |
| 1347 | + udelay(1); | |
| 1348 | + } | |
| 1349 | +} | |
| 1350 | + | |
| 1258 | 1351 | static int its_probe(struct device_node *node, struct irq_domain *parent) |
| 1259 | 1352 | { |
| 1260 | 1353 | struct resource res; |
| @@ -1283,6 +1376,13 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) · 22 unmodified lines | ||
| 1283 | 1376 | goto out_unmap; |
| 1284 | 1377 | } |
| 1285 | 1378 | |
| 1379 | + err = its_force_quiescent(its_base); | |
| 1380 | + if (err) { | |
| 1381 | + pr_warn("%s: failed to quiesce, giving up\n", | |
| 1382 | + node->full_name); | |
| 1383 | + goto out_unmap; | |
| 1384 | + } | |
| 1385 | + | |
| 1286 | 1386 | pr_info("ITS: %s\n", node->full_name); |
| 1287 | 1387 | |
| 1288 | 1388 | its = kzalloc(sizeof(*its), GFP_KERNEL); |
| @@ -1323,7 +1423,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) · 34 unmodified lines | ||
| 1323 | 1423 | writeq_relaxed(baser, its->base + GITS_CBASER); |
| 1324 | 1424 | tmp = readq_relaxed(its->base + GITS_CBASER); |
| 1325 | 1425 | writeq_relaxed(0, its->base + GITS_CWRITER); |
| 1326 | − writel_relaxed(1, its->base + GITS_CTLR); | |
| 1426 | + writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); | |
| 1327 | 1427 | |
| 1328 | 1428 | if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) { |
| 1329 | 1429 | pr_info("ITS: using cache flushing for cmd queue\n"); |
| @@ -1382,12 +1482,11 @@ static bool gic_rdists_supports_plpis(void) · 52 unmodified lines | ||
| 1382 | 1482 | |
| 1383 | 1483 | int its_cpu_init(void) |
| 1384 | 1484 | { |
| 1385 | − if (!gic_rdists_supports_plpis()) { | |
| 1386 | − pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); | |
| 1387 | − return -ENXIO; | |
| 1388 | − } | |
| 1389 | − | |
| 1390 | 1485 | if (!list_empty(&its_nodes)) { |
| 1486 | + if (!gic_rdists_supports_plpis()) { | |
| 1487 | + pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); | |
| 1488 | + return -ENXIO; | |
| 1489 | + } | |
| 1391 | 1490 | its_cpu_init_lpis(); |
| 1392 | 1491 | its_cpu_init_collection(); |
| 1393 | 1492 | } |
| @@ -466,7 +466,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, · 465 unmodified lines | ||
| 466 | 466 | tlist |= 1 << (mpidr & 0xf); |
| 467 | 467 | |
| 468 | 468 | cpu = cpumask_next(cpu, mask); |
| 469 | − if (cpu == nr_cpu_ids) | |
| 469 | + if (cpu >= nr_cpu_ids) | |
| 470 | 470 | goto out; |
| 471 | 471 | |
| 472 | 472 | mpidr = cpu_logical_map(cpu); |
| @@ -154,23 +154,25 @@ static inline unsigned int gic_irq(struct irq_data *d) · 153 unmodified lines | ||
| 154 | 154 | static void gic_mask_irq(struct irq_data *d) |
| 155 | 155 | { |
| 156 | 156 | u32 mask = 1 << (gic_irq(d) % 32); |
| 157 | + unsigned long flags; | |
| 157 | 158 | |
| 158 | − raw_spin_lock(&irq_controller_lock); | |
| 159 | + raw_spin_lock_irqsave(&irq_controller_lock, flags); | |
| 159 | 160 | writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); |
| 160 | 161 | if (gic_arch_extn.irq_mask) |
| 161 | 162 | gic_arch_extn.irq_mask(d); |
| 162 | − raw_spin_unlock(&irq_controller_lock); | |
| 163 | + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | |
| 163 | 164 | } |
| 164 | 165 | |
| 165 | 166 | static void gic_unmask_irq(struct irq_data *d) |
| 166 | 167 | { |
| 167 | 168 | u32 mask = 1 << (gic_irq(d) % 32); |
| 169 | + unsigned long flags; | |
| 168 | 170 | |
| 169 | − raw_spin_lock(&irq_controller_lock); | |
| 171 | + raw_spin_lock_irqsave(&irq_controller_lock, flags); | |
| 170 | 172 | if (gic_arch_extn.irq_unmask) |
| 171 | 173 | gic_arch_extn.irq_unmask(d); |
| 172 | 174 | writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); |
| 173 | − raw_spin_unlock(&irq_controller_lock); | |
| 175 | + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | |
| 174 | 176 | } |
| 175 | 177 | |
| 176 | 178 | static void gic_eoi_irq(struct irq_data *d) |
| @@ -188,6 +190,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) · 11 unmodified lines | ||
| 188 | 190 | { |
| 189 | 191 | void __iomem *base = gic_dist_base(d); |
| 190 | 192 | unsigned int gicirq = gic_irq(d); |
| 193 | + unsigned long flags; | |
| 191 | 194 | int ret; |
| 192 | 195 | |
| 193 | 196 | /* Interrupt configuration for SGIs can't be changed */ |
| @@ -199,14 +202,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type) · 5 unmodified lines | ||
| 199 | 202 | type != IRQ_TYPE_EDGE_RISING) |
| 200 | 203 | return -EINVAL; |
| 201 | 204 | |
| 202 | − raw_spin_lock(&irq_controller_lock); | |
| 205 | + raw_spin_lock_irqsave(&irq_controller_lock, flags); | |
| 203 | 206 | |
| 204 | 207 | if (gic_arch_extn.irq_set_type) |
| 205 | 208 | gic_arch_extn.irq_set_type(d, type); |
| 206 | 209 | |
| 207 | 210 | ret = gic_configure_irq(gicirq, type, base, NULL); |
| 208 | 211 | |
| 209 | − raw_spin_unlock(&irq_controller_lock); | |
| 212 | + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | |
| 210 | 213 | |
| 211 | 214 | return ret; |
| 212 | 215 | } |
| @@ -227,6 +230,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, · 14 unmodified lines | ||
| 227 | 230 | void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); |
| 228 | 231 | unsigned int cpu, shift = (gic_irq(d) % 4) * 8; |
| 229 | 232 | u32 val, mask, bit; |
| 233 | + unsigned long flags; | |
| 230 | 234 | |
| 231 | 235 | if (!force) |
| 232 | 236 | cpu = cpumask_any_and(mask_val, cpu_online_mask); |
| @@ -236,12 +240,12 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, · 3 unmodified lines | ||
| 236 | 240 | if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) |
| 237 | 241 | return -EINVAL; |
| 238 | 242 | |
| 239 | − raw_spin_lock(&irq_controller_lock); | |
| 243 | + raw_spin_lock_irqsave(&irq_controller_lock, flags); | |
| 240 | 244 | mask = 0xff << shift; |
| 241 | 245 | bit = gic_cpu_map[cpu] << shift; |
| 242 | 246 | val = readl_relaxed(reg) & ~mask; |
| 243 | 247 | writel_relaxed(val | bit, reg); |
| 244 | − raw_spin_unlock(&irq_controller_lock); | |
| 248 | + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); | |
| 245 | 249 | |
| 246 | 250 | return IRQ_SET_MASK_OK; |
| 247 | 251 | } |
| @@ -1609,7 +1609,7 @@ icn_setup(char *line) · 1608 unmodified lines | ||
| 1609 | 1609 | if (ints[0] > 1) |
| 1610 | 1610 | membase = (unsigned long)ints[2]; |
| 1611 | 1611 | if (str && *str) { |
| 1612 | − strcpy(sid, str); | |
| 1612 | + strlcpy(sid, str, sizeof(sid)); | |
| 1613 | 1613 | icn_id = sid; |
| 1614 | 1614 | if ((p = strchr(sid, ','))) { |
| 1615 | 1615 | *p++ = 0; |
| @@ -289,9 +289,16 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, · 288 unmodified lines | ||
| 289 | 289 | struct request_queue *q = bdev_get_queue(where->bdev); |
| 290 | 290 | unsigned short logical_block_size = queue_logical_block_size(q); |
| 291 | 291 | sector_t num_sectors; |
| 292 | + unsigned int uninitialized_var(special_cmd_max_sectors); | |
| 292 | 293 | |
| 293 | − /* Reject unsupported discard requests */ | |
| 294 | − if ((rw & REQ_DISCARD) && !blk_queue_discard(q)) { | |
| 294 | + /* | |
| 295 | + * Reject unsupported discard and write same requests. | |
| 296 | + */ | |
| 297 | + if (rw & REQ_DISCARD) | |
| 298 | + special_cmd_max_sectors = q->limits.max_discard_sectors; | |
| 299 | + else if (rw & REQ_WRITE_SAME) | |
| 300 | + special_cmd_max_sectors = q->limits.max_write_same_sectors; | |
| 301 | + if ((rw & (REQ_DISCARD | REQ_WRITE_SAME)) && special_cmd_max_sectors == 0) { | |
| 295 | 302 | dec_count(io, region, -EOPNOTSUPP); |
| 296 | 303 | return; |
| 297 | 304 | } |
| @@ -317,7 +324,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, · 19 unmodified lines | ||
| 317 | 324 | store_io_and_region_in_bio(bio, io, region); |
| 318 | 325 | |
| 319 | 326 | if (rw & REQ_DISCARD) { |
| 320 | − num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); | |
| 327 | + num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining); | |
| 321 | 328 | bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT; |
| 322 | 329 | remaining -= num_sectors; |
| 323 | 330 | } else if (rw & REQ_WRITE_SAME) { |
| @@ -326,7 +333,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, · 2 unmodified lines | ||
| 326 | 333 | */ |
| 327 | 334 | dp->get_page(dp, &page, &len, &offset); |
| 328 | 335 | bio_add_page(bio, page, logical_block_size, offset); |
| 329 | − num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining); | |
| 336 | + num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining); | |
| 330 | 337 | bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT; |
| 331 | 338 | |
| 332 | 339 | offset = 0; |
| @@ -20,6 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/log2.h> |
| 21 | 21 | #include <linux/dm-kcopyd.h> |
| 22 | 22 | |
| 23 | +#include "dm.h" | |
| 24 | + | |
| 23 | 25 | #include "dm-exception-store.h" |
| 24 | 26 | |
| 25 | 27 | #define DM_MSG_PREFIX "snapshots" |
| @@ -290,6 +292,16 @@ struct origin { · 264 unmodified lines | ||
| 290 | 292 | struct list_head snapshots; |
| 291 | 293 | }; |
| 292 | 294 | |
| 295 | +/* | |
| 296 | + * This structure is allocated for each origin target | |
| 297 | + */ | |
| 298 | +struct dm_origin { | |
| 299 | + struct dm_dev *dev; | |
| 300 | + struct dm_target *ti; | |
| 301 | + unsigned split_boundary; | |
| 302 | + struct list_head hash_list; | |
| 303 | +}; | |
| 304 | + | |
| 293 | 305 | /* |
| 294 | 306 | * Size of the hash table for origin volumes. If we make this |
| 295 | 307 | * the size of the minors list then it should be nearly perfect |
| @@ -297,6 +309,7 @@ struct origin { · 1 unmodified line | ||
| 297 | 309 | #define ORIGIN_HASH_SIZE 256 |
| 298 | 310 | #define ORIGIN_MASK 0xFF |
| 299 | 311 | static struct list_head *_origins; |
| 312 | +static struct list_head *_dm_origins; | |
| 300 | 313 | static struct rw_semaphore _origins_lock; |
| 301 | 314 | |
| 302 | 315 | static DECLARE_WAIT_QUEUE_HEAD(_pending_exceptions_done); |
| @@ -310,12 +323,22 @@ static int init_origin_hash(void) · 7 unmodified lines | ||
| 310 | 323 | _origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), |
| 311 | 324 | GFP_KERNEL); |
| 312 | 325 | if (!_origins) { |
| 313 | − DMERR("unable to allocate memory"); | |
| 326 | + DMERR("unable to allocate memory for _origins"); | |
| 314 | 327 | return -ENOMEM; |
| 315 | 328 | } |
| 316 | − | |
| 317 | 329 | for (i = 0; i < ORIGIN_HASH_SIZE; i++) |
| 318 | 330 | INIT_LIST_HEAD(_origins + i); |
| 331 | + | |
| 332 | + _dm_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head), | |
| 333 | + GFP_KERNEL); | |
| 334 | + if (!_dm_origins) { | |
| 335 | + DMERR("unable to allocate memory for _dm_origins"); | |
| 336 | + kfree(_origins); | |
| 337 | + return -ENOMEM; | |
| 338 | + } | |
| 339 | + for (i = 0; i < ORIGIN_HASH_SIZE; i++) | |
| 340 | + INIT_LIST_HEAD(_dm_origins + i); | |
| 341 | + | |
| 319 | 342 | init_rwsem(&_origins_lock); |
| 320 | 343 | |
| 321 | 344 | return 0; |
| @@ -324,6 +347,7 @@ static int init_origin_hash(void) · 2 unmodified lines | ||
| 324 | 347 | static void exit_origin_hash(void) |
| 325 | 348 | { |
| 326 | 349 | kfree(_origins); |
| 350 | + kfree(_dm_origins); | |
| 327 | 351 | } |
| 328 | 352 | |
| 329 | 353 | static unsigned origin_hash(struct block_device *bdev) |
| @@ -350,6 +374,30 @@ static void __insert_origin(struct origin *o) · 20 unmodified lines | ||
| 350 | 374 | list_add_tail(&o->hash_list, sl); |
| 351 | 375 | } |
| 352 | 376 | |
| 377 | +static struct dm_origin *__lookup_dm_origin(struct block_device *origin) | |
| 378 | +{ | |
| 379 | + struct list_head *ol; | |
| 380 | + struct dm_origin *o; | |
| 381 | + | |
| 382 | + ol = &_dm_origins[origin_hash(origin)]; | |
| 383 | + list_for_each_entry (o, ol, hash_list) | |
| 384 | + if (bdev_equal(o->dev->bdev, origin)) | |
| 385 | + return o; | |
| 386 | + | |
| 387 | + return NULL; | |
| 388 | +} | |
| 389 | + | |
| 390 | +static void __insert_dm_origin(struct dm_origin *o) | |
| 391 | +{ | |
| 392 | + struct list_head *sl = &_dm_origins[origin_hash(o->dev->bdev)]; | |
| 393 | + list_add_tail(&o->hash_list, sl); | |
| 394 | +} | |
| 395 | + | |
| 396 | +static void __remove_dm_origin(struct dm_origin *o) | |
| 397 | +{ | |
| 398 | + list_del(&o->hash_list); | |
| 399 | +} | |
| 400 | + | |
| 353 | 401 | /* |
| 354 | 402 | * _origins_lock must be held when calling this function. |
| 355 | 403 | * Returns number of snapshots registered using the supplied cow device, plus: |
| @@ -1840,9 +1888,40 @@ static int snapshot_preresume(struct dm_target *ti) · 1484 unmodified lines | ||
| 1840 | 1888 | static void snapshot_resume(struct dm_target *ti) |
| 1841 | 1889 | { |
| 1842 | 1890 | struct dm_snapshot *s = ti->private; |
| 1843 | − struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; | |
| 1891 | + struct dm_snapshot *snap_src = NULL, *snap_dest = NULL, *snap_merging = NULL; | |
| 1892 | + struct dm_origin *o; | |
| 1893 | + struct mapped_device *origin_md = NULL; | |
| 1894 | + bool must_restart_merging = false; | |
| 1844 | 1895 | |
| 1845 | 1896 | down_read(&_origins_lock); |
| 1897 | + | |
| 1898 | + o = __lookup_dm_origin(s->origin->bdev); | |
| 1899 | + if (o) | |
| 1900 | + origin_md = dm_table_get_md(o->ti->table); | |
| 1901 | + if (!origin_md) { | |
| 1902 | + (void) __find_snapshots_sharing_cow(s, NULL, NULL, &snap_merging); | |
| 1903 | + if (snap_merging) | |
| 1904 | + origin_md = dm_table_get_md(snap_merging->ti->table); | |
| 1905 | + } | |
| 1906 | + if (origin_md == dm_table_get_md(ti->table)) | |
| 1907 | + origin_md = NULL; | |
| 1908 | + if (origin_md) { | |
| 1909 | + if (dm_hold(origin_md)) | |
| 1910 | + origin_md = NULL; | |
| 1911 | + } | |
| 1912 | + | |
| 1913 | + up_read(&_origins_lock); | |
| 1914 | + | |
| 1915 | + if (origin_md) { | |
| 1916 | + dm_internal_suspend_fast(origin_md); | |
| 1917 | + if (snap_merging && test_bit(RUNNING_MERGE, &snap_merging->state_bits)) { | |
| 1918 | + must_restart_merging = true; | |
| 1919 | + stop_merge(snap_merging); | |
| 1920 | + } | |
| 1921 | + } | |
| 1922 | + | |
| 1923 | + down_read(&_origins_lock); | |
| 1924 | + | |
| 1846 | 1925 | (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL); |
| 1847 | 1926 | if (snap_src && snap_dest) { |
| 1848 | 1927 | down_write(&snap_src->lock); |
| @@ -1851,8 +1930,16 @@ static void snapshot_resume(struct dm_target *ti) · 2 unmodified lines | ||
| 1851 | 1930 | up_write(&snap_dest->lock); |
| 1852 | 1931 | up_write(&snap_src->lock); |
| 1853 | 1932 | } |
| 1933 | + | |
| 1854 | 1934 | up_read(&_origins_lock); |
| 1855 | 1935 | |
| 1936 | + if (origin_md) { | |
| 1937 | + if (must_restart_merging) | |
| 1938 | + start_merge(snap_merging); | |
| 1939 | + dm_internal_resume_fast(origin_md); | |
| 1940 | + dm_put(origin_md); | |
| 1941 | + } | |
| 1942 | + | |
| 1856 | 1943 | /* Now we have correct chunk size, reregister */ |
| 1857 | 1944 | reregister_snapshot(s); |
| 1858 | 1945 | |
| @@ -2133,11 +2220,6 @@ static int origin_write_extent(struct dm_snapshot *merging_snap, · 274 unmodified lines | ||
| 2133 | 2220 | * Origin: maps a linear range of a device, with hooks for snapshotting. |
| 2134 | 2221 | */ |
| 2135 | 2222 | |
| 2136 | −struct dm_origin { | |
| 2137 | − struct dm_dev *dev; | |
| 2138 | − unsigned split_boundary; | |
| 2139 | −}; | |
| 2140 | − | |
| 2141 | 2223 | /* |
| 2142 | 2224 | * Construct an origin mapping: <dev_path> |
| 2143 | 2225 | * The context for an origin is merely a 'struct dm_dev *' |
| @@ -2166,6 +2248,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 22 unmodified lines | ||
| 2166 | 2248 | goto bad_open; |
| 2167 | 2249 | } |
| 2168 | 2250 | |
| 2251 | + o->ti = ti; | |
| 2169 | 2252 | ti->private = o; |
| 2170 | 2253 | ti->num_flush_bios = 1; |
| 2171 | 2254 | |
| @@ -2180,6 +2263,7 @@ bad_alloc: · 8 unmodified lines | ||
| 2180 | 2263 | static void origin_dtr(struct dm_target *ti) |
| 2181 | 2264 | { |
| 2182 | 2265 | struct dm_origin *o = ti->private; |
| 2266 | + | |
| 2183 | 2267 | dm_put_device(ti, o->dev); |
| 2184 | 2268 | kfree(o); |
| 2185 | 2269 | } |
| @@ -2216,6 +2300,19 @@ static void origin_resume(struct dm_target *ti) · 30 unmodified lines | ||
| 2216 | 2300 | struct dm_origin *o = ti->private; |
| 2217 | 2301 | |
| 2218 | 2302 | o->split_boundary = get_origin_minimum_chunksize(o->dev->bdev); |
| 2303 | + | |
| 2304 | + down_write(&_origins_lock); | |
| 2305 | + __insert_dm_origin(o); | |
| 2306 | + up_write(&_origins_lock); | |
| 2307 | +} | |
| 2308 | + | |
| 2309 | +static void origin_postsuspend(struct dm_target *ti) | |
| 2310 | +{ | |
| 2311 | + struct dm_origin *o = ti->private; | |
| 2312 | + | |
| 2313 | + down_write(&_origins_lock); | |
| 2314 | + __remove_dm_origin(o); | |
| 2315 | + up_write(&_origins_lock); | |
| 2219 | 2316 | } |
| 2220 | 2317 | |
| 2221 | 2318 | static void origin_status(struct dm_target *ti, status_type_t type, |
| @@ -2258,12 +2355,13 @@ static int origin_iterate_devices(struct dm_target *ti, · 36 unmodified lines | ||
| 2258 | 2355 | |
| 2259 | 2356 | static struct target_type origin_target = { |
| 2260 | 2357 | .name = "snapshot-origin", |
| 2261 | − .version = {1, 8, 1}, | |
| 2358 | + .version = {1, 9, 0}, | |
| 2262 | 2359 | .module = THIS_MODULE, |
| 2263 | 2360 | .ctr = origin_ctr, |
| 2264 | 2361 | .dtr = origin_dtr, |
| 2265 | 2362 | .map = origin_map, |
| 2266 | 2363 | .resume = origin_resume, |
| 2364 | + .postsuspend = origin_postsuspend, | |
| 2267 | 2365 | .status = origin_status, |
| 2268 | 2366 | .merge = origin_merge, |
| 2269 | 2367 | .iterate_devices = origin_iterate_devices, |
| @@ -2271,7 +2369,7 @@ static struct target_type origin_target = { · 1 unmodified line | ||
| 2271 | 2369 | |
| 2272 | 2370 | static struct target_type snapshot_target = { |
| 2273 | 2371 | .name = "snapshot", |
| 2274 | − .version = {1, 12, 0}, | |
| 2372 | + .version = {1, 13, 0}, | |
| 2275 | 2373 | .module = THIS_MODULE, |
| 2276 | 2374 | .ctr = snapshot_ctr, |
| 2277 | 2375 | .dtr = snapshot_dtr, |
| @@ -2285,7 +2383,7 @@ static struct target_type snapshot_target = { · 7 unmodified lines | ||
| 2285 | 2383 | |
| 2286 | 2384 | static struct target_type merge_target = { |
| 2287 | 2385 | .name = dm_snapshot_merge_target_name, |
| 2288 | − .version = {1, 2, 0}, | |
| 2386 | + .version = {1, 3, 0}, | |
| 2289 | 2387 | .module = THIS_MODULE, |
| 2290 | 2388 | .ctr = snapshot_ctr, |
| 2291 | 2389 | .dtr = snapshot_dtr, |
| @@ -2358,17 +2358,6 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) · 2357 unmodified lines | ||
| 2358 | 2358 | return DM_MAPIO_REMAPPED; |
| 2359 | 2359 | |
| 2360 | 2360 | case -ENODATA: |
| 2361 | − if (get_pool_mode(tc->pool) == PM_READ_ONLY) { | |
| 2362 | − /* | |
| 2363 | − * This block isn't provisioned, and we have no way | |
| 2364 | − * of doing so. | |
| 2365 | − */ | |
| 2366 | − handle_unserviceable_bio(tc->pool, bio); | |
| 2367 | − cell_defer_no_holder(tc, virt_cell); | |
| 2368 | − return DM_MAPIO_SUBMITTED; | |
| 2369 | − } | |
| 2370 | − /* fall through */ | |
| 2371 | − | |
| 2372 | 2361 | case -EWOULDBLOCK: |
| 2373 | 2362 | thin_defer_cell(tc, virt_cell); |
| 2374 | 2363 | return DM_MAPIO_SUBMITTED; |
| @@ -2616,6 +2616,19 @@ void dm_get(struct mapped_device *md) · 2615 unmodified lines | ||
| 2616 | 2616 | BUG_ON(test_bit(DMF_FREEING, &md->flags)); |
| 2617 | 2617 | } |
| 2618 | 2618 | |
| 2619 | +int dm_hold(struct mapped_device *md) | |
| 2620 | +{ | |
| 2621 | + spin_lock(&_minor_lock); | |
| 2622 | + if (test_bit(DMF_FREEING, &md->flags)) { | |
| 2623 | + spin_unlock(&_minor_lock); | |
| 2624 | + return -EBUSY; | |
| 2625 | + } | |
| 2626 | + dm_get(md); | |
| 2627 | + spin_unlock(&_minor_lock); | |
| 2628 | + return 0; | |
| 2629 | +} | |
| 2630 | +EXPORT_SYMBOL_GPL(dm_hold); | |
| 2631 | + | |
| 2619 | 2632 | const char *dm_device_name(struct mapped_device *md) |
| 2620 | 2633 | { |
| 2621 | 2634 | return md->name; |
| @@ -2638,10 +2651,16 @@ static void __dm_destroy(struct mapped_device *md, bool wait) · 16 unmodified lines | ||
| 2638 | 2651 | if (dm_request_based(md)) |
| 2639 | 2652 | flush_kthread_worker(&md->kworker); |
| 2640 | 2653 | |
| 2654 | + /* | |
| 2655 | + * Take suspend_lock so that presuspend and postsuspend methods | |
| 2656 | + * do not race with internal suspend. | |
| 2657 | + */ | |
| 2658 | + mutex_lock(&md->suspend_lock); | |
| 2641 | 2659 | if (!dm_suspended_md(md)) { |
| 2642 | 2660 | dm_table_presuspend_targets(map); |
| 2643 | 2661 | dm_table_postsuspend_targets(map); |
| 2644 | 2662 | } |
| 2663 | + mutex_unlock(&md->suspend_lock); | |
| 2645 | 2664 | |
| 2646 | 2665 | /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ |
| 2647 | 2666 | dm_put_live_table(md, srcu_idx); |
| @@ -3115,6 +3134,7 @@ void dm_internal_suspend_fast(struct mapped_device *md) · 467 unmodified lines | ||
| 3115 | 3134 | flush_workqueue(md->wq); |
| 3116 | 3135 | dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); |
| 3117 | 3136 | } |
| 3137 | +EXPORT_SYMBOL_GPL(dm_internal_suspend_fast); | |
| 3118 | 3138 | |
| 3119 | 3139 | void dm_internal_resume_fast(struct mapped_device *md) |
| 3120 | 3140 | { |
| @@ -3126,6 +3146,7 @@ void dm_internal_resume_fast(struct mapped_device *md) · 5 unmodified lines | ||
| 3126 | 3146 | done: |
| 3127 | 3147 | mutex_unlock(&md->suspend_lock); |
| 3128 | 3148 | } |
| 3149 | +EXPORT_SYMBOL_GPL(dm_internal_resume_fast); | |
| 3129 | 3150 | |
| 3130 | 3151 | /*----------------------------------------------------------------- |
| 3131 | 3152 | * Event notification. |
| @@ -5080,7 +5080,8 @@ int md_run(struct mddev *mddev) · 5079 unmodified lines | ||
| 5080 | 5080 | } |
| 5081 | 5081 | if (err) { |
| 5082 | 5082 | mddev_detach(mddev); |
| 5083 | − pers->free(mddev, mddev->private); | |
| 5083 | + if (mddev->private) | |
| 5084 | + pers->free(mddev, mddev->private); | |
| 5084 | 5085 | module_put(pers->owner); |
| 5085 | 5086 | bitmap_destroy(mddev); |
| 5086 | 5087 | return err; |
| @@ -467,8 +467,6 @@ static int raid0_run(struct mddev *mddev) · 466 unmodified lines | ||
| 467 | 467 | dump_zones(mddev); |
| 468 | 468 | |
| 469 | 469 | ret = md_integrity_register(mddev); |
| 470 | − if (ret) | |
| 471 | − raid0_free(mddev, conf); | |
| 472 | 470 | |
| 473 | 471 | return ret; |
| 474 | 472 | } |
| @@ -124,7 +124,7 @@ int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev) · 123 unmodified lines | ||
| 124 | 124 | PTR_ERR(pwrseq->reset_gpios[i]) != -ENOSYS) { |
| 125 | 125 | ret = PTR_ERR(pwrseq->reset_gpios[i]); |
| 126 | 126 | |
| 127 | − while (--i) | |
| 127 | + while (i--) | |
| 128 | 128 | gpiod_put(pwrseq->reset_gpios[i]); |
| 129 | 129 | |
| 130 | 130 | goto clk_put; |
| @@ -526,6 +526,7 @@ config MTD_NAND_SUNXI · 525 unmodified lines | ||
| 526 | 526 | |
| 527 | 527 | config MTD_NAND_HISI504 |
| 528 | 528 | tristate "Support for NAND controller on Hisilicon SoC Hip04" |
| 529 | + depends on HAS_DMA | |
| 529 | 530 | help |
| 530 | 531 | Enables support for NAND controller on Hisilicon SoC Hip04. |
| 531 | 532 | |
| @@ -480,6 +480,42 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) · 479 unmodified lines | ||
| 480 | 480 | nand_writel(info, NDCR, ndcr | int_mask); |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | +static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len) | |
| 484 | +{ | |
| 485 | + if (info->ecc_bch) { | |
| 486 | + int timeout; | |
| 487 | + | |
| 488 | + /* | |
| 489 | + * According to the datasheet, when reading from NDDB | |
| 490 | + * with BCH enabled, after each 32 bytes reads, we | |
| 491 | + * have to make sure that the NDSR.RDDREQ bit is set. | |
| 492 | + * | |
| 493 | + * Drain the FIFO 8 32 bits reads at a time, and skip | |
| 494 | + * the polling on the last read. | |
| 495 | + */ | |
| 496 | + while (len > 8) { | |
| 497 | + __raw_readsl(info->mmio_base + NDDB, data, 8); | |
| 498 | + | |
| 499 | + for (timeout = 0; | |
| 500 | + !(nand_readl(info, NDSR) & NDSR_RDDREQ); | |
| 501 | + timeout++) { | |
| 502 | + if (timeout >= 5) { | |
| 503 | + dev_err(&info->pdev->dev, | |
| 504 | + "Timeout on RDDREQ while draining the FIFO\n"); | |
| 505 | + return; | |
| 506 | + } | |
| 507 | + | |
| 508 | + mdelay(1); | |
| 509 | + } | |
| 510 | + | |
| 511 | + data += 32; | |
| 512 | + len -= 8; | |
| 513 | + } | |
| 514 | + } | |
| 515 | + | |
| 516 | + __raw_readsl(info->mmio_base + NDDB, data, len); | |
| 517 | +} | |
| 518 | + | |
| 483 | 519 | static void handle_data_pio(struct pxa3xx_nand_info *info) |
| 484 | 520 | { |
| 485 | 521 | unsigned int do_bytes = min(info->data_size, info->chunk_size); |
| @@ -496,14 +532,14 @@ static void handle_data_pio(struct pxa3xx_nand_info *info) · 10 unmodified lines | ||
| 496 | 532 | DIV_ROUND_UP(info->oob_size, 4)); |
| 497 | 533 | break; |
| 498 | 534 | case STATE_PIO_READING: |
| 499 | − __raw_readsl(info->mmio_base + NDDB, | |
| 500 | − info->data_buff + info->data_buff_pos, | |
| 501 | − DIV_ROUND_UP(do_bytes, 4)); | |
| 535 | + drain_fifo(info, | |
| 536 | + info->data_buff + info->data_buff_pos, | |
| 537 | + DIV_ROUND_UP(do_bytes, 4)); | |
| 502 | 538 | |
| 503 | 539 | if (info->oob_size > 0) |
| 504 | − __raw_readsl(info->mmio_base + NDDB, | |
| 505 | − info->oob_buff + info->oob_buff_pos, | |
| 506 | − DIV_ROUND_UP(info->oob_size, 4)); | |
| 540 | + drain_fifo(info, | |
| 541 | + info->oob_buff + info->oob_buff_pos, | |
| 542 | + DIV_ROUND_UP(info->oob_size, 4)); | |
| 507 | 543 | break; |
| 508 | 544 | default: |
| 509 | 545 | dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, |
| @@ -1572,6 +1608,8 @@ static int alloc_nand_resource(struct platform_device *pdev) · 1062 unmodified lines | ||
| 1572 | 1608 | int ret, irq, cs; |
| 1573 | 1609 | |
| 1574 | 1610 | pdata = dev_get_platdata(&pdev->dev); |
| 1611 | + if (pdata->num_cs <= 0) | |
| 1612 | + return -ENODEV; | |
| 1575 | 1613 | info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) + |
| 1576 | 1614 | sizeof(*host)) * pdata->num_cs, GFP_KERNEL); |
| 1577 | 1615 | if (!info) |
| @@ -425,9 +425,10 @@ retry: · 424 unmodified lines | ||
| 425 | 425 | ubi_warn(ubi, "corrupted VID header at PEB %d, LEB %d:%d", |
| 426 | 426 | pnum, vol_id, lnum); |
| 427 | 427 | err = -EBADMSG; |
| 428 | − } else | |
| 428 | + } else { | |
| 429 | 429 | err = -EINVAL; |
| 430 | 430 | ubi_ro_mode(ubi); |
| 431 | + } | |
| 431 | 432 | } |
| 432 | 433 | goto out_free; |
| 433 | 434 | } else if (err == UBI_IO_BITFLIPS) |
| @@ -131,7 +131,7 @@ config CAN_RCAR · 130 unmodified lines | ||
| 131 | 131 | |
| 132 | 132 | config CAN_XILINXCAN |
| 133 | 133 | tristate "Xilinx CAN" |
| 134 | − depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST | |
| 134 | + depends on ARCH_ZYNQ || ARM64 || MICROBLAZE || COMPILE_TEST | |
| 135 | 135 | depends on COMMON_CLK && HAS_IOMEM |
| 136 | 136 | ---help--- |
| 137 | 137 | Xilinx CAN driver. This driver supports both soft AXI CAN IP and |
| @@ -579,6 +579,10 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) · 578 unmodified lines | ||
| 579 | 579 | skb->pkt_type = PACKET_BROADCAST; |
| 580 | 580 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 581 | 581 | |
| 582 | + skb_reset_mac_header(skb); | |
| 583 | + skb_reset_network_header(skb); | |
| 584 | + skb_reset_transport_header(skb); | |
| 585 | + | |
| 582 | 586 | can_skb_reserve(skb); |
| 583 | 587 | can_skb_prv(skb)->ifindex = dev->ifindex; |
| 584 | 588 | |
| @@ -603,6 +607,10 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, · 18 unmodified lines | ||
| 603 | 607 | skb->pkt_type = PACKET_BROADCAST; |
| 604 | 608 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| 605 | 609 | |
| 610 | + skb_reset_mac_header(skb); | |
| 611 | + skb_reset_network_header(skb); | |
| 612 | + skb_reset_transport_header(skb); | |
| 613 | + | |
| 606 | 614 | can_skb_reserve(skb); |
| 607 | 615 | can_skb_prv(skb)->ifindex = dev->ifindex; |
| 608 | 616 | |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | * Copyright (C) 2015 Valeo S.A. |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | +#include <linux/spinlock.h> | |
| 18 | +#include <linux/kernel.h> | |
| 17 | 19 | #include <linux/completion.h> |
| 18 | 20 | #include <linux/module.h> |
| 19 | 21 | #include <linux/netdevice.h> |
| @@ -466,10 +468,11 @@ struct kvaser_usb { · 446 unmodified lines | ||
| 466 | 468 | struct kvaser_usb_net_priv { |
| 467 | 469 | struct can_priv can; |
| 468 | 470 | |
| 469 | − atomic_t active_tx_urbs; | |
| 470 | − struct usb_anchor tx_submitted; | |
| 471 | + spinlock_t tx_contexts_lock; | |
| 472 | + int active_tx_contexts; | |
| 471 | 473 | struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS]; |
| 472 | 474 | |
| 475 | + struct usb_anchor tx_submitted; | |
| 473 | 476 | struct completion start_comp, stop_comp; |
| 474 | 477 | |
| 475 | 478 | struct kvaser_usb *dev; |
| @@ -584,8 +587,15 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id, · 108 unmodified lines | ||
| 584 | 587 | while (pos <= actual_len - MSG_HEADER_LEN) { |
| 585 | 588 | tmp = buf + pos; |
| 586 | 589 | |
| 587 | − if (!tmp->len) | |
| 588 | − break; | |
| 590 | + /* Handle messages crossing the USB endpoint max packet | |
| 591 | + * size boundary. Check kvaser_usb_read_bulk_callback() | |
| 592 | + * for further details. | |
| 593 | + */ | |
| 594 | + if (tmp->len == 0) { | |
| 595 | + pos = round_up(pos, | |
| 596 | + dev->bulk_in->wMaxPacketSize); | |
| 597 | + continue; | |
| 598 | + } | |
| 589 | 599 | |
| 590 | 600 | if (pos + tmp->len > actual_len) { |
| 591 | 601 | dev_err(dev->udev->dev.parent, |
| @@ -686,6 +696,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, · 94 unmodified lines | ||
| 686 | 696 | struct kvaser_usb_net_priv *priv; |
| 687 | 697 | struct sk_buff *skb; |
| 688 | 698 | struct can_frame *cf; |
| 699 | + unsigned long flags; | |
| 689 | 700 | u8 channel, tid; |
| 690 | 701 | |
| 691 | 702 | channel = msg->u.tx_acknowledge_header.channel; |
| @@ -729,12 +740,15 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, · 37 unmodified lines | ||
| 729 | 740 | |
| 730 | 741 | stats->tx_packets++; |
| 731 | 742 | stats->tx_bytes += context->dlc; |
| 732 | − can_get_echo_skb(priv->netdev, context->echo_index); | |
| 733 | 743 | |
| 734 | − context->echo_index = MAX_TX_URBS; | |
| 735 | − atomic_dec(&priv->active_tx_urbs); | |
| 744 | + spin_lock_irqsave(&priv->tx_contexts_lock, flags); | |
| 736 | 745 | |
| 746 | + can_get_echo_skb(priv->netdev, context->echo_index); | |
| 747 | + context->echo_index = MAX_TX_URBS; | |
| 748 | + --priv->active_tx_contexts; | |
| 737 | 749 | netif_wake_queue(priv->netdev); |
| 750 | + | |
| 751 | + spin_unlock_irqrestore(&priv->tx_contexts_lock, flags); | |
| 738 | 752 | } |
| 739 | 753 | |
| 740 | 754 | static void kvaser_usb_simple_msg_callback(struct urb *urb) |
| @@ -787,7 +801,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, · 46 unmodified lines | ||
| 787 | 801 | netdev_err(netdev, "Error transmitting URB\n"); |
| 788 | 802 | usb_unanchor_urb(urb); |
| 789 | 803 | usb_free_urb(urb); |
| 790 | − kfree(buf); | |
| 791 | 804 | return err; |
| 792 | 805 | } |
| 793 | 806 | |
| @@ -796,17 +809,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, · 2 unmodified lines | ||
| 796 | 809 | return 0; |
| 797 | 810 | } |
| 798 | 811 | |
| 799 | −static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) | |
| 800 | −{ | |
| 801 | − int i; | |
| 802 | − | |
| 803 | − usb_kill_anchored_urbs(&priv->tx_submitted); | |
| 804 | − atomic_set(&priv->active_tx_urbs, 0); | |
| 805 | − | |
| 806 | − for (i = 0; i < MAX_TX_URBS; i++) | |
| 807 | − priv->tx_contexts[i].echo_index = MAX_TX_URBS; | |
| 808 | −} | |
| 809 | − | |
| 810 | 812 | static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, |
| 811 | 813 | const struct kvaser_usb_error_summary *es, |
| 812 | 814 | struct can_frame *cf) |
| @@ -1317,8 +1319,19 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) · 504 unmodified lines | ||
| 1317 | 1319 | while (pos <= urb->actual_length - MSG_HEADER_LEN) { |
| 1318 | 1320 | msg = urb->transfer_buffer + pos; |
| 1319 | 1321 | |
| 1320 | − if (!msg->len) | |
| 1321 | − break; | |
| 1322 | + /* The Kvaser firmware can only read and write messages that | |
| 1323 | + * does not cross the USB's endpoint wMaxPacketSize boundary. | |
| 1324 | + * If a follow-up command crosses such boundary, firmware puts | |
| 1325 | + * a placeholder zero-length command in its place then aligns | |
| 1326 | + * the real command to the next max packet size. | |
| 1327 | + * | |
| 1328 | + * Handle such cases or we're going to miss a significant | |
| 1329 | + * number of events in case of a heavy rx load on the bus. | |
| 1330 | + */ | |
| 1331 | + if (msg->len == 0) { | |
| 1332 | + pos = round_up(pos, dev->bulk_in->wMaxPacketSize); | |
| 1333 | + continue; | |
| 1334 | + } | |
| 1322 | 1335 | |
| 1323 | 1336 | if (pos + msg->len > urb->actual_length) { |
| 1324 | 1337 | dev_err(dev->udev->dev.parent, "Format error\n"); |
| @@ -1326,7 +1339,6 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) · 1 unmodified line | ||
| 1326 | 1339 | } |
| 1327 | 1340 | |
| 1328 | 1341 | kvaser_usb_handle_message(dev, msg); |
| 1329 | − | |
| 1330 | 1342 | pos += msg->len; |
| 1331 | 1343 | } |
| 1332 | 1344 | |
| @@ -1498,6 +1510,24 @@ error: · 165 unmodified lines | ||
| 1498 | 1510 | return err; |
| 1499 | 1511 | } |
| 1500 | 1512 | |
| 1513 | +static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) | |
| 1514 | +{ | |
| 1515 | + int i; | |
| 1516 | + | |
| 1517 | + priv->active_tx_contexts = 0; | |
| 1518 | + for (i = 0; i < MAX_TX_URBS; i++) | |
| 1519 | + priv->tx_contexts[i].echo_index = MAX_TX_URBS; | |
| 1520 | +} | |
| 1521 | + | |
| 1522 | +/* This method might sleep. Do not call it in the atomic context | |
| 1523 | + * of URB completions. | |
| 1524 | + */ | |
| 1525 | +static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) | |
| 1526 | +{ | |
| 1527 | + usb_kill_anchored_urbs(&priv->tx_submitted); | |
| 1528 | + kvaser_usb_reset_tx_urb_contexts(priv); | |
| 1529 | +} | |
| 1530 | + | |
| 1501 | 1531 | static void kvaser_usb_unlink_all_urbs(struct kvaser_usb *dev) |
| 1502 | 1532 | { |
| 1503 | 1533 | int i; |
| @@ -1615,9 +1645,9 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 111 unmodified lines | ||
| 1615 | 1645 | struct urb *urb; |
| 1616 | 1646 | void *buf; |
| 1617 | 1647 | struct kvaser_msg *msg; |
| 1618 | − int i, err; | |
| 1619 | − int ret = NETDEV_TX_OK; | |
| 1648 | + int i, err, ret = NETDEV_TX_OK; | |
| 1620 | 1649 | u8 *msg_tx_can_flags = NULL; /* GCC */ |
| 1650 | + unsigned long flags; | |
| 1621 | 1651 | |
| 1622 | 1652 | if (can_dropped_invalid_skb(netdev, skb)) |
| 1623 | 1653 | return NETDEV_TX_OK; |
| @@ -1634,7 +1664,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 10 unmodified lines | ||
| 1634 | 1664 | if (!buf) { |
| 1635 | 1665 | stats->tx_dropped++; |
| 1636 | 1666 | dev_kfree_skb(skb); |
| 1637 | − goto nobufmem; | |
| 1667 | + goto freeurb; | |
| 1638 | 1668 | } |
| 1639 | 1669 | |
| 1640 | 1670 | msg = buf; |
| @@ -1671,22 +1701,32 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 30 unmodified lines | ||
| 1671 | 1701 | if (cf->can_id & CAN_RTR_FLAG) |
| 1672 | 1702 | *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; |
| 1673 | 1703 | |
| 1704 | + spin_lock_irqsave(&priv->tx_contexts_lock, flags); | |
| 1674 | 1705 | for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { |
| 1675 | 1706 | if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { |
| 1676 | 1707 | context = &priv->tx_contexts[i]; |
| 1708 | + | |
| 1709 | + context->echo_index = i; | |
| 1710 | + can_put_echo_skb(skb, netdev, context->echo_index); | |
| 1711 | + ++priv->active_tx_contexts; | |
| 1712 | + if (priv->active_tx_contexts >= MAX_TX_URBS) | |
| 1713 | + netif_stop_queue(netdev); | |
| 1714 | + | |
| 1677 | 1715 | break; |
| 1678 | 1716 | } |
| 1679 | 1717 | } |
| 1718 | + spin_unlock_irqrestore(&priv->tx_contexts_lock, flags); | |
| 1680 | 1719 | |
| 1681 | 1720 | /* This should never happen; it implies a flow control bug */ |
| 1682 | 1721 | if (!context) { |
| 1683 | 1722 | netdev_warn(netdev, "cannot find free context\n"); |
| 1723 | + | |
| 1724 | + kfree(buf); | |
| 1684 | 1725 | ret = NETDEV_TX_BUSY; |
| 1685 | − goto releasebuf; | |
| 1726 | + goto freeurb; | |
| 1686 | 1727 | } |
| 1687 | 1728 | |
| 1688 | 1729 | context->priv = priv; |
| 1689 | − context->echo_index = i; | |
| 1690 | 1730 | context->dlc = cf->can_dlc; |
| 1691 | 1731 | |
| 1692 | 1732 | msg->u.tx_can.tid = context->echo_index; |
| @@ -1698,18 +1738,17 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 5 unmodified lines | ||
| 1698 | 1738 | kvaser_usb_write_bulk_callback, context); |
| 1699 | 1739 | usb_anchor_urb(urb, &priv->tx_submitted); |
| 1700 | 1740 | |
| 1701 | − can_put_echo_skb(skb, netdev, context->echo_index); | |
| 1702 | − | |
| 1703 | − atomic_inc(&priv->active_tx_urbs); | |
| 1704 | − | |
| 1705 | − if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) | |
| 1706 | − netif_stop_queue(netdev); | |
| 1707 | − | |
| 1708 | 1741 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 1709 | 1742 | if (unlikely(err)) { |
| 1743 | + spin_lock_irqsave(&priv->tx_contexts_lock, flags); | |
| 1744 | + | |
| 1710 | 1745 | can_free_echo_skb(netdev, context->echo_index); |
| 1746 | + context->echo_index = MAX_TX_URBS; | |
| 1747 | + --priv->active_tx_contexts; | |
| 1748 | + netif_wake_queue(netdev); | |
| 1749 | + | |
| 1750 | + spin_unlock_irqrestore(&priv->tx_contexts_lock, flags); | |
| 1711 | 1751 | |
| 1712 | − atomic_dec(&priv->active_tx_urbs); | |
| 1713 | 1752 | usb_unanchor_urb(urb); |
| 1714 | 1753 | |
| 1715 | 1754 | stats->tx_dropped++; |
| @@ -1719,16 +1758,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 3 unmodified lines | ||
| 1719 | 1758 | else |
| 1720 | 1759 | netdev_warn(netdev, "Failed tx_urb %d\n", err); |
| 1721 | 1760 | |
| 1722 | − goto releasebuf; | |
| 1761 | + goto freeurb; | |
| 1723 | 1762 | } |
| 1724 | 1763 | |
| 1725 | − usb_free_urb(urb); | |
| 1726 | − | |
| 1727 | − return NETDEV_TX_OK; | |
| 1764 | + ret = NETDEV_TX_OK; | |
| 1728 | 1765 | |
| 1729 | −releasebuf: | |
| 1730 | − kfree(buf); | |
| 1731 | −nobufmem: | |
| 1766 | +freeurb: | |
| 1732 | 1767 | usb_free_urb(urb); |
| 1733 | 1768 | return ret; |
| 1734 | 1769 | } |
| @@ -1840,7 +1875,7 @@ static int kvaser_usb_init_one(struct usb_interface *intf, · 105 unmodified lines | ||
| 1840 | 1875 | struct kvaser_usb *dev = usb_get_intfdata(intf); |
| 1841 | 1876 | struct net_device *netdev; |
| 1842 | 1877 | struct kvaser_usb_net_priv *priv; |
| 1843 | − int i, err; | |
| 1878 | + int err; | |
| 1844 | 1879 | |
| 1845 | 1880 | err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel); |
| 1846 | 1881 | if (err) |
| @@ -1854,19 +1889,17 @@ static int kvaser_usb_init_one(struct usb_interface *intf, · 7 unmodified lines | ||
| 1854 | 1889 | |
| 1855 | 1890 | priv = netdev_priv(netdev); |
| 1856 | 1891 | |
| 1892 | + init_usb_anchor(&priv->tx_submitted); | |
| 1857 | 1893 | init_completion(&priv->start_comp); |
| 1858 | 1894 | init_completion(&priv->stop_comp); |
| 1859 | 1895 | |
| 1860 | − init_usb_anchor(&priv->tx_submitted); | |
| 1861 | − atomic_set(&priv->active_tx_urbs, 0); | |
| 1862 | − | |
| 1863 | − for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) | |
| 1864 | − priv->tx_contexts[i].echo_index = MAX_TX_URBS; | |
| 1865 | − | |
| 1866 | 1896 | priv->dev = dev; |
| 1867 | 1897 | priv->netdev = netdev; |
| 1868 | 1898 | priv->channel = channel; |
| 1869 | 1899 | |
| 1900 | + spin_lock_init(&priv->tx_contexts_lock); | |
| 1901 | + kvaser_usb_reset_tx_urb_contexts(priv); | |
| 1902 | + | |
| 1870 | 1903 | priv->can.state = CAN_STATE_STOPPED; |
| 1871 | 1904 | priv->can.clock.freq = CAN_USB_CLOCK; |
| 1872 | 1905 | priv->can.bittiming_const = &kvaser_usb_bittiming_const; |
| @@ -879,6 +879,10 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) · 878 unmodified lines | ||
| 879 | 879 | |
| 880 | 880 | pdev->usb_if = ppdev->usb_if; |
| 881 | 881 | pdev->cmd_buffer_addr = ppdev->cmd_buffer_addr; |
| 882 | + | |
| 883 | + /* do a copy of the ctrlmode[_supported] too */ | |
| 884 | + dev->can.ctrlmode = ppdev->dev.can.ctrlmode; | |
| 885 | + dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported; | |
| 882 | 886 | } |
| 883 | 887 | |
| 884 | 888 | pdev->usb_if->dev[dev->ctrl_idx] = dev; |
| @@ -593,7 +593,7 @@ static int xgene_enet_reset(struct xgene_enet_pdata *pdata) · 592 unmodified lines | ||
| 593 | 593 | if (!xgene_ring_mgr_init(pdata)) |
| 594 | 594 | return -ENODEV; |
| 595 | 595 | |
| 596 | − if (!efi_enabled(EFI_BOOT)) { | |
| 596 | + if (pdata->clk) { | |
| 597 | 597 | clk_prepare_enable(pdata->clk); |
| 598 | 598 | clk_disable_unprepare(pdata->clk); |
| 599 | 599 | clk_prepare_enable(pdata->clk); |
| @@ -1025,6 +1025,8 @@ static int xgene_enet_remove(struct platform_device *pdev) · 1024 unmodified lines | ||
| 1025 | 1025 | #ifdef CONFIG_ACPI |
| 1026 | 1026 | static const struct acpi_device_id xgene_enet_acpi_match[] = { |
| 1027 | 1027 | { "APMC0D05", }, |
| 1028 | + { "APMC0D30", }, | |
| 1029 | + { "APMC0D31", }, | |
| 1028 | 1030 | { } |
| 1029 | 1031 | }; |
| 1030 | 1032 | MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); |
| @@ -1033,6 +1035,8 @@ MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match); · 2 unmodified lines | ||
| 1033 | 1035 | #ifdef CONFIG_OF |
| 1034 | 1036 | static struct of_device_id xgene_enet_of_match[] = { |
| 1035 | 1037 | {.compatible = "apm,xgene-enet",}, |
| 1038 | + {.compatible = "apm,xgene1-sgenet",}, | |
| 1039 | + {.compatible = "apm,xgene1-xgenet",}, | |
| 1036 | 1040 | {}, |
| 1037 | 1041 | }; |
| 1038 | 1042 | |
| @@ -486,7 +486,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) · 485 unmodified lines | ||
| 486 | 486 | { |
| 487 | 487 | struct bcm_enet_priv *priv; |
| 488 | 488 | struct net_device *dev; |
| 489 | − int tx_work_done, rx_work_done; | |
| 489 | + int rx_work_done; | |
| 490 | 490 | |
| 491 | 491 | priv = container_of(napi, struct bcm_enet_priv, napi); |
| 492 | 492 | dev = priv->net_dev; |
| @@ -498,14 +498,14 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget) · 5 unmodified lines | ||
| 498 | 498 | ENETDMAC_IR, priv->tx_chan); |
| 499 | 499 | |
| 500 | 500 | /* reclaim sent skb */ |
| 501 | − tx_work_done = bcm_enet_tx_reclaim(dev, 0); | |
| 501 | + bcm_enet_tx_reclaim(dev, 0); | |
| 502 | 502 | |
| 503 | 503 | spin_lock(&priv->rx_lock); |
| 504 | 504 | rx_work_done = bcm_enet_receive_queue(dev, budget); |
| 505 | 505 | spin_unlock(&priv->rx_lock); |
| 506 | 506 | |
| 507 | − if (rx_work_done >= budget || tx_work_done > 0) { | |
| 508 | − /* rx/tx queue is not yet empty/clean */ | |
| 507 | + if (rx_work_done >= budget) { | |
| 508 | + /* rx queue is not yet empty/clean */ | |
| 509 | 509 | return rx_work_done; |
| 510 | 510 | } |
| 511 | 511 | |
| @@ -302,9 +302,6 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, · 301 unmodified lines | ||
| 302 | 302 | slot->skb = skb; |
| 303 | 303 | slot->dma_addr = dma_addr; |
| 304 | 304 | |
| 305 | − if (slot->dma_addr & 0xC0000000) | |
| 306 | − bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); | |
| 307 | − | |
| 308 | 305 | return 0; |
| 309 | 306 | } |
| 310 | 307 | |
| @@ -505,8 +502,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) · 194 unmodified lines | ||
| 505 | 502 | ring->mmio_base); |
| 506 | 503 | goto err_dma_free; |
| 507 | 504 | } |
| 508 | − if (ring->dma_base & 0xC0000000) | |
| 509 | − bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); | |
| 510 | 505 | |
| 511 | 506 | ring->unaligned = bgmac_dma_unaligned(bgmac, ring, |
| 512 | 507 | BGMAC_DMA_RING_TX); |
| @@ -536,8 +531,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac) · 23 unmodified lines | ||
| 536 | 531 | err = -ENOMEM; |
| 537 | 532 | goto err_dma_free; |
| 538 | 533 | } |
| 539 | − if (ring->dma_base & 0xC0000000) | |
| 540 | − bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); | |
| 541 | 534 | |
| 542 | 535 | ring->unaligned = bgmac_dma_unaligned(bgmac, ring, |
| 543 | 536 | BGMAC_DMA_RING_RX); |
| @@ -12722,6 +12722,9 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, · 12721 unmodified lines | ||
| 12722 | 12722 | pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, |
| 12723 | 12723 | PCICFG_VENDOR_ID_OFFSET); |
| 12724 | 12724 | |
| 12725 | + /* Set PCIe reset type to fundamental for EEH recovery */ | |
| 12726 | + pdev->needs_freset = 1; | |
| 12727 | + | |
| 12725 | 12728 | /* AER (Advanced Error reporting) configuration */ |
| 12726 | 12729 | rc = pci_enable_pcie_error_reporting(pdev); |
| 12727 | 12730 | if (!rc) |
| @@ -12766,7 +12769,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, · 38 unmodified lines | ||
| 12766 | 12769 | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | |
| 12767 | 12770 | NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO | |
| 12768 | 12771 | NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX; |
| 12769 | − if (!CHIP_IS_E1x(bp)) { | |
| 12772 | + if (!chip_is_e1x) { | |
| 12770 | 12773 | dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL | |
| 12771 | 12774 | NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT; |
| 12772 | 12775 | dev->hw_enc_features = |
| @@ -73,15 +73,17 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) · 72 unmodified lines | ||
| 73 | 73 | if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) |
| 74 | 74 | return -EINVAL; |
| 75 | 75 | |
| 76 | + reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); | |
| 76 | 77 | if (wol->wolopts & WAKE_MAGICSECURE) { |
| 77 | 78 | bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]), |
| 78 | 79 | UMAC_MPD_PW_MS); |
| 79 | 80 | bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]), |
| 80 | 81 | UMAC_MPD_PW_LS); |
| 81 | − reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); | |
| 82 | 82 | reg |= MPD_PW_EN; |
| 83 | − bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); | |
| 83 | + } else { | |
| 84 | + reg &= ~MPD_PW_EN; | |
| 84 | 85 | } |
| 86 | + bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); | |
| 85 | 87 | |
| 86 | 88 | /* Flag the device and relevant IRQ as wakeup capable */ |
| 87 | 89 | if (wol->wolopts) { |
| @@ -2113,17 +2113,17 @@ static const struct net_device_ops macb_netdev_ops = { · 2112 unmodified lines | ||
| 2113 | 2113 | }; |
| 2114 | 2114 | |
| 2115 | 2115 | #if defined(CONFIG_OF) |
| 2116 | −static struct macb_config pc302gem_config = { | |
| 2116 | +static const struct macb_config pc302gem_config = { | |
| 2117 | 2117 | .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, |
| 2118 | 2118 | .dma_burst_length = 16, |
| 2119 | 2119 | }; |
| 2120 | 2120 | |
| 2121 | −static struct macb_config sama5d3_config = { | |
| 2121 | +static const struct macb_config sama5d3_config = { | |
| 2122 | 2122 | .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, |
| 2123 | 2123 | .dma_burst_length = 16, |
| 2124 | 2124 | }; |
| 2125 | 2125 | |
| 2126 | −static struct macb_config sama5d4_config = { | |
| 2126 | +static const struct macb_config sama5d4_config = { | |
| 2127 | 2127 | .caps = 0, |
| 2128 | 2128 | .dma_burst_length = 4, |
| 2129 | 2129 | }; |
| @@ -2154,7 +2154,7 @@ static void macb_configure_caps(struct macb *bp) · 24 unmodified lines | ||
| 2154 | 2154 | if (bp->pdev->dev.of_node) { |
| 2155 | 2155 | match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node); |
| 2156 | 2156 | if (match && match->data) { |
| 2157 | − config = (const struct macb_config *)match->data; | |
| 2157 | + config = match->data; | |
| 2158 | 2158 | |
| 2159 | 2159 | bp->caps = config->caps; |
| 2160 | 2160 | /* |
| @@ -351,7 +351,7 @@ · 350 unmodified lines | ||
| 351 | 351 | |
| 352 | 352 | /* Bitfields in MID */ |
| 353 | 353 | #define MACB_IDNUM_OFFSET 16 |
| 354 | −#define MACB_IDNUM_SIZE 16 | |
| 354 | +#define MACB_IDNUM_SIZE 12 | |
| 355 | 355 | #define MACB_REV_OFFSET 0 |
| 356 | 356 | #define MACB_REV_SIZE 16 |
| 357 | 357 | |
| @@ -1120,7 +1120,7 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, · 1119 unmodified lines | ||
| 1120 | 1120 | } |
| 1121 | 1121 | |
| 1122 | 1122 | /* Installed successfully, update the cached header too. */ |
| 1123 | − memcpy(card_fw, fs_fw, sizeof(*card_fw)); | |
| 1123 | + *card_fw = *fs_fw; | |
| 1124 | 1124 | card_fw_usable = 1; |
| 1125 | 1125 | *reset = 0; /* already reset as part of load_fw */ |
| 1126 | 1126 | } |
| @@ -589,7 +589,7 @@ static void tulip_tx_timeout(struct net_device *dev) · 588 unmodified lines | ||
| 589 | 589 | (unsigned int)tp->rx_ring[i].buffer1, |
| 590 | 590 | (unsigned int)tp->rx_ring[i].buffer2, |
| 591 | 591 | buf[0], buf[1], buf[2]); |
| 592 | − for (j = 0; buf[j] != 0xee && j < 1600; j++) | |
| 592 | + for (j = 0; ((j < 1600) && buf[j] != 0xee); j++) | |
| 593 | 593 | if (j < 100) |
| 594 | 594 | pr_cont(" %02x", buf[j]); |
| 595 | 595 | pr_cont(" j=%d\n", j); |
| @@ -1189,13 +1189,12 @@ static void · 1188 unmodified lines | ||
| 1189 | 1189 | fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) |
| 1190 | 1190 | { |
| 1191 | 1191 | struct fec_enet_private *fep; |
| 1192 | − struct bufdesc *bdp, *bdp_t; | |
| 1192 | + struct bufdesc *bdp; | |
| 1193 | 1193 | unsigned short status; |
| 1194 | 1194 | struct sk_buff *skb; |
| 1195 | 1195 | struct fec_enet_priv_tx_q *txq; |
| 1196 | 1196 | struct netdev_queue *nq; |
| 1197 | 1197 | int index = 0; |
| 1198 | − int i, bdnum; | |
| 1199 | 1198 | int entries_free; |
| 1200 | 1199 | |
| 1201 | 1200 | fep = netdev_priv(ndev); |
| @@ -1216,29 +1215,18 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) · 14 unmodified lines | ||
| 1216 | 1215 | if (bdp == txq->cur_tx) |
| 1217 | 1216 | break; |
| 1218 | 1217 | |
| 1219 | − bdp_t = bdp; | |
| 1220 | − bdnum = 1; | |
| 1221 | − index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep); | |
| 1222 | − skb = txq->tx_skbuff[index]; | |
| 1223 | − while (!skb) { | |
| 1224 | − bdp_t = fec_enet_get_nextdesc(bdp_t, fep, queue_id); | |
| 1225 | − index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep); | |
| 1226 | − skb = txq->tx_skbuff[index]; | |
| 1227 | − bdnum++; | |
| 1228 | − } | |
| 1229 | − if (skb_shinfo(skb)->nr_frags && | |
| 1230 | − (status = bdp_t->cbd_sc) & BD_ENET_TX_READY) | |
| 1231 | − break; | |
| 1218 | + index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep); | |
| 1232 | 1219 | |
| 1233 | − for (i = 0; i < bdnum; i++) { | |
| 1234 | − if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr)) | |
| 1235 | − dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, | |
| 1236 | − bdp->cbd_datlen, DMA_TO_DEVICE); | |
| 1237 | − bdp->cbd_bufaddr = 0; | |
| 1238 | − if (i < bdnum - 1) | |
| 1239 | − bdp = fec_enet_get_nextdesc(bdp, fep, queue_id); | |
| 1240 | − } | |
| 1220 | + skb = txq->tx_skbuff[index]; | |
| 1241 | 1221 | txq->tx_skbuff[index] = NULL; |
| 1222 | + if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr)) | |
| 1223 | + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, | |
| 1224 | + bdp->cbd_datlen, DMA_TO_DEVICE); | |
| 1225 | + bdp->cbd_bufaddr = 0; | |
| 1226 | + if (!skb) { | |
| 1227 | + bdp = fec_enet_get_nextdesc(bdp, fep, queue_id); | |
| 1228 | + continue; | |
| 1229 | + } | |
| 1242 | 1230 | |
| 1243 | 1231 | /* Check for errors. */ |
| 1244 | 1232 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | |
| @@ -1479,8 +1467,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) · 234 unmodified lines | ||
| 1479 | 1467 | |
| 1480 | 1468 | vlan_packet_rcvd = true; |
| 1481 | 1469 | |
| 1482 | − skb_copy_to_linear_data_offset(skb, VLAN_HLEN, | |
| 1483 | − data, (2 * ETH_ALEN)); | |
| 1470 | + memmove(skb->data + VLAN_HLEN, data, ETH_ALEN * 2); | |
| 1484 | 1471 | skb_pull(skb, VLAN_HLEN); |
| 1485 | 1472 | } |
| 1486 | 1473 | |
| @@ -1597,7 +1584,7 @@ fec_enet_interrupt(int irq, void *dev_id) · 110 unmodified lines | ||
| 1597 | 1584 | writel(int_events, fep->hwp + FEC_IEVENT); |
| 1598 | 1585 | fec_enet_collect_events(fep, int_events); |
| 1599 | 1586 | |
| 1600 | − if (fep->work_tx || fep->work_rx) { | |
| 1587 | + if ((fep->work_tx || fep->work_rx) && fep->link) { | |
| 1601 | 1588 | ret = IRQ_HANDLED; |
| 1602 | 1589 | |
| 1603 | 1590 | if (napi_schedule_prep(&fep->napi)) { |
| @@ -3383,7 +3370,6 @@ fec_drv_remove(struct platform_device *pdev) · 1779 unmodified lines | ||
| 3383 | 3370 | regulator_disable(fep->reg_phy); |
| 3384 | 3371 | if (fep->ptp_clock) |
| 3385 | 3372 | ptp_clock_unregister(fep->ptp_clock); |
| 3386 | − fec_enet_clk_enable(ndev, false); | |
| 3387 | 3373 | of_node_put(fep->phy_node); |
| 3388 | 3374 | free_netdev(ndev); |
| 3389 | 3375 | |
| @@ -747,6 +747,18 @@ static int gfar_parse_group(struct device_node *np, · 746 unmodified lines | ||
| 747 | 747 | return 0; |
| 748 | 748 | } |
| 749 | 749 | |
| 750 | +static int gfar_of_group_count(struct device_node *np) | |
| 751 | +{ | |
| 752 | + struct device_node *child; | |
| 753 | + int num = 0; | |
| 754 | + | |
| 755 | + for_each_available_child_of_node(np, child) | |
| 756 | + if (!of_node_cmp(child->name, "queue-group")) | |
| 757 | + num++; | |
| 758 | + | |
| 759 | + return num; | |
| 760 | +} | |
| 761 | + | |
| 750 | 762 | static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) |
| 751 | 763 | { |
| 752 | 764 | const char *model; |
| @@ -784,7 +796,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) · 31 unmodified lines | ||
| 784 | 796 | num_rx_qs = 1; |
| 785 | 797 | } else { /* MQ_MG_MODE */ |
| 786 | 798 | /* get the actual number of supported groups */ |
| 787 | − unsigned int num_grps = of_get_available_child_count(np); | |
| 799 | + unsigned int num_grps = gfar_of_group_count(np); | |
| 788 | 800 | |
| 789 | 801 | if (num_grps == 0 || num_grps > MAXGROUPS) { |
| 790 | 802 | dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n", |
| @@ -851,7 +863,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) · 60 unmodified lines | ||
| 851 | 863 | |
| 852 | 864 | /* Parse and initialize group specific information */ |
| 853 | 865 | if (priv->mode == MQ_MG_MODE) { |
| 854 | − for_each_child_of_node(np, child) { | |
| 866 | + for_each_available_child_of_node(np, child) { | |
| 867 | + if (of_node_cmp(child->name, "queue-group")) | |
| 868 | + continue; | |
| 869 | + | |
| 855 | 870 | err = gfar_parse_group(child, priv, model); |
| 856 | 871 | if (err) |
| 857 | 872 | goto err_grp_init; |
| @@ -1136,6 +1136,8 @@ restart_poll: · 1135 unmodified lines | ||
| 1136 | 1136 | ibmveth_replenish_task(adapter); |
| 1137 | 1137 | |
| 1138 | 1138 | if (frames_processed < budget) { |
| 1139 | + napi_complete(napi); | |
| 1140 | + | |
| 1139 | 1141 | /* We think we are done - reenable interrupts, |
| 1140 | 1142 | * then check once more to make sure we are done. |
| 1141 | 1143 | */ |
| @@ -1144,8 +1146,6 @@ restart_poll: · 2 unmodified lines | ||
| 1144 | 1146 | |
| 1145 | 1147 | BUG_ON(lpar_rc != H_SUCCESS); |
| 1146 | 1148 | |
| 1147 | − napi_complete(napi); | |
| 1148 | − | |
| 1149 | 1149 | if (ibmveth_rxq_pending_buffer(adapter) && |
| 1150 | 1150 | napi_reschedule(napi)) { |
| 1151 | 1151 | lpar_rc = h_vio_signal(adapter->vdev->unit_address, |
| @@ -1698,8 +1698,6 @@ int mlx4_en_start_port(struct net_device *dev) · 1697 unmodified lines | ||
| 1698 | 1698 | /* Schedule multicast task to populate multicast list */ |
| 1699 | 1699 | queue_work(mdev->workqueue, &priv->rx_mode_task); |
| 1700 | 1700 | |
| 1701 | − mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); | |
| 1702 | − | |
| 1703 | 1701 | #ifdef CONFIG_MLX4_EN_VXLAN |
| 1704 | 1702 | if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
| 1705 | 1703 | vxlan_get_rx_port(dev); |
| @@ -2853,6 +2851,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, · 1147 unmodified lines | ||
| 2853 | 2851 | queue_delayed_work(mdev->workqueue, &priv->service_task, |
| 2854 | 2852 | SERVICE_TASK_DELAY); |
| 2855 | 2853 | |
| 2854 | + mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); | |
| 2855 | + | |
| 2856 | 2856 | return 0; |
| 2857 | 2857 | |
| 2858 | 2858 | out: |
| @@ -453,7 +453,7 @@ struct mlx4_en_port_stats { · 452 unmodified lines | ||
| 453 | 453 | unsigned long rx_chksum_none; |
| 454 | 454 | unsigned long rx_chksum_complete; |
| 455 | 455 | unsigned long tx_chksum_offload; |
| 456 | −#define NUM_PORT_STATS 9 | |
| 456 | +#define NUM_PORT_STATS 10 | |
| 457 | 457 | }; |
| 458 | 458 | |
| 459 | 459 | struct mlx4_en_perf_stats { |
| @@ -92,6 +92,7 @@ static const char version[] = · 91 unmodified lines | ||
| 92 | 92 | #include "smc91x.h" |
| 93 | 93 | |
| 94 | 94 | #if defined(CONFIG_ASSABET_NEPONSET) |
| 95 | +#include <mach/assabet.h> | |
| 95 | 96 | #include <mach/neponset.h> |
| 96 | 97 | #endif |
| 97 | 98 | |
| @@ -2247,10 +2248,9 @@ static int smc_drv_probe(struct platform_device *pdev) · 2149 unmodified lines | ||
| 2247 | 2248 | const struct of_device_id *match = NULL; |
| 2248 | 2249 | struct smc_local *lp; |
| 2249 | 2250 | struct net_device *ndev; |
| 2250 | − struct resource *res; | |
| 2251 | + struct resource *res, *ires; | |
| 2251 | 2252 | unsigned int __iomem *addr; |
| 2252 | 2253 | unsigned long irq_flags = SMC_IRQ_FLAGS; |
| 2253 | − unsigned long irq_resflags; | |
| 2254 | 2254 | int ret; |
| 2255 | 2255 | |
| 2256 | 2256 | ndev = alloc_etherdev(sizeof(struct smc_local)); |
| @@ -2342,19 +2342,16 @@ static int smc_drv_probe(struct platform_device *pdev) · 85 unmodified lines | ||
| 2342 | 2342 | goto out_free_netdev; |
| 2343 | 2343 | } |
| 2344 | 2344 | |
| 2345 | − ndev->irq = platform_get_irq(pdev, 0); | |
| 2346 | − if (ndev->irq <= 0) { | |
| 2345 | + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
| 2346 | + if (!ires) { | |
| 2347 | 2347 | ret = -ENODEV; |
| 2348 | 2348 | goto out_release_io; |
| 2349 | 2349 | } |
| 2350 | − /* | |
| 2351 | − * If this platform does not specify any special irqflags, or if | |
| 2352 | − * the resource supplies a trigger, override the irqflags with | |
| 2353 | − * the trigger flags from the resource. | |
| 2354 | − */ | |
| 2355 | − irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq)); | |
| 2356 | − if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK) | |
| 2357 | − irq_flags = irq_resflags & IRQF_TRIGGER_MASK; | |
| 2350 | + | |
| 2351 | + ndev->irq = ires->start; | |
| 2352 | + | |
| 2353 | + if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) | |
| 2354 | + irq_flags = ires->flags & IRQF_TRIGGER_MASK; | |
| 2358 | 2355 | |
| 2359 | 2356 | ret = smc_request_attrib(pdev, ndev); |
| 2360 | 2357 | if (ret) |
| @@ -272,6 +272,37 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) · 271 unmodified lines | ||
| 272 | 272 | struct stmmac_priv *priv = NULL; |
| 273 | 273 | struct plat_stmmacenet_data *plat_dat = NULL; |
| 274 | 274 | const char *mac = NULL; |
| 275 | + int irq, wol_irq, lpi_irq; | |
| 276 | + | |
| 277 | + /* Get IRQ information early to have an ability to ask for deferred | |
| 278 | + * probe if needed before we went too far with resource allocation. | |
| 279 | + */ | |
| 280 | + irq = platform_get_irq_byname(pdev, "macirq"); | |
| 281 | + if (irq < 0) { | |
| 282 | + if (irq != -EPROBE_DEFER) { | |
| 283 | + dev_err(dev, | |
| 284 | + "MAC IRQ configuration information not found\n"); | |
| 285 | + } | |
| 286 | + return irq; | |
| 287 | + } | |
| 288 | + | |
| 289 | + /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq | |
| 290 | + * The external wake up irq can be passed through the platform code | |
| 291 | + * named as "eth_wake_irq" | |
| 292 | + * | |
| 293 | + * In case the wake up interrupt is not passed from the platform | |
| 294 | + * so the driver will continue to use the mac irq (ndev->irq) | |
| 295 | + */ | |
| 296 | + wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); | |
| 297 | + if (wol_irq < 0) { | |
| 298 | + if (wol_irq == -EPROBE_DEFER) | |
| 299 | + return -EPROBE_DEFER; | |
| 300 | + wol_irq = irq; | |
| 301 | + } | |
| 302 | + | |
| 303 | + lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); | |
| 304 | + if (lpi_irq == -EPROBE_DEFER) | |
| 305 | + return -EPROBE_DEFER; | |
| 275 | 306 | |
| 276 | 307 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 277 | 308 | addr = devm_ioremap_resource(dev, res); |
| @@ -323,39 +354,15 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) · 45 unmodified lines | ||
| 323 | 354 | return PTR_ERR(priv); |
| 324 | 355 | } |
| 325 | 356 | |
| 357 | + /* Copy IRQ values to priv structure which is now avaialble */ | |
| 358 | + priv->dev->irq = irq; | |
| 359 | + priv->wol_irq = wol_irq; | |
| 360 | + priv->lpi_irq = lpi_irq; | |
| 361 | + | |
| 326 | 362 | /* Get MAC address if available (DT) */ |
| 327 | 363 | if (mac) |
| 328 | 364 | memcpy(priv->dev->dev_addr, mac, ETH_ALEN); |
| 329 | 365 | |
| 330 | − /* Get the MAC information */ | |
| 331 | − priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); | |
| 332 | − if (priv->dev->irq < 0) { | |
| 333 | − if (priv->dev->irq != -EPROBE_DEFER) { | |
| 334 | − netdev_err(priv->dev, | |
| 335 | − "MAC IRQ configuration information not found\n"); | |
| 336 | − } | |
| 337 | − return priv->dev->irq; | |
| 338 | − } | |
| 339 | − | |
| 340 | − /* | |
| 341 | − * On some platforms e.g. SPEAr the wake up irq differs from the mac irq | |
| 342 | − * The external wake up irq can be passed through the platform code | |
| 343 | − * named as "eth_wake_irq" | |
| 344 | − * | |
| 345 | − * In case the wake up interrupt is not passed from the platform | |
| 346 | − * so the driver will continue to use the mac irq (ndev->irq) | |
| 347 | − */ | |
| 348 | − priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); | |
| 349 | − if (priv->wol_irq < 0) { | |
| 350 | − if (priv->wol_irq == -EPROBE_DEFER) | |
| 351 | − return -EPROBE_DEFER; | |
| 352 | − priv->wol_irq = priv->dev->irq; | |
| 353 | − } | |
| 354 | − | |
| 355 | − priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); | |
| 356 | − if (priv->lpi_irq == -EPROBE_DEFER) | |
| 357 | − return -EPROBE_DEFER; | |
| 358 | − | |
| 359 | 366 | platform_set_drvdata(pdev, priv->dev); |
| 360 | 367 | |
| 361 | 368 | pr_debug("STMMAC platform driver registration completed"); |
| @@ -498,9 +498,9 @@ static int w5100_napi_poll(struct napi_struct *napi, int budget) · 497 unmodified lines | ||
| 498 | 498 | } |
| 499 | 499 | |
| 500 | 500 | if (rx_count < budget) { |
| 501 | + napi_complete(napi); | |
| 501 | 502 | w5100_write(priv, W5100_IMR, IR_S0); |
| 502 | 503 | mmiowb(); |
| 503 | − napi_complete(napi); | |
| 504 | 504 | } |
| 505 | 505 | |
| 506 | 506 | return rx_count; |
| @@ -418,9 +418,9 @@ static int w5300_napi_poll(struct napi_struct *napi, int budget) · 417 unmodified lines | ||
| 418 | 418 | } |
| 419 | 419 | |
| 420 | 420 | if (rx_count < budget) { |
| 421 | + napi_complete(napi); | |
| 421 | 422 | w5300_write(priv, W5300_IMR, IR_S0); |
| 422 | 423 | mmiowb(); |
| 423 | − napi_complete(napi); | |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | 426 | return rx_count; |
| @@ -1730,11 +1730,11 @@ static int team_set_mac_address(struct net_device *dev, void *p) · 1729 unmodified lines | ||
| 1730 | 1730 | if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data)) |
| 1731 | 1731 | return -EADDRNOTAVAIL; |
| 1732 | 1732 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
| 1733 | − rcu_read_lock(); | |
| 1734 | − list_for_each_entry_rcu(port, &team->port_list, list) | |
| 1733 | + mutex_lock(&team->lock); | |
| 1734 | + list_for_each_entry(port, &team->port_list, list) | |
| 1735 | 1735 | if (team->ops.port_change_dev_addr) |
| 1736 | 1736 | team->ops.port_change_dev_addr(team, port); |
| 1737 | − rcu_read_unlock(); | |
| 1737 | + mutex_unlock(&team->lock); | |
| 1738 | 1738 | return 0; |
| 1739 | 1739 | } |
| 1740 | 1740 | |
| @@ -300,9 +300,18 @@ static const struct driver_info cx82310_info = { · 299 unmodified lines | ||
| 300 | 300 | .tx_fixup = cx82310_tx_fixup, |
| 301 | 301 | }; |
| 302 | 302 | |
| 303 | +#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \ | |
| 304 | + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ | |
| 305 | + USB_DEVICE_ID_MATCH_DEV_INFO, \ | |
| 306 | + .idVendor = (vend), \ | |
| 307 | + .idProduct = (prod), \ | |
| 308 | + .bDeviceClass = (cl), \ | |
| 309 | + .bDeviceSubClass = (sc), \ | |
| 310 | + .bDeviceProtocol = (pr) | |
| 311 | + | |
| 303 | 312 | static const struct usb_device_id products[] = { |
| 304 | 313 | { |
| 305 | − USB_DEVICE_AND_INTERFACE_INFO(0x0572, 0xcb01, 0xff, 0, 0), | |
| 314 | + USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0), | |
| 306 | 315 | .driver_info = (unsigned long) &cx82310_info |
| 307 | 316 | }, |
| 308 | 317 | { }, |
| @@ -1448,8 +1448,10 @@ static void virtnet_free_queues(struct virtnet_info *vi) · 1447 unmodified lines | ||
| 1448 | 1448 | { |
| 1449 | 1449 | int i; |
| 1450 | 1450 | |
| 1451 | − for (i = 0; i < vi->max_queue_pairs; i++) | |
| 1451 | + for (i = 0; i < vi->max_queue_pairs; i++) { | |
| 1452 | + napi_hash_del(&vi->rq[i].napi); | |
| 1452 | 1453 | netif_napi_del(&vi->rq[i].napi); |
| 1454 | + } | |
| 1453 | 1455 | |
| 1454 | 1456 | kfree(vi->rq); |
| 1455 | 1457 | kfree(vi->sq); |
| @@ -1948,11 +1950,8 @@ static int virtnet_freeze(struct virtio_device *vdev) · 492 unmodified lines | ||
| 1948 | 1950 | cancel_delayed_work_sync(&vi->refill); |
| 1949 | 1951 | |
| 1950 | 1952 | if (netif_running(vi->dev)) { |
| 1951 | − for (i = 0; i < vi->max_queue_pairs; i++) { | |
| 1953 | + for (i = 0; i < vi->max_queue_pairs; i++) | |
| 1952 | 1954 | napi_disable(&vi->rq[i].napi); |
| 1953 | − napi_hash_del(&vi->rq[i].napi); | |
| 1954 | − netif_napi_del(&vi->rq[i].napi); | |
| 1955 | − } | |
| 1956 | 1955 | } |
| 1957 | 1956 | |
| 1958 | 1957 | remove_vq_common(vi); |
| @@ -1218,7 +1218,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 1217 unmodified lines | ||
| 1218 | 1218 | goto drop; |
| 1219 | 1219 | |
| 1220 | 1220 | flags &= ~VXLAN_HF_RCO; |
| 1221 | − vni &= VXLAN_VID_MASK; | |
| 1221 | + vni &= VXLAN_VNI_MASK; | |
| 1222 | 1222 | } |
| 1223 | 1223 | |
| 1224 | 1224 | /* For backwards compatibility, only allow reserved fields to be |
| @@ -1239,7 +1239,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 14 unmodified lines | ||
| 1239 | 1239 | flags &= ~VXLAN_GBP_USED_BITS; |
| 1240 | 1240 | } |
| 1241 | 1241 | |
| 1242 | − if (flags || (vni & ~VXLAN_VID_MASK)) { | |
| 1242 | + if (flags || vni & ~VXLAN_VNI_MASK) { | |
| 1243 | 1243 | /* If there are any unprocessed flags remaining treat |
| 1244 | 1244 | * this as a malformed packet. This behavior diverges from |
| 1245 | 1245 | * VXLAN RFC (RFC7348) which stipulates that bits in reserved |
| @@ -5370,6 +5370,7 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy, · 5369 unmodified lines | ||
| 5370 | 5370 | case 0x432a: /* BCM4321 */ |
| 5371 | 5371 | case 0x432d: /* BCM4322 */ |
| 5372 | 5372 | case 0x4352: /* BCM43222 */ |
| 5373 | + case 0x435a: /* BCM43228 */ | |
| 5373 | 5374 | case 0x4333: /* BCM4331 */ |
| 5374 | 5375 | case 0x43a2: /* BCM4360 */ |
| 5375 | 5376 | case 0x43b3: /* BCM4352 */ |
| @@ -39,13 +39,22 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy, · 38 unmodified lines | ||
| 39 | 39 | void *dcmd_buf = NULL, *wr_pointer; |
| 40 | 40 | u16 msglen, maxmsglen = PAGE_SIZE - 0x100; |
| 41 | 41 | |
| 42 | − brcmf_dbg(TRACE, "cmd %x set %d len %d\n", cmdhdr->cmd, cmdhdr->set, | |
| 43 | − cmdhdr->len); | |
| 42 | + if (len < sizeof(*cmdhdr)) { | |
| 43 | + brcmf_err("vendor command too short: %d\n", len); | |
| 44 | + return -EINVAL; | |
| 45 | + } | |
| 44 | 46 | |
| 45 | 47 | vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); |
| 46 | 48 | ifp = vif->ifp; |
| 47 | 49 | |
| 48 | − len -= sizeof(struct brcmf_vndr_dcmd_hdr); | |
| 50 | + brcmf_dbg(TRACE, "ifidx=%d, cmd=%d\n", ifp->ifidx, cmdhdr->cmd); | |
| 51 | + | |
| 52 | + if (cmdhdr->offset > len) { | |
| 53 | + brcmf_err("bad buffer offset %d > %d\n", cmdhdr->offset, len); | |
| 54 | + return -EINVAL; | |
| 55 | + } | |
| 56 | + | |
| 57 | + len -= cmdhdr->offset; | |
| 49 | 58 | ret_len = cmdhdr->len; |
| 50 | 59 | if (ret_len > 0 || len > 0) { |
| 51 | 60 | if (len > BRCMF_DCMD_MAXLEN) { |
| @@ -95,7 +95,8 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = { · 94 unmodified lines | ||
| 95 | 95 | .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
| 96 | 96 | .base_params = &iwl1000_base_params, \ |
| 97 | 97 | .eeprom_params = &iwl1000_eeprom_params, \ |
| 98 | − .led_mode = IWL_LED_BLINK | |
| 98 | + .led_mode = IWL_LED_BLINK, \ | |
| 99 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 99 | 100 | |
| 100 | 101 | const struct iwl_cfg iwl1000_bgn_cfg = { |
| 101 | 102 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", |
| @@ -121,7 +122,8 @@ const struct iwl_cfg iwl1000_bg_cfg = { · 19 unmodified lines | ||
| 121 | 122 | .base_params = &iwl1000_base_params, \ |
| 122 | 123 | .eeprom_params = &iwl1000_eeprom_params, \ |
| 123 | 124 | .led_mode = IWL_LED_RF_STATE, \ |
| 124 | − .rx_with_siso_diversity = true | |
| 125 | + .rx_with_siso_diversity = true, \ | |
| 126 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 125 | 127 | |
| 126 | 128 | const struct iwl_cfg iwl100_bgn_cfg = { |
| 127 | 129 | .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", |
| @@ -123,7 +123,9 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = { · 122 unmodified lines | ||
| 123 | 123 | .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
| 124 | 124 | .base_params = &iwl2000_base_params, \ |
| 125 | 125 | .eeprom_params = &iwl20x0_eeprom_params, \ |
| 126 | − .led_mode = IWL_LED_RF_STATE | |
| 126 | + .led_mode = IWL_LED_RF_STATE, \ | |
| 127 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 128 | + | |
| 127 | 129 | |
| 128 | 130 | const struct iwl_cfg iwl2000_2bgn_cfg = { |
| 129 | 131 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", |
| @@ -149,7 +151,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { · 19 unmodified lines | ||
| 149 | 151 | .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
| 150 | 152 | .base_params = &iwl2030_base_params, \ |
| 151 | 153 | .eeprom_params = &iwl20x0_eeprom_params, \ |
| 152 | − .led_mode = IWL_LED_RF_STATE | |
| 154 | + .led_mode = IWL_LED_RF_STATE, \ | |
| 155 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 153 | 156 | |
| 154 | 157 | const struct iwl_cfg iwl2030_2bgn_cfg = { |
| 155 | 158 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", |
| @@ -170,7 +173,8 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { · 14 unmodified lines | ||
| 170 | 173 | .base_params = &iwl2000_base_params, \ |
| 171 | 174 | .eeprom_params = &iwl20x0_eeprom_params, \ |
| 172 | 175 | .led_mode = IWL_LED_RF_STATE, \ |
| 173 | − .rx_with_siso_diversity = true | |
| 176 | + .rx_with_siso_diversity = true, \ | |
| 177 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 174 | 178 | |
| 175 | 179 | const struct iwl_cfg iwl105_bgn_cfg = { |
| 176 | 180 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", |
| @@ -197,7 +201,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { · 20 unmodified lines | ||
| 197 | 201 | .base_params = &iwl2030_base_params, \ |
| 198 | 202 | .eeprom_params = &iwl20x0_eeprom_params, \ |
| 199 | 203 | .led_mode = IWL_LED_RF_STATE, \ |
| 200 | − .rx_with_siso_diversity = true | |
| 204 | + .rx_with_siso_diversity = true, \ | |
| 205 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 201 | 206 | |
| 202 | 207 | const struct iwl_cfg iwl135_bgn_cfg = { |
| 203 | 208 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", |
| @@ -93,7 +93,8 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = { · 92 unmodified lines | ||
| 93 | 93 | .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ |
| 94 | 94 | .base_params = &iwl5000_base_params, \ |
| 95 | 95 | .eeprom_params = &iwl5000_eeprom_params, \ |
| 96 | − .led_mode = IWL_LED_BLINK | |
| 96 | + .led_mode = IWL_LED_BLINK, \ | |
| 97 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 97 | 98 | |
| 98 | 99 | const struct iwl_cfg iwl5300_agn_cfg = { |
| 99 | 100 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", |
| @@ -158,7 +159,8 @@ const struct iwl_cfg iwl5350_agn_cfg = { · 58 unmodified lines | ||
| 158 | 159 | .base_params = &iwl5000_base_params, \ |
| 159 | 160 | .eeprom_params = &iwl5000_eeprom_params, \ |
| 160 | 161 | .led_mode = IWL_LED_BLINK, \ |
| 161 | − .internal_wimax_coex = true | |
| 162 | + .internal_wimax_coex = true, \ | |
| 163 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 162 | 164 | |
| 163 | 165 | const struct iwl_cfg iwl5150_agn_cfg = { |
| 164 | 166 | .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", |
| @@ -145,7 +145,8 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = { · 144 unmodified lines | ||
| 145 | 145 | .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
| 146 | 146 | .base_params = &iwl6000_g2_base_params, \ |
| 147 | 147 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 148 | − .led_mode = IWL_LED_RF_STATE | |
| 148 | + .led_mode = IWL_LED_RF_STATE, \ | |
| 149 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 149 | 150 | |
| 150 | 151 | const struct iwl_cfg iwl6005_2agn_cfg = { |
| 151 | 152 | .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", |
| @@ -199,7 +200,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { · 47 unmodified lines | ||
| 199 | 200 | .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
| 200 | 201 | .base_params = &iwl6000_g2_base_params, \ |
| 201 | 202 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 202 | − .led_mode = IWL_LED_RF_STATE | |
| 203 | + .led_mode = IWL_LED_RF_STATE, \ | |
| 204 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 203 | 205 | |
| 204 | 206 | const struct iwl_cfg iwl6030_2agn_cfg = { |
| 205 | 207 | .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", |
| @@ -235,7 +237,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = { · 29 unmodified lines | ||
| 235 | 237 | .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
| 236 | 238 | .base_params = &iwl6000_g2_base_params, \ |
| 237 | 239 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 238 | − .led_mode = IWL_LED_RF_STATE | |
| 240 | + .led_mode = IWL_LED_RF_STATE, \ | |
| 241 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 239 | 242 | |
| 240 | 243 | const struct iwl_cfg iwl6035_2agn_cfg = { |
| 241 | 244 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", |
| @@ -290,7 +293,8 @@ const struct iwl_cfg iwl130_bg_cfg = { · 48 unmodified lines | ||
| 290 | 293 | .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
| 291 | 294 | .base_params = &iwl6000_base_params, \ |
| 292 | 295 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 293 | − .led_mode = IWL_LED_BLINK | |
| 296 | + .led_mode = IWL_LED_BLINK, \ | |
| 297 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 294 | 298 | |
| 295 | 299 | const struct iwl_cfg iwl6000i_2agn_cfg = { |
| 296 | 300 | .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", |
| @@ -322,7 +326,8 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { · 25 unmodified lines | ||
| 322 | 326 | .base_params = &iwl6050_base_params, \ |
| 323 | 327 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 324 | 328 | .led_mode = IWL_LED_BLINK, \ |
| 325 | − .internal_wimax_coex = true | |
| 329 | + .internal_wimax_coex = true, \ | |
| 330 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 326 | 331 | |
| 327 | 332 | const struct iwl_cfg iwl6050_2agn_cfg = { |
| 328 | 333 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", |
| @@ -347,7 +352,8 @@ const struct iwl_cfg iwl6050_2abg_cfg = { · 18 unmodified lines | ||
| 347 | 352 | .base_params = &iwl6050_base_params, \ |
| 348 | 353 | .eeprom_params = &iwl6000_eeprom_params, \ |
| 349 | 354 | .led_mode = IWL_LED_BLINK, \ |
| 350 | − .internal_wimax_coex = true | |
| 355 | + .internal_wimax_coex = true, \ | |
| 356 | + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K | |
| 351 | 357 | |
| 352 | 358 | const struct iwl_cfg iwl6150_bgn_cfg = { |
| 353 | 359 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", |
| @@ -793,7 +793,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, · 792 unmodified lines | ||
| 793 | 793 | if (!vif->bss_conf.assoc) |
| 794 | 794 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
| 795 | 795 | |
| 796 | − if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, | |
| 796 | + if (mvmvif->phy_ctxt && | |
| 797 | + IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status, | |
| 797 | 798 | mvmvif->phy_ctxt->id)) |
| 798 | 799 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
| 799 | 800 | |
| @@ -832,7 +832,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, · 831 unmodified lines | ||
| 832 | 832 | if (!vif->bss_conf.assoc) |
| 833 | 833 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
| 834 | 834 | |
| 835 | − if (data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) | |
| 835 | + if (mvmvif->phy_ctxt && | |
| 836 | + data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id)) | |
| 836 | 837 | smps_mode = IEEE80211_SMPS_AUTOMATIC; |
| 837 | 838 | |
| 838 | 839 | IWL_DEBUG_COEX(data->mvm, |
| @@ -405,7 +405,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) · 404 unmodified lines | ||
| 405 | 405 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
| 406 | 406 | &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; |
| 407 | 407 | |
| 408 | − if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER) | |
| 408 | + if ((mvm->fw->ucode_capa.capa[0] & | |
| 409 | + IWL_UCODE_TLV_CAPA_BEAMFORMER) && | |
| 410 | + (mvm->fw->ucode_capa.api[0] & | |
| 411 | + IWL_UCODE_TLV_API_LQ_SS_PARAMS)) | |
| 409 | 412 | hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |= |
| 410 | 413 | IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; |
| 411 | 414 | } |
| @@ -2215,7 +2218,19 @@ static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw, · 1803 unmodified lines | ||
| 2215 | 2218 | |
| 2216 | 2219 | mutex_lock(&mvm->mutex); |
| 2217 | 2220 | |
| 2218 | − iwl_mvm_cancel_scan(mvm); | |
| 2221 | + /* Due to a race condition, it's possible that mac80211 asks | |
| 2222 | + * us to stop a hw_scan when it's already stopped. This can | |
| 2223 | + * happen, for instance, if we stopped the scan ourselves, | |
| 2224 | + * called ieee80211_scan_completed() and the userspace called | |
| 2225 | + * cancel scan scan before ieee80211_scan_work() could run. | |
| 2226 | + * To handle that, simply return if the scan is not running. | |
| 2227 | + */ | |
| 2228 | + /* FIXME: for now, we ignore this race for UMAC scans, since | |
| 2229 | + * they don't set the scan_status. | |
| 2230 | + */ | |
| 2231 | + if ((mvm->scan_status == IWL_MVM_SCAN_OS) || | |
| 2232 | + (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) | |
| 2233 | + iwl_mvm_cancel_scan(mvm); | |
| 2219 | 2234 | |
| 2220 | 2235 | mutex_unlock(&mvm->mutex); |
| 2221 | 2236 | } |
| @@ -2559,12 +2574,29 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, · 337 unmodified lines | ||
| 2559 | 2574 | int ret; |
| 2560 | 2575 | |
| 2561 | 2576 | mutex_lock(&mvm->mutex); |
| 2577 | + | |
| 2578 | + /* Due to a race condition, it's possible that mac80211 asks | |
| 2579 | + * us to stop a sched_scan when it's already stopped. This | |
| 2580 | + * can happen, for instance, if we stopped the scan ourselves, | |
| 2581 | + * called ieee80211_sched_scan_stopped() and the userspace called | |
| 2582 | + * stop sched scan scan before ieee80211_sched_scan_stopped_work() | |
| 2583 | + * could run. To handle this, simply return if the scan is | |
| 2584 | + * not running. | |
| 2585 | + */ | |
| 2586 | + /* FIXME: for now, we ignore this race for UMAC scans, since | |
| 2587 | + * they don't set the scan_status. | |
| 2588 | + */ | |
| 2589 | + if (mvm->scan_status != IWL_MVM_SCAN_SCHED && | |
| 2590 | + !(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { | |
| 2591 | + mutex_unlock(&mvm->mutex); | |
| 2592 | + return 0; | |
| 2593 | + } | |
| 2594 | + | |
| 2562 | 2595 | ret = iwl_mvm_scan_offload_stop(mvm, false); |
| 2563 | 2596 | mutex_unlock(&mvm->mutex); |
| 2564 | 2597 | iwl_mvm_wait_for_async_handlers(mvm); |
| 2565 | 2598 | |
| 2566 | 2599 | return ret; |
| 2567 | − | |
| 2568 | 2600 | } |
| 2569 | 2601 | |
| 2570 | 2602 | static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, |
| @@ -134,9 +134,12 @@ enum rs_column_mode { · 133 unmodified lines | ||
| 134 | 134 | #define MAX_NEXT_COLUMNS 7 |
| 135 | 135 | #define MAX_COLUMN_CHECKS 3 |
| 136 | 136 | |
| 137 | +struct rs_tx_column; | |
| 138 | + | |
| 137 | 139 | typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, |
| 138 | 140 | struct ieee80211_sta *sta, |
| 139 | − struct iwl_scale_tbl_info *tbl); | |
| 141 | + struct iwl_scale_tbl_info *tbl, | |
| 142 | + const struct rs_tx_column *next_col); | |
| 140 | 143 | |
| 141 | 144 | struct rs_tx_column { |
| 142 | 145 | enum rs_column_mode mode; |
| @@ -147,13 +150,15 @@ struct rs_tx_column { · 4 unmodified lines | ||
| 147 | 150 | }; |
| 148 | 151 | |
| 149 | 152 | static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
| 150 | − struct iwl_scale_tbl_info *tbl) | |
| 153 | + struct iwl_scale_tbl_info *tbl, | |
| 154 | + const struct rs_tx_column *next_col) | |
| 151 | 155 | { |
| 152 | − return iwl_mvm_bt_coex_is_ant_avail(mvm, tbl->rate.ant); | |
| 156 | + return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant); | |
| 153 | 157 | } |
| 154 | 158 | |
| 155 | 159 | static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
| 156 | − struct iwl_scale_tbl_info *tbl) | |
| 160 | + struct iwl_scale_tbl_info *tbl, | |
| 161 | + const struct rs_tx_column *next_col) | |
| 157 | 162 | { |
| 158 | 163 | if (!sta->ht_cap.ht_supported) |
| 159 | 164 | return false; |
| @@ -171,7 +176,8 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, · 11 unmodified lines | ||
| 171 | 176 | } |
| 172 | 177 | |
| 173 | 178 | static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
| 174 | − struct iwl_scale_tbl_info *tbl) | |
| 179 | + struct iwl_scale_tbl_info *tbl, | |
| 180 | + const struct rs_tx_column *next_col) | |
| 175 | 181 | { |
| 176 | 182 | if (!sta->ht_cap.ht_supported) |
| 177 | 183 | return false; |
| @@ -180,7 +186,8 @@ static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, · 2 unmodified lines | ||
| 180 | 186 | } |
| 181 | 187 | |
| 182 | 188 | static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, |
| 183 | − struct iwl_scale_tbl_info *tbl) | |
| 189 | + struct iwl_scale_tbl_info *tbl, | |
| 190 | + const struct rs_tx_column *next_col) | |
| 184 | 191 | { |
| 185 | 192 | struct rs_rate *rate = &tbl->rate; |
| 186 | 193 | struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; |
| @@ -1590,7 +1597,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm, · 1403 unmodified lines | ||
| 1590 | 1597 | |
| 1591 | 1598 | for (j = 0; j < MAX_COLUMN_CHECKS; j++) { |
| 1592 | 1599 | allow_func = next_col->checks[j]; |
| 1593 | − if (allow_func && !allow_func(mvm, sta, tbl)) | |
| 1600 | + if (allow_func && !allow_func(mvm, sta, tbl, next_col)) | |
| 1594 | 1601 | break; |
| 1595 | 1602 | } |
| 1596 | 1603 | |
| @@ -1128,8 +1128,10 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) · 1127 unmodified lines | ||
| 1128 | 1128 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) |
| 1129 | 1129 | return 0; |
| 1130 | 1130 | |
| 1131 | − if (iwl_mvm_is_radio_killed(mvm)) | |
| 1131 | + if (iwl_mvm_is_radio_killed(mvm)) { | |
| 1132 | + ret = 0; | |
| 1132 | 1133 | goto out; |
| 1134 | + } | |
| 1133 | 1135 | |
| 1134 | 1136 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && |
| 1135 | 1137 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || |
| @@ -1148,16 +1150,14 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) · 12 unmodified lines | ||
| 1148 | 1150 | IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n", |
| 1149 | 1151 | sched ? "offloaded " : "", ret); |
| 1150 | 1152 | iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); |
| 1151 | − return ret; | |
| 1153 | + goto out; | |
| 1152 | 1154 | } |
| 1153 | 1155 | |
| 1154 | 1156 | IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n", |
| 1155 | 1157 | sched ? "offloaded " : ""); |
| 1156 | 1158 | |
| 1157 | 1159 | ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); |
| 1158 | − if (ret) | |
| 1159 | − return ret; | |
| 1160 | − | |
| 1160 | +out: | |
| 1161 | 1161 | /* |
| 1162 | 1162 | * Clear the scan status so the next scan requests will succeed. This |
| 1163 | 1163 | * also ensures the Rx handler doesn't do anything, as the scan was |
| @@ -1167,7 +1167,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) · 3 unmodified lines | ||
| 1167 | 1167 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
| 1168 | 1168 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
| 1169 | 1169 | |
| 1170 | −out: | |
| 1171 | 1170 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
| 1172 | 1171 | |
| 1173 | 1172 | if (notify) { |
| @@ -1177,7 +1176,7 @@ out: · 3 unmodified lines | ||
| 1177 | 1176 | ieee80211_scan_completed(mvm->hw, true); |
| 1178 | 1177 | } |
| 1179 | 1178 | |
| 1180 | − return 0; | |
| 1179 | + return ret; | |
| 1181 | 1180 | } |
| 1182 | 1181 | |
| 1183 | 1182 | static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm, |
| @@ -750,8 +750,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) · 749 unmodified lines | ||
| 750 | 750 | * request |
| 751 | 751 | */ |
| 752 | 752 | list_for_each_entry(te_data, &mvm->time_event_list, list) { |
| 753 | − if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE && | |
| 754 | − te_data->running) { | |
| 753 | + if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { | |
| 755 | 754 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); |
| 756 | 755 | is_p2p = true; |
| 757 | 756 | goto remove_te; |
| @@ -766,10 +765,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) · 8 unmodified lines | ||
| 766 | 765 | * request |
| 767 | 766 | */ |
| 768 | 767 | list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { |
| 769 | − if (te_data->running) { | |
| 770 | − mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | |
| 771 | − goto remove_te; | |
| 772 | − } | |
| 768 | + mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | |
| 769 | + goto remove_te; | |
| 773 | 770 | } |
| 774 | 771 | |
| 775 | 772 | remove_te: |
| @@ -1386,8 +1386,11 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) · 1385 unmodified lines | ||
| 1386 | 1386 | } |
| 1387 | 1387 | |
| 1388 | 1388 | return true; |
| 1389 | − } else if (0x86DD == ether_type) { | |
| 1390 | − return true; | |
| 1389 | + } else if (ETH_P_IPV6 == ether_type) { | |
| 1390 | + /* TODO: Handle any IPv6 cases that need special handling. | |
| 1391 | + * For now, always return false | |
| 1392 | + */ | |
| 1393 | + goto end; | |
| 1391 | 1394 | } |
| 1392 | 1395 | |
| 1393 | 1396 | end: |
| @@ -340,12 +340,11 @@ static void xenvif_get_ethtool_stats(struct net_device *dev, · 339 unmodified lines | ||
| 340 | 340 | unsigned int num_queues = vif->num_queues; |
| 341 | 341 | int i; |
| 342 | 342 | unsigned int queue_index; |
| 343 | − struct xenvif_stats *vif_stats; | |
| 344 | 343 | |
| 345 | 344 | for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) { |
| 346 | 345 | unsigned long accum = 0; |
| 347 | 346 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { |
| 348 | − vif_stats = &vif->queues[queue_index].stats; | |
| 347 | + void *vif_stats = &vif->queues[queue_index].stats; | |
| 349 | 348 | accum += *(unsigned long *)(vif_stats + xenvif_stats[i].offset); |
| 350 | 349 | } |
| 351 | 350 | data[i] = accum; |
| @@ -96,6 +96,7 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 95 unmodified lines | ||
| 96 | 96 | static void make_tx_response(struct xenvif_queue *queue, |
| 97 | 97 | struct xen_netif_tx_request *txp, |
| 98 | 98 | s8 st); |
| 99 | +static void push_tx_responses(struct xenvif_queue *queue); | |
| 99 | 100 | |
| 100 | 101 | static inline int tx_work_todo(struct xenvif_queue *queue); |
| 101 | 102 | |
| @@ -655,15 +656,10 @@ static void xenvif_tx_err(struct xenvif_queue *queue, · 553 unmodified lines | ||
| 655 | 656 | unsigned long flags; |
| 656 | 657 | |
| 657 | 658 | do { |
| 658 | − int notify; | |
| 659 | − | |
| 660 | 659 | spin_lock_irqsave(&queue->response_lock, flags); |
| 661 | 660 | make_tx_response(queue, txp, XEN_NETIF_RSP_ERROR); |
| 662 | − RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | |
| 661 | + push_tx_responses(queue); | |
| 663 | 662 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 664 | − if (notify) | |
| 665 | − notify_remote_via_irq(queue->tx_irq); | |
| 666 | − | |
| 667 | 663 | if (cons == end) |
| 668 | 664 | break; |
| 669 | 665 | txp = RING_GET_REQUEST(&queue->tx, cons++); |
| @@ -1349,7 +1345,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s · 679 unmodified lines | ||
| 1349 | 1345 | { |
| 1350 | 1346 | unsigned int offset = skb_headlen(skb); |
| 1351 | 1347 | skb_frag_t frags[MAX_SKB_FRAGS]; |
| 1352 | − int i; | |
| 1348 | + int i, f; | |
| 1353 | 1349 | struct ubuf_info *uarg; |
| 1354 | 1350 | struct sk_buff *nskb = skb_shinfo(skb)->frag_list; |
| 1355 | 1351 | |
| @@ -1389,23 +1385,25 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s · 33 unmodified lines | ||
| 1389 | 1385 | frags[i].page_offset = 0; |
| 1390 | 1386 | skb_frag_size_set(&frags[i], len); |
| 1391 | 1387 | } |
| 1392 | − /* swap out with old one */ | |
| 1393 | − memcpy(skb_shinfo(skb)->frags, | |
| 1394 | − frags, | |
| 1395 | − i * sizeof(skb_frag_t)); | |
| 1396 | − skb_shinfo(skb)->nr_frags = i; | |
| 1397 | − skb->truesize += i * PAGE_SIZE; | |
| 1398 | 1388 | |
| 1399 | − /* remove traces of mapped pages and frag_list */ | |
| 1389 | + /* Copied all the bits from the frag list -- free it. */ | |
| 1400 | 1390 | skb_frag_list_init(skb); |
| 1391 | + xenvif_skb_zerocopy_prepare(queue, nskb); | |
| 1392 | + kfree_skb(nskb); | |
| 1393 | + | |
| 1394 | + /* Release all the original (foreign) frags. */ | |
| 1395 | + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) | |
| 1396 | + skb_frag_unref(skb, f); | |
| 1401 | 1397 | uarg = skb_shinfo(skb)->destructor_arg; |
| 1402 | 1398 | /* increase inflight counter to offset decrement in callback */ |
| 1403 | 1399 | atomic_inc(&queue->inflight_packets); |
| 1404 | 1400 | uarg->callback(uarg, true); |
| 1405 | 1401 | skb_shinfo(skb)->destructor_arg = NULL; |
| 1406 | 1402 | |
| 1407 | − xenvif_skb_zerocopy_prepare(queue, nskb); | |
| 1408 | − kfree_skb(nskb); | |
| 1403 | + /* Fill the skb with the new (local) frags. */ | |
| 1404 | + memcpy(skb_shinfo(skb)->frags, frags, i * sizeof(skb_frag_t)); | |
| 1405 | + skb_shinfo(skb)->nr_frags = i; | |
| 1406 | + skb->truesize += i * PAGE_SIZE; | |
| 1409 | 1407 | |
| 1410 | 1408 | return 0; |
| 1411 | 1409 | } |
| @@ -1655,7 +1653,6 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 243 unmodified lines | ||
| 1655 | 1653 | { |
| 1656 | 1654 | struct pending_tx_info *pending_tx_info; |
| 1657 | 1655 | pending_ring_idx_t index; |
| 1658 | − int notify; | |
| 1659 | 1656 | unsigned long flags; |
| 1660 | 1657 | |
| 1661 | 1658 | pending_tx_info = &queue->pending_tx_info[pending_idx]; |
| @@ -1671,12 +1668,9 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 9 unmodified lines | ||
| 1671 | 1668 | index = pending_index(queue->pending_prod++); |
| 1672 | 1669 | queue->pending_ring[index] = pending_idx; |
| 1673 | 1670 | |
| 1674 | − RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | |
| 1671 | + push_tx_responses(queue); | |
| 1675 | 1672 | |
| 1676 | 1673 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1677 | − | |
| 1678 | − if (notify) | |
| 1679 | − notify_remote_via_irq(queue->tx_irq); | |
| 1680 | 1674 | } |
| 1681 | 1675 | |
| 1682 | 1676 | |
| @@ -1697,6 +1691,15 @@ static void make_tx_response(struct xenvif_queue *queue, · 14 unmodified lines | ||
| 1697 | 1691 | queue->tx.rsp_prod_pvt = ++i; |
| 1698 | 1692 | } |
| 1699 | 1693 | |
| 1694 | +static void push_tx_responses(struct xenvif_queue *queue) | |
| 1695 | +{ | |
| 1696 | + int notify; | |
| 1697 | + | |
| 1698 | + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | |
| 1699 | + if (notify) | |
| 1700 | + notify_remote_via_irq(queue->tx_irq); | |
| 1701 | +} | |
| 1702 | + | |
| 1700 | 1703 | static struct xen_netif_rx_response *make_rx_response(struct xenvif_queue *queue, |
| 1701 | 1704 | u16 id, |
| 1702 | 1705 | s8 st, |
| @@ -84,8 +84,7 @@ config OF_RESOLVE · 83 unmodified lines | ||
| 84 | 84 | bool |
| 85 | 85 | |
| 86 | 86 | config OF_OVERLAY |
| 87 | − bool | |
| 88 | − depends on OF | |
| 87 | + bool "Device Tree overlays" | |
| 89 | 88 | select OF_DYNAMIC |
| 90 | 89 | select OF_RESOLVE |
| 91 | 90 | |
| @@ -714,16 +714,12 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent, · 713 unmodified lines | ||
| 714 | 714 | const char *path) |
| 715 | 715 | { |
| 716 | 716 | struct device_node *child; |
| 717 | − int len = strchrnul(path, '/') - path; | |
| 718 | − int term; | |
| 717 | + int len; | |
| 719 | 718 | |
| 719 | + len = strcspn(path, "/:"); | |
| 720 | 720 | if (!len) |
| 721 | 721 | return NULL; |
| 722 | 722 | |
| 723 | − term = strchrnul(path, ':') - path; | |
| 724 | − if (term < len) | |
| 725 | − len = term; | |
| 726 | − | |
| 727 | 723 | __for_each_child_of_node(parent, child) { |
| 728 | 724 | const char *name = strrchr(child->full_name, '/'); |
| 729 | 725 | if (WARN(!name, "malformed device_node %s\n", child->full_name)) |
| @@ -768,8 +764,12 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt · 38 unmodified lines | ||
| 768 | 764 | |
| 769 | 765 | /* The path could begin with an alias */ |
| 770 | 766 | if (*path != '/') { |
| 771 | − char *p = strchrnul(path, '/'); | |
| 772 | − int len = separator ? separator - path : p - path; | |
| 767 | + int len; | |
| 768 | + const char *p = separator; | |
| 769 | + | |
| 770 | + if (!p) | |
| 771 | + p = strchrnul(path, '/'); | |
| 772 | + len = p - path; | |
| 773 | 773 | |
| 774 | 774 | /* of_aliases must not be NULL */ |
| 775 | 775 | if (!of_aliases) |
| @@ -794,6 +794,8 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt · 18 unmodified lines | ||
| 794 | 794 | path++; /* Increment past '/' delimiter */ |
| 795 | 795 | np = __of_find_node_by_path(np, path); |
| 796 | 796 | path = strchrnul(path, '/'); |
| 797 | + if (separator && separator < path) | |
| 798 | + break; | |
| 797 | 799 | } |
| 798 | 800 | raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| 799 | 801 | return np; |
| @@ -290,7 +290,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar · 289 unmodified lines | ||
| 290 | 290 | struct device_node *p; |
| 291 | 291 | const __be32 *intspec, *tmp, *addr; |
| 292 | 292 | u32 intsize, intlen; |
| 293 | − int i, res = -EINVAL; | |
| 293 | + int i, res; | |
| 294 | 294 | |
| 295 | 295 | pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); |
| 296 | 296 | |
| @@ -323,15 +323,19 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar · 26 unmodified lines | ||
| 323 | 323 | |
| 324 | 324 | /* Get size of interrupt specifier */ |
| 325 | 325 | tmp = of_get_property(p, "#interrupt-cells", NULL); |
| 326 | − if (tmp == NULL) | |
| 326 | + if (tmp == NULL) { | |
| 327 | + res = -EINVAL; | |
| 327 | 328 | goto out; |
| 329 | + } | |
| 328 | 330 | intsize = be32_to_cpu(*tmp); |
| 329 | 331 | |
| 330 | 332 | pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); |
| 331 | 333 | |
| 332 | 334 | /* Check index */ |
| 333 | − if ((index + 1) * intsize > intlen) | |
| 335 | + if ((index + 1) * intsize > intlen) { | |
| 336 | + res = -EINVAL; | |
| 334 | 337 | goto out; |
| 338 | + } | |
| 335 | 339 | |
| 336 | 340 | /* Copy intspec into irq structure */ |
| 337 | 341 | intspec += index * intsize; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/string.h> |
| 20 | 20 | #include <linux/slab.h> |
| 21 | 21 | #include <linux/err.h> |
| 22 | +#include <linux/idr.h> | |
| 22 | 23 | |
| 23 | 24 | #include "of_private.h" |
| 24 | 25 | |
| @@ -85,7 +86,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, · 60 unmodified lines | ||
| 85 | 86 | struct device_node *target, struct device_node *child) |
| 86 | 87 | { |
| 87 | 88 | const char *cname; |
| 88 | − struct device_node *tchild, *grandchild; | |
| 89 | + struct device_node *tchild; | |
| 89 | 90 | int ret = 0; |
| 90 | 91 | |
| 91 | 92 | cname = kbasename(child->full_name); |
| @@ -92,6 +92,16 @@ static void __init of_selftest_find_node_by_name(void) · 91 unmodified lines | ||
| 92 | 92 | "option path test failed\n"); |
| 93 | 93 | of_node_put(np); |
| 94 | 94 | |
| 95 | + np = of_find_node_opts_by_path("/testcase-data:test/option", &options); | |
| 96 | + selftest(np && !strcmp("test/option", options), | |
| 97 | + "option path test, subcase #1 failed\n"); | |
| 98 | + of_node_put(np); | |
| 99 | + | |
| 100 | + np = of_find_node_opts_by_path("/testcase-data/testcase-device1:test/option", &options); | |
| 101 | + selftest(np && !strcmp("test/option", options), | |
| 102 | + "option path test, subcase #2 failed\n"); | |
| 103 | + of_node_put(np); | |
| 104 | + | |
| 95 | 105 | np = of_find_node_opts_by_path("/testcase-data:testoption", NULL); |
| 96 | 106 | selftest(np, "NULL option path test failed\n"); |
| 97 | 107 | of_node_put(np); |
| @@ -102,6 +112,12 @@ static void __init of_selftest_find_node_by_name(void) · 4 unmodified lines | ||
| 102 | 112 | "option alias path test failed\n"); |
| 103 | 113 | of_node_put(np); |
| 104 | 114 | |
| 115 | + np = of_find_node_opts_by_path("testcase-alias:test/alias/option", | |
| 116 | + &options); | |
| 117 | + selftest(np && !strcmp("test/alias/option", options), | |
| 118 | + "option alias path test, subcase #1 failed\n"); | |
| 119 | + of_node_put(np); | |
| 120 | + | |
| 105 | 121 | np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL); |
| 106 | 122 | selftest(np, "NULL option alias path test failed\n"); |
| 107 | 123 | of_node_put(np); |
| @@ -378,9 +394,9 @@ static void __init of_selftest_property_string(void) · 270 unmodified lines | ||
| 378 | 394 | rc = of_property_match_string(np, "phandle-list-names", "first"); |
| 379 | 395 | selftest(rc == 0, "first expected:0 got:%i\n", rc); |
| 380 | 396 | rc = of_property_match_string(np, "phandle-list-names", "second"); |
| 381 | − selftest(rc == 1, "second expected:0 got:%i\n", rc); | |
| 397 | + selftest(rc == 1, "second expected:1 got:%i\n", rc); | |
| 382 | 398 | rc = of_property_match_string(np, "phandle-list-names", "third"); |
| 383 | − selftest(rc == 2, "third expected:0 got:%i\n", rc); | |
| 399 | + selftest(rc == 2, "third expected:2 got:%i\n", rc); | |
| 384 | 400 | rc = of_property_match_string(np, "phandle-list-names", "fourth"); |
| 385 | 401 | selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc); |
| 386 | 402 | rc = of_property_match_string(np, "missing-property", "blah"); |
| @@ -478,7 +494,6 @@ static void __init of_selftest_changeset(void) · 91 unmodified lines | ||
| 478 | 494 | struct device_node *n1, *n2, *n21, *nremove, *parent, *np; |
| 479 | 495 | struct of_changeset chgset; |
| 480 | 496 | |
| 481 | − of_changeset_init(&chgset); | |
| 482 | 497 | n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1"); |
| 483 | 498 | selftest(n1, "testcase setup failure\n"); |
| 484 | 499 | n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2"); |
| @@ -979,7 +994,7 @@ static int of_path_platform_device_exists(const char *path) · 494 unmodified lines | ||
| 979 | 994 | return pdev != NULL; |
| 980 | 995 | } |
| 981 | 996 | |
| 982 | −#if IS_ENABLED(CONFIG_I2C) | |
| 997 | +#if IS_BUILTIN(CONFIG_I2C) | |
| 983 | 998 | |
| 984 | 999 | /* get the i2c client device instantiated at the path */ |
| 985 | 1000 | static struct i2c_client *of_path_to_i2c_client(const char *path) |
| @@ -1445,7 +1460,7 @@ static void of_selftest_overlay_11(void) · 459 unmodified lines | ||
| 1445 | 1460 | return; |
| 1446 | 1461 | } |
| 1447 | 1462 | |
| 1448 | −#if IS_ENABLED(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY) | |
| 1463 | +#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY) | |
| 1449 | 1464 | |
| 1450 | 1465 | struct selftest_i2c_bus_data { |
| 1451 | 1466 | struct platform_device *pdev; |
| @@ -1584,7 +1599,7 @@ static struct i2c_driver selftest_i2c_dev_driver = { · 132 unmodified lines | ||
| 1584 | 1599 | .id_table = selftest_i2c_dev_id, |
| 1585 | 1600 | }; |
| 1586 | 1601 | |
| 1587 | −#if IS_ENABLED(CONFIG_I2C_MUX) | |
| 1602 | +#if IS_BUILTIN(CONFIG_I2C_MUX) | |
| 1588 | 1603 | |
| 1589 | 1604 | struct selftest_i2c_mux_data { |
| 1590 | 1605 | int nchans; |
| @@ -1695,7 +1710,7 @@ static int of_selftest_overlay_i2c_init(void) · 104 unmodified lines | ||
| 1695 | 1710 | "could not register selftest i2c bus driver\n")) |
| 1696 | 1711 | return ret; |
| 1697 | 1712 | |
| 1698 | −#if IS_ENABLED(CONFIG_I2C_MUX) | |
| 1713 | +#if IS_BUILTIN(CONFIG_I2C_MUX) | |
| 1699 | 1714 | ret = i2c_add_driver(&selftest_i2c_mux_driver); |
| 1700 | 1715 | if (selftest(ret == 0, |
| 1701 | 1716 | "could not register selftest i2c mux driver\n")) |
| @@ -1707,7 +1722,7 @@ static int of_selftest_overlay_i2c_init(void) · 5 unmodified lines | ||
| 1707 | 1722 | |
| 1708 | 1723 | static void of_selftest_overlay_i2c_cleanup(void) |
| 1709 | 1724 | { |
| 1710 | −#if IS_ENABLED(CONFIG_I2C_MUX) | |
| 1725 | +#if IS_BUILTIN(CONFIG_I2C_MUX) | |
| 1711 | 1726 | i2c_del_driver(&selftest_i2c_mux_driver); |
| 1712 | 1727 | #endif |
| 1713 | 1728 | platform_driver_unregister(&selftest_i2c_bus_driver); |
| @@ -1814,7 +1829,7 @@ static void __init of_selftest_overlay(void) · 100 unmodified lines | ||
| 1814 | 1829 | of_selftest_overlay_10(); |
| 1815 | 1830 | of_selftest_overlay_11(); |
| 1816 | 1831 | |
| 1817 | −#if IS_ENABLED(CONFIG_I2C) | |
| 1832 | +#if IS_BUILTIN(CONFIG_I2C) | |
| 1818 | 1833 | if (selftest(of_selftest_overlay_i2c_init() == 0, "i2c init failed\n")) |
| 1819 | 1834 | goto out; |
| 1820 | 1835 | |
| @@ -127,7 +127,7 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) · 126 unmodified lines | ||
| 127 | 127 | return false; |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | −static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | |
| 130 | +static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | |
| 131 | 131 | int offset) |
| 132 | 132 | { |
| 133 | 133 | struct xgene_pcie_port *port = bus->sysdata; |
| @@ -137,7 +137,7 @@ static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, · 3 unmodified lines | ||
| 137 | 137 | return NULL; |
| 138 | 138 | |
| 139 | 139 | xgene_pcie_set_rtdid_reg(bus, devfn); |
| 140 | − return xgene_pcie_get_cfg_base(bus); | |
| 140 | + return xgene_pcie_get_cfg_base(bus) + offset; | |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | static struct pci_ops xgene_pcie_ops = { |
| @@ -521,7 +521,8 @@ static ssize_t driver_override_store(struct device *dev, · 520 unmodified lines | ||
| 521 | 521 | struct pci_dev *pdev = to_pci_dev(dev); |
| 522 | 522 | char *driver_override, *old = pdev->driver_override, *cp; |
| 523 | 523 | |
| 524 | − if (count > PATH_MAX) | |
| 524 | + /* We need to keep extra room for a newline */ | |
| 525 | + if (count >= (PAGE_SIZE - 1)) | |
| 525 | 526 | return -EINVAL; |
| 526 | 527 | |
| 527 | 528 | driver_override = kstrndup(buf, count, GFP_KERNEL); |
| @@ -549,7 +550,7 @@ static ssize_t driver_override_show(struct device *dev, · 21 unmodified lines | ||
| 549 | 550 | { |
| 550 | 551 | struct pci_dev *pdev = to_pci_dev(dev); |
| 551 | 552 | |
| 552 | − return sprintf(buf, "%s\n", pdev->driver_override); | |
| 553 | + return snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override); | |
| 553 | 554 | } |
| 554 | 555 | static DEVICE_ATTR_RW(driver_override); |
| 555 | 556 | |
| @@ -69,8 +69,7 @@ config YENTA · 68 unmodified lines | ||
| 69 | 69 | tristate "CardBus yenta-compatible bridge support" |
| 70 | 70 | depends on PCI |
| 71 | 71 | select CARDBUS if !EXPERT |
| 72 | − select PCCARD_NONSTATIC if PCMCIA != n && ISA | |
| 73 | − select PCCARD_PCI if PCMCIA !=n && !ISA | |
| 72 | + select PCCARD_NONSTATIC if PCMCIA != n | |
| 74 | 73 | ---help--- |
| 75 | 74 | This option enables support for CardBus host bridges. Virtually |
| 76 | 75 | all modern PCMCIA bridges are CardBus compatible. A "bridge" is |
| @@ -110,8 +109,7 @@ config YENTA_TOSHIBA · 33 unmodified lines | ||
| 110 | 109 | config PD6729 |
| 111 | 110 | tristate "Cirrus PD6729 compatible bridge support" |
| 112 | 111 | depends on PCMCIA && PCI |
| 113 | − select PCCARD_NONSTATIC if PCMCIA != n && ISA | |
| 114 | − select PCCARD_PCI if PCMCIA !=n && !ISA | |
| 112 | + select PCCARD_NONSTATIC | |
| 115 | 113 | help |
| 116 | 114 | This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge |
| 117 | 115 | device, found in some older laptops and PCMCIA card readers. |
| @@ -119,8 +117,7 @@ config PD6729 · 1 unmodified line | ||
| 119 | 117 | config I82092 |
| 120 | 118 | tristate "i82092 compatible bridge support" |
| 121 | 119 | depends on PCMCIA && PCI |
| 122 | − select PCCARD_NONSTATIC if PCMCIA != n && ISA | |
| 123 | − select PCCARD_PCI if PCMCIA !=n && !ISA | |
| 120 | + select PCCARD_NONSTATIC | |
| 124 | 121 | help |
| 125 | 122 | This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device, |
| 126 | 123 | found in some older laptops and more commonly in evaluation boards for the |
| @@ -291,9 +288,6 @@ config ELECTRA_CF · 164 unmodified lines | ||
| 291 | 288 | Say Y here to support the CompactFlash controller on the |
| 292 | 289 | PA Semi Electra eval board. |
| 293 | 290 | |
| 294 | −config PCCARD_PCI | |
| 295 | − bool | |
| 296 | − | |
| 297 | 291 | config PCCARD_NONSTATIC |
| 298 | 292 | bool |
| 299 | 293 | |
| @@ -12,7 +12,6 @@ obj-$(CONFIG_PCMCIA) += pcmcia.o · 11 unmodified lines | ||
| 12 | 12 | pcmcia_rsrc-y += rsrc_mgr.o |
| 13 | 13 | pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o |
| 14 | 14 | pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o |
| 15 | −pcmcia_rsrc-$(CONFIG_PCCARD_PCI) += rsrc_pci.o | |
| 16 | 15 | obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o |
| 17 | 16 | |
| 18 | 17 | |
| @@ -1,173 +0,0 @@ | ||
| 1 | −#include <linux/slab.h> | |
| 2 | −#include <linux/module.h> | |
| 3 | −#include <linux/kernel.h> | |
| 4 | −#include <linux/pci.h> | |
| 5 | − | |
| 6 | −#include <pcmcia/ss.h> | |
| 7 | −#include <pcmcia/cistpl.h> | |
| 8 | −#include "cs_internal.h" | |
| 9 | − | |
| 10 | − | |
| 11 | −struct pcmcia_align_data { | |
| 12 | − unsigned long mask; | |
| 13 | − unsigned long offset; | |
| 14 | −}; | |
| 15 | − | |
| 16 | −static resource_size_t pcmcia_align(void *align_data, | |
| 17 | − const struct resource *res, | |
| 18 | − resource_size_t size, resource_size_t align) | |
| 19 | −{ | |
| 20 | − struct pcmcia_align_data *data = align_data; | |
| 21 | − resource_size_t start; | |
| 22 | − | |
| 23 | − start = (res->start & ~data->mask) + data->offset; | |
| 24 | − if (start < res->start) | |
| 25 | − start += data->mask + 1; | |
| 26 | − return start; | |
| 27 | −} | |
| 28 | − | |
| 29 | −static struct resource *find_io_region(struct pcmcia_socket *s, | |
| 30 | − unsigned long base, int num, | |
| 31 | − unsigned long align) | |
| 32 | −{ | |
| 33 | − struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, | |
| 34 | − dev_name(&s->dev)); | |
| 35 | − struct pcmcia_align_data data; | |
| 36 | − int ret; | |
| 37 | − | |
| 38 | − data.mask = align - 1; | |
| 39 | − data.offset = base & data.mask; | |
| 40 | − | |
| 41 | − ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | |
| 42 | − base, 0, pcmcia_align, &data); | |
| 43 | − if (ret != 0) { | |
| 44 | − kfree(res); | |
| 45 | − res = NULL; | |
| 46 | − } | |
| 47 | − return res; | |
| 48 | −} | |
| 49 | − | |
| 50 | −static int res_pci_find_io(struct pcmcia_socket *s, unsigned int attr, | |
| 51 | − unsigned int *base, unsigned int num, | |
| 52 | − unsigned int align, struct resource **parent) | |
| 53 | −{ | |
| 54 | − int i, ret = 0; | |
| 55 | − | |
| 56 | − /* Check for an already-allocated window that must conflict with | |
| 57 | − * what was asked for. It is a hack because it does not catch all | |
| 58 | − * potential conflicts, just the most obvious ones. | |
| 59 | − */ | |
| 60 | − for (i = 0; i < MAX_IO_WIN; i++) { | |
| 61 | − if (!s->io[i].res) | |
| 62 | − continue; | |
| 63 | − | |
| 64 | − if (!*base) | |
| 65 | − continue; | |
| 66 | − | |
| 67 | − if ((s->io[i].res->start & (align-1)) == *base) | |
| 68 | − return -EBUSY; | |
| 69 | − } | |
| 70 | − | |
| 71 | − for (i = 0; i < MAX_IO_WIN; i++) { | |
| 72 | − struct resource *res = s->io[i].res; | |
| 73 | − unsigned int try; | |
| 74 | − | |
| 75 | − if (res && (res->flags & IORESOURCE_BITS) != | |
| 76 | − (attr & IORESOURCE_BITS)) | |
| 77 | − continue; | |
| 78 | − | |
| 79 | − if (!res) { | |
| 80 | − if (align == 0) | |
| 81 | − align = 0x10000; | |
| 82 | − | |
| 83 | − res = s->io[i].res = find_io_region(s, *base, num, | |
| 84 | − align); | |
| 85 | − if (!res) | |
| 86 | − return -EINVAL; | |
| 87 | − | |
| 88 | − *base = res->start; | |
| 89 | − s->io[i].res->flags = | |
| 90 | − ((res->flags & ~IORESOURCE_BITS) | | |
| 91 | − (attr & IORESOURCE_BITS)); | |
| 92 | − s->io[i].InUse = num; | |
| 93 | − *parent = res; | |
| 94 | − return 0; | |
| 95 | − } | |
| 96 | − | |
| 97 | − /* Try to extend top of window */ | |
| 98 | − try = res->end + 1; | |
| 99 | − if ((*base == 0) || (*base == try)) { | |
| 100 | − ret = adjust_resource(s->io[i].res, res->start, | |
| 101 | − resource_size(res) + num); | |
| 102 | − if (ret) | |
| 103 | − continue; | |
| 104 | − *base = try; | |
| 105 | − s->io[i].InUse += num; | |
| 106 | − *parent = res; | |
| 107 | − return 0; | |
| 108 | − } | |
| 109 | − | |
| 110 | − /* Try to extend bottom of window */ | |
| 111 | − try = res->start - num; | |
| 112 | − if ((*base == 0) || (*base == try)) { | |
| 113 | − ret = adjust_resource(s->io[i].res, | |
| 114 | − res->start - num, | |
| 115 | − resource_size(res) + num); | |
| 116 | − if (ret) | |
| 117 | − continue; | |
| 118 | − *base = try; | |
| 119 | − s->io[i].InUse += num; | |
| 120 | − *parent = res; | |
| 121 | − return 0; | |
| 122 | − } | |
| 123 | − } | |
| 124 | − return -EINVAL; | |
| 125 | −} | |
| 126 | − | |
| 127 | −static struct resource *res_pci_find_mem(u_long base, u_long num, | |
| 128 | − u_long align, int low, struct pcmcia_socket *s) | |
| 129 | −{ | |
| 130 | − struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM, | |
| 131 | − dev_name(&s->dev)); | |
| 132 | − struct pcmcia_align_data data; | |
| 133 | − unsigned long min; | |
| 134 | − int ret; | |
| 135 | − | |
| 136 | − if (align < 0x20000) | |
| 137 | − align = 0x20000; | |
| 138 | − data.mask = align - 1; | |
| 139 | − data.offset = base & data.mask; | |
| 140 | − | |
| 141 | − min = 0; | |
| 142 | − if (!low) | |
| 143 | − min = 0x100000UL; | |
| 144 | − | |
| 145 | − ret = pci_bus_alloc_resource(s->cb_dev->bus, | |
| 146 | − res, num, 1, min, 0, | |
| 147 | − pcmcia_align, &data); | |
| 148 | − | |
| 149 | − if (ret != 0) { | |
| 150 | − kfree(res); | |
| 151 | − res = NULL; | |
| 152 | − } | |
| 153 | − return res; | |
| 154 | −} | |
| 155 | − | |
| 156 | − | |
| 157 | −static int res_pci_init(struct pcmcia_socket *s) | |
| 158 | −{ | |
| 159 | − if (!s->cb_dev || !(s->features & SS_CAP_PAGE_REGS)) { | |
| 160 | − dev_err(&s->dev, "not supported by res_pci\n"); | |
| 161 | − return -EOPNOTSUPP; | |
| 162 | − } | |
| 163 | − return 0; | |
| 164 | −} | |
| 165 | − | |
| 166 | −struct pccard_resource_ops pccard_nonstatic_ops = { | |
| 167 | − .validate_mem = NULL, | |
| 168 | − .find_io = res_pci_find_io, | |
| 169 | − .find_mem = res_pci_find_mem, | |
| 170 | − .init = res_pci_init, | |
| 171 | − .exit = NULL, | |
| 172 | −}; | |
| 173 | −EXPORT_SYMBOL(pccard_nonstatic_ops); | |
| @@ -37,7 +37,7 @@ static int armada375_usb_phy_init(struct phy *phy) · 36 unmodified lines | ||
| 37 | 37 | struct armada375_cluster_phy *cluster_phy; |
| 38 | 38 | u32 reg; |
| 39 | 39 | |
| 40 | − cluster_phy = dev_get_drvdata(phy->dev.parent); | |
| 40 | + cluster_phy = phy_get_drvdata(phy); | |
| 41 | 41 | if (!cluster_phy) |
| 42 | 42 | return -ENODEV; |
| 43 | 43 | |
| @@ -131,6 +131,7 @@ static int armada375_usb_phy_probe(struct platform_device *pdev) · 87 unmodified lines | ||
| 131 | 131 | cluster_phy->reg = usb_cluster_base; |
| 132 | 132 | |
| 133 | 133 | dev_set_drvdata(dev, cluster_phy); |
| 134 | + phy_set_drvdata(phy, cluster_phy); | |
| 134 | 135 | |
| 135 | 136 | phy_provider = devm_of_phy_provider_register(&pdev->dev, |
| 136 | 137 | armada375_usb_phy_xlate); |
| @@ -52,7 +52,9 @@ static void devm_phy_consume(struct device *dev, void *res) · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | static int devm_phy_match(struct device *dev, void *res, void *match_data) |
| 54 | 54 | { |
| 55 | − return res == match_data; | |
| 55 | + struct phy **phy = res; | |
| 56 | + | |
| 57 | + return *phy == match_data; | |
| 56 | 58 | } |
| 57 | 59 | |
| 58 | 60 | /** |
| @@ -223,6 +225,7 @@ int phy_init(struct phy *phy) · 164 unmodified lines | ||
| 223 | 225 | ret = phy_pm_runtime_get_sync(phy); |
| 224 | 226 | if (ret < 0 && ret != -ENOTSUPP) |
| 225 | 227 | return ret; |
| 228 | + ret = 0; /* Override possible ret == -ENOTSUPP */ | |
| 226 | 229 | |
| 227 | 230 | mutex_lock(&phy->mutex); |
| 228 | 231 | if (phy->init_count == 0 && phy->ops->init) { |
| @@ -231,8 +234,6 @@ int phy_init(struct phy *phy) · 2 unmodified lines | ||
| 231 | 234 | dev_err(&phy->dev, "phy init failed --> %d\n", ret); |
| 232 | 235 | goto out; |
| 233 | 236 | } |
| 234 | − } else { | |
| 235 | − ret = 0; /* Override possible ret == -ENOTSUPP */ | |
| 236 | 237 | } |
| 237 | 238 | ++phy->init_count; |
| 238 | 239 | |
| @@ -253,6 +254,7 @@ int phy_exit(struct phy *phy) · 14 unmodified lines | ||
| 253 | 254 | ret = phy_pm_runtime_get_sync(phy); |
| 254 | 255 | if (ret < 0 && ret != -ENOTSUPP) |
| 255 | 256 | return ret; |
| 257 | + ret = 0; /* Override possible ret == -ENOTSUPP */ | |
| 256 | 258 | |
| 257 | 259 | mutex_lock(&phy->mutex); |
| 258 | 260 | if (phy->init_count == 1 && phy->ops->exit) { |
| @@ -287,6 +289,7 @@ int phy_power_on(struct phy *phy) · 28 unmodified lines | ||
| 287 | 289 | ret = phy_pm_runtime_get_sync(phy); |
| 288 | 290 | if (ret < 0 && ret != -ENOTSUPP) |
| 289 | 291 | return ret; |
| 292 | + ret = 0; /* Override possible ret == -ENOTSUPP */ | |
| 290 | 293 | |
| 291 | 294 | mutex_lock(&phy->mutex); |
| 292 | 295 | if (phy->power_count == 0 && phy->ops->power_on) { |
| @@ -295,8 +298,6 @@ int phy_power_on(struct phy *phy) · 2 unmodified lines | ||
| 295 | 298 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); |
| 296 | 299 | goto out; |
| 297 | 300 | } |
| 298 | − } else { | |
| 299 | − ret = 0; /* Override possible ret == -ENOTSUPP */ | |
| 300 | 301 | } |
| 301 | 302 | ++phy->power_count; |
| 302 | 303 | mutex_unlock(&phy->mutex); |
| @@ -30,28 +30,13 @@ struct exynos_dp_video_phy { · 29 unmodified lines | ||
| 30 | 30 | const struct exynos_dp_video_phy_drvdata *drvdata; |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | −static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, | |
| 34 | − unsigned int on) | |
| 35 | −{ | |
| 36 | − unsigned int val; | |
| 37 | − | |
| 38 | − if (IS_ERR(state->regs)) | |
| 39 | − return; | |
| 40 | − | |
| 41 | − val = on ? 0 : EXYNOS5_PHY_ENABLE; | |
| 42 | − | |
| 43 | − regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, | |
| 44 | − EXYNOS5_PHY_ENABLE, val); | |
| 45 | −} | |
| 46 | − | |
| 47 | 33 | static int exynos_dp_video_phy_power_on(struct phy *phy) |
| 48 | 34 | { |
| 49 | 35 | struct exynos_dp_video_phy *state = phy_get_drvdata(phy); |
| 50 | 36 | |
| 51 | 37 | /* Disable power isolation on DP-PHY */ |
| 52 | − exynos_dp_video_phy_pwr_isol(state, 0); | |
| 53 | − | |
| 54 | − return 0; | |
| 38 | + return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, | |
| 39 | + EXYNOS5_PHY_ENABLE, EXYNOS5_PHY_ENABLE); | |
| 55 | 40 | } |
| 56 | 41 | |
| 57 | 42 | static int exynos_dp_video_phy_power_off(struct phy *phy) |
| @@ -59,9 +44,8 @@ static int exynos_dp_video_phy_power_off(struct phy *phy) · 1 unmodified line | ||
| 59 | 44 | struct exynos_dp_video_phy *state = phy_get_drvdata(phy); |
| 60 | 45 | |
| 61 | 46 | /* Enable power isolation on DP-PHY */ |
| 62 | − exynos_dp_video_phy_pwr_isol(state, 1); | |
| 63 | − | |
| 64 | − return 0; | |
| 47 | + return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, | |
| 48 | + EXYNOS5_PHY_ENABLE, 0); | |
| 65 | 49 | } |
| 66 | 50 | |
| 67 | 51 | static struct phy_ops exynos_dp_video_phy_ops = { |
| @@ -43,7 +43,6 @@ struct exynos_mipi_video_phy { · 42 unmodified lines | ||
| 43 | 43 | } phys[EXYNOS_MIPI_PHYS_NUM]; |
| 44 | 44 | spinlock_t slock; |
| 45 | 45 | void __iomem *regs; |
| 46 | − struct mutex mutex; | |
| 47 | 46 | struct regmap *regmap; |
| 48 | 47 | }; |
| 49 | 48 | |
| @@ -59,8 +58,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, · 9 unmodified lines | ||
| 59 | 58 | else |
| 60 | 59 | reset = EXYNOS4_MIPI_PHY_SRESETN; |
| 61 | 60 | |
| 62 | − if (state->regmap) { | |
| 63 | − mutex_lock(&state->mutex); | |
| 61 | + spin_lock(&state->slock); | |
| 62 | + | |
| 63 | + if (!IS_ERR(state->regmap)) { | |
| 64 | 64 | regmap_read(state->regmap, offset, &val); |
| 65 | 65 | if (on) |
| 66 | 66 | val |= reset; |
| @@ -72,11 +72,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, · 5 unmodified lines | ||
| 72 | 72 | else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK)) |
| 73 | 73 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; |
| 74 | 74 | regmap_write(state->regmap, offset, val); |
| 75 | − mutex_unlock(&state->mutex); | |
| 76 | 75 | } else { |
| 77 | 76 | addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2); |
| 78 | 77 | |
| 79 | − spin_lock(&state->slock); | |
| 80 | 78 | val = readl(addr); |
| 81 | 79 | if (on) |
| 82 | 80 | val |= reset; |
| @@ -90,9 +88,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state, · 7 unmodified lines | ||
| 90 | 88 | val &= ~EXYNOS4_MIPI_PHY_ENABLE; |
| 91 | 89 | |
| 92 | 90 | writel(val, addr); |
| 93 | − spin_unlock(&state->slock); | |
| 94 | 91 | } |
| 95 | 92 | |
| 93 | + spin_unlock(&state->slock); | |
| 96 | 94 | return 0; |
| 97 | 95 | } |
| 98 | 96 | |
| @@ -158,7 +156,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 158 | 156 | |
| 159 | 157 | dev_set_drvdata(dev, state); |
| 160 | 158 | spin_lock_init(&state->slock); |
| 161 | − mutex_init(&state->mutex); | |
| 162 | 159 | |
| 163 | 160 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { |
| 164 | 161 | struct phy *phy = devm_phy_create(dev, NULL, |
| @@ -250,7 +250,6 @@ static const struct samsung_usb2_common_phy exynos4210_phys[] = { · 249 unmodified lines | ||
| 250 | 250 | .power_on = exynos4210_power_on, |
| 251 | 251 | .power_off = exynos4210_power_off, |
| 252 | 252 | }, |
| 253 | − {}, | |
| 254 | 253 | }; |
| 255 | 254 | |
| 256 | 255 | const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = { |
| @@ -361,7 +361,6 @@ static const struct samsung_usb2_common_phy exynos4x12_phys[] = { · 360 unmodified lines | ||
| 361 | 361 | .power_on = exynos4x12_power_on, |
| 362 | 362 | .power_off = exynos4x12_power_off, |
| 363 | 363 | }, |
| 364 | − {}, | |
| 365 | 364 | }; |
| 366 | 365 | |
| 367 | 366 | const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = { |
| @@ -531,7 +531,7 @@ static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev, · 530 unmodified lines | ||
| 531 | 531 | { |
| 532 | 532 | struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev); |
| 533 | 533 | |
| 534 | − if (WARN_ON(args->args[0] > EXYNOS5_DRDPHYS_NUM)) | |
| 534 | + if (WARN_ON(args->args[0] >= EXYNOS5_DRDPHYS_NUM)) | |
| 535 | 535 | return ERR_PTR(-ENODEV); |
| 536 | 536 | |
| 537 | 537 | return phy_drd->phys[args->args[0]].phy; |
| @@ -391,7 +391,6 @@ static const struct samsung_usb2_common_phy exynos5250_phys[] = { · 390 unmodified lines | ||
| 391 | 391 | .power_on = exynos5250_power_on, |
| 392 | 392 | .power_off = exynos5250_power_off, |
| 393 | 393 | }, |
| 394 | − {}, | |
| 395 | 394 | }; |
| 396 | 395 | |
| 397 | 396 | const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = { |
| @@ -147,6 +147,9 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev) · 146 unmodified lines | ||
| 147 | 147 | return -ENOMEM; |
| 148 | 148 | |
| 149 | 149 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 150 | + if (!res) | |
| 151 | + return -EINVAL; | |
| 152 | + | |
| 150 | 153 | priv->base = devm_ioremap(dev, res->start, resource_size(res)); |
| 151 | 154 | if (!priv->base) |
| 152 | 155 | return -ENOMEM; |
| @@ -228,6 +228,7 @@ struct miphy28lp_dev { · 227 unmodified lines | ||
| 228 | 228 | struct regmap *regmap; |
| 229 | 229 | struct mutex miphy_mutex; |
| 230 | 230 | struct miphy28lp_phy **phys; |
| 231 | + int nphys; | |
| 231 | 232 | }; |
| 232 | 233 | |
| 233 | 234 | struct miphy_initval { |
| @@ -1116,7 +1117,7 @@ static struct phy *miphy28lp_xlate(struct device *dev, · 882 unmodified lines | ||
| 1116 | 1117 | return ERR_PTR(-EINVAL); |
| 1117 | 1118 | } |
| 1118 | 1119 | |
| 1119 | − for (index = 0; index < of_get_child_count(dev->of_node); index++) | |
| 1120 | + for (index = 0; index < miphy_dev->nphys; index++) | |
| 1120 | 1121 | if (phynode == miphy_dev->phys[index]->phy->dev.of_node) { |
| 1121 | 1122 | miphy_phy = miphy_dev->phys[index]; |
| 1122 | 1123 | break; |
| @@ -1138,6 +1139,7 @@ static struct phy *miphy28lp_xlate(struct device *dev, · 15 unmodified lines | ||
| 1138 | 1139 | |
| 1139 | 1140 | static struct phy_ops miphy28lp_ops = { |
| 1140 | 1141 | .init = miphy28lp_init, |
| 1142 | + .owner = THIS_MODULE, | |
| 1141 | 1143 | }; |
| 1142 | 1144 | |
| 1143 | 1145 | static int miphy28lp_probe_resets(struct device_node *node, |
| @@ -1200,16 +1202,15 @@ static int miphy28lp_probe(struct platform_device *pdev) · 56 unmodified lines | ||
| 1200 | 1202 | struct miphy28lp_dev *miphy_dev; |
| 1201 | 1203 | struct phy_provider *provider; |
| 1202 | 1204 | struct phy *phy; |
| 1203 | − int chancount, port = 0; | |
| 1204 | − int ret; | |
| 1205 | + int ret, port = 0; | |
| 1205 | 1206 | |
| 1206 | 1207 | miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL); |
| 1207 | 1208 | if (!miphy_dev) |
| 1208 | 1209 | return -ENOMEM; |
| 1209 | 1210 | |
| 1210 | − chancount = of_get_child_count(np); | |
| 1211 | − miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount, | |
| 1212 | − GFP_KERNEL); | |
| 1211 | + miphy_dev->nphys = of_get_child_count(np); | |
| 1212 | + miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys, | |
| 1213 | + sizeof(*miphy_dev->phys), GFP_KERNEL); | |
| 1213 | 1214 | if (!miphy_dev->phys) |
| 1214 | 1215 | return -ENOMEM; |
| 1215 | 1216 | |
| @@ -150,6 +150,7 @@ struct miphy365x_dev { · 149 unmodified lines | ||
| 150 | 150 | struct regmap *regmap; |
| 151 | 151 | struct mutex miphy_mutex; |
| 152 | 152 | struct miphy365x_phy **phys; |
| 153 | + int nphys; | |
| 153 | 154 | }; |
| 154 | 155 | |
| 155 | 156 | /* |
| @@ -485,7 +486,7 @@ static struct phy *miphy365x_xlate(struct device *dev, · 329 unmodified lines | ||
| 485 | 486 | return ERR_PTR(-EINVAL); |
| 486 | 487 | } |
| 487 | 488 | |
| 488 | − for (index = 0; index < of_get_child_count(dev->of_node); index++) | |
| 489 | + for (index = 0; index < miphy_dev->nphys; index++) | |
| 489 | 490 | if (phynode == miphy_dev->phys[index]->phy->dev.of_node) { |
| 490 | 491 | miphy_phy = miphy_dev->phys[index]; |
| 491 | 492 | break; |
| @@ -541,16 +542,15 @@ static int miphy365x_probe(struct platform_device *pdev) · 49 unmodified lines | ||
| 541 | 542 | struct miphy365x_dev *miphy_dev; |
| 542 | 543 | struct phy_provider *provider; |
| 543 | 544 | struct phy *phy; |
| 544 | − int chancount, port = 0; | |
| 545 | − int ret; | |
| 545 | + int ret, port = 0; | |
| 546 | 546 | |
| 547 | 547 | miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL); |
| 548 | 548 | if (!miphy_dev) |
| 549 | 549 | return -ENOMEM; |
| 550 | 550 | |
| 551 | − chancount = of_get_child_count(np); | |
| 552 | − miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount, | |
| 553 | − GFP_KERNEL); | |
| 551 | + miphy_dev->nphys = of_get_child_count(np); | |
| 552 | + miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys, | |
| 553 | + sizeof(*miphy_dev->phys), GFP_KERNEL); | |
| 554 | 554 | if (!miphy_dev->phys) |
| 555 | 555 | return -ENOMEM; |
| 556 | 556 | |
| @@ -360,7 +360,7 @@ static void __exit omap_control_phy_exit(void) · 359 unmodified lines | ||
| 360 | 360 | } |
| 361 | 361 | module_exit(omap_control_phy_exit); |
| 362 | 362 | |
| 363 | −MODULE_ALIAS("platform: omap_control_phy"); | |
| 363 | +MODULE_ALIAS("platform:omap_control_phy"); | |
| 364 | 364 | MODULE_AUTHOR("Texas Instruments Inc."); |
| 365 | 365 | MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); |
| 366 | 366 | MODULE_LICENSE("GPL v2"); |
| @@ -296,10 +296,11 @@ static int omap_usb2_probe(struct platform_device *pdev) · 295 unmodified lines | ||
| 296 | 296 | dev_warn(&pdev->dev, |
| 297 | 297 | "found usb_otg_ss_refclk960m, please fix DTS\n"); |
| 298 | 298 | } |
| 299 | − } else { | |
| 300 | − clk_prepare(phy->optclk); | |
| 301 | 299 | } |
| 302 | 300 | |
| 301 | + if (!IS_ERR(phy->optclk)) | |
| 302 | + clk_prepare(phy->optclk); | |
| 303 | + | |
| 303 | 304 | usb_add_phy_dev(&phy->phy); |
| 304 | 305 | |
| 305 | 306 | return 0; |
| @@ -383,7 +384,7 @@ static struct platform_driver omap_usb2_driver = { · 77 unmodified lines | ||
| 383 | 384 | |
| 384 | 385 | module_platform_driver(omap_usb2_driver); |
| 385 | 386 | |
| 386 | −MODULE_ALIAS("platform: omap_usb2"); | |
| 387 | +MODULE_ALIAS("platform:omap_usb2"); | |
| 387 | 388 | MODULE_AUTHOR("Texas Instruments Inc."); |
| 388 | 389 | MODULE_DESCRIPTION("OMAP USB2 phy driver"); |
| 389 | 390 | MODULE_LICENSE("GPL v2"); |
| @@ -61,8 +61,6 @@ static int rockchip_usb_phy_power_off(struct phy *_phy) · 60 unmodified lines | ||
| 61 | 61 | return ret; |
| 62 | 62 | |
| 63 | 63 | clk_disable_unprepare(phy->clk); |
| 64 | − if (ret) | |
| 65 | − return ret; | |
| 66 | 64 | |
| 67 | 65 | return 0; |
| 68 | 66 | } |
| @@ -78,8 +76,10 @@ static int rockchip_usb_phy_power_on(struct phy *_phy) · 9 unmodified lines | ||
| 78 | 76 | |
| 79 | 77 | /* Power up usb phy analog blocks by set siddq 0 */ |
| 80 | 78 | ret = rockchip_usb_phy_power(phy, 0); |
| 81 | − if (ret) | |
| 79 | + if (ret) { | |
| 80 | + clk_disable_unprepare(phy->clk); | |
| 82 | 81 | return ret; |
| 82 | + } | |
| 83 | 83 | |
| 84 | 84 | return 0; |
| 85 | 85 | } |
| @@ -165,15 +165,11 @@ static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy) · 164 unmodified lines | ||
| 165 | 165 | cpu_relax(); |
| 166 | 166 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); |
| 167 | 167 | if (val & PLL_LOCK) |
| 168 | − break; | |
| 168 | + return 0; | |
| 169 | 169 | } while (!time_after(jiffies, timeout)); |
| 170 | 170 | |
| 171 | − if (!(val & PLL_LOCK)) { | |
| 172 | − dev_err(phy->dev, "DPLL failed to lock\n"); | |
| 173 | − return -EBUSY; | |
| 174 | − } | |
| 175 | − | |
| 176 | − return 0; | |
| 171 | + dev_err(phy->dev, "DPLL failed to lock\n"); | |
| 172 | + return -EBUSY; | |
| 177 | 173 | } |
| 178 | 174 | |
| 179 | 175 | static int ti_pipe3_dpll_program(struct ti_pipe3 *phy) |
| @@ -608,7 +604,7 @@ static struct platform_driver ti_pipe3_driver = { · 428 unmodified lines | ||
| 608 | 604 | |
| 609 | 605 | module_platform_driver(ti_pipe3_driver); |
| 610 | 606 | |
| 611 | −MODULE_ALIAS("platform: ti_pipe3"); | |
| 607 | +MODULE_ALIAS("platform:ti_pipe3"); | |
| 612 | 608 | MODULE_AUTHOR("Texas Instruments Inc."); |
| 613 | 609 | MODULE_DESCRIPTION("TI PIPE3 phy driver"); |
| 614 | 610 | MODULE_LICENSE("GPL v2"); |
| @@ -666,7 +666,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) · 665 unmodified lines | ||
| 666 | 666 | twl->dev = &pdev->dev; |
| 667 | 667 | twl->irq = platform_get_irq(pdev, 0); |
| 668 | 668 | twl->vbus_supplied = false; |
| 669 | − twl->linkstat = -EINVAL; | |
| 670 | 669 | twl->linkstat = OMAP_MUSB_UNKNOWN; |
| 671 | 670 | |
| 672 | 671 | twl->phy.dev = twl->dev; |
| @@ -1704,7 +1704,6 @@ static int xgene_phy_probe(struct platform_device *pdev) · 1703 unmodified lines | ||
| 1704 | 1704 | for (i = 0; i < MAX_LANE; i++) |
| 1705 | 1705 | ctx->sata_param.speed[i] = 2; /* Default to Gen3 */ |
| 1706 | 1706 | |
| 1707 | − ctx->dev = &pdev->dev; | |
| 1708 | 1707 | platform_set_drvdata(pdev, ctx); |
| 1709 | 1708 | |
| 1710 | 1709 | ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops); |
| @@ -66,6 +66,10 @@ · 65 unmodified lines | ||
| 66 | 66 | #define BYT_DIR_MASK (BIT(1) | BIT(2)) |
| 67 | 67 | #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) |
| 68 | 68 | |
| 69 | +#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ | |
| 70 | + BYT_PIN_MUX) | |
| 71 | +#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) | |
| 72 | + | |
| 69 | 73 | #define BYT_NGPIO_SCORE 102 |
| 70 | 74 | #define BYT_NGPIO_NCORE 28 |
| 71 | 75 | #define BYT_NGPIO_SUS 44 |
| @@ -134,12 +138,18 @@ static struct pinctrl_gpio_range byt_ranges[] = { · 62 unmodified lines | ||
| 134 | 138 | }, |
| 135 | 139 | }; |
| 136 | 140 | |
| 141 | +struct byt_gpio_pin_context { | |
| 142 | + u32 conf0; | |
| 143 | + u32 val; | |
| 144 | +}; | |
| 145 | + | |
| 137 | 146 | struct byt_gpio { |
| 138 | 147 | struct gpio_chip chip; |
| 139 | 148 | struct platform_device *pdev; |
| 140 | 149 | spinlock_t lock; |
| 141 | 150 | void __iomem *reg_base; |
| 142 | 151 | struct pinctrl_gpio_range *range; |
| 152 | + struct byt_gpio_pin_context *saved_context; | |
| 143 | 153 | }; |
| 144 | 154 | |
| 145 | 155 | #define to_byt_gpio(c) container_of(c, struct byt_gpio, chip) |
| @@ -158,40 +168,62 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset, · 12 unmodified lines | ||
| 158 | 168 | return vg->reg_base + reg_offset + reg; |
| 159 | 169 | } |
| 160 | 170 | |
| 161 | −static bool is_special_pin(struct byt_gpio *vg, unsigned offset) | |
| 171 | +static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset) | |
| 172 | +{ | |
| 173 | + void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); | |
| 174 | + unsigned long flags; | |
| 175 | + u32 value; | |
| 176 | + | |
| 177 | + spin_lock_irqsave(&vg->lock, flags); | |
| 178 | + value = readl(reg); | |
| 179 | + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); | |
| 180 | + writel(value, reg); | |
| 181 | + spin_unlock_irqrestore(&vg->lock, flags); | |
| 182 | +} | |
| 183 | + | |
| 184 | +static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) | |
| 162 | 185 | { |
| 163 | 186 | /* SCORE pin 92-93 */ |
| 164 | 187 | if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) && |
| 165 | 188 | offset >= 92 && offset <= 93) |
| 166 | − return true; | |
| 189 | + return 1; | |
| 167 | 190 | |
| 168 | 191 | /* SUS pin 11-21 */ |
| 169 | 192 | if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) && |
| 170 | 193 | offset >= 11 && offset <= 21) |
| 171 | − return true; | |
| 194 | + return 1; | |
| 172 | 195 | |
| 173 | − return false; | |
| 196 | + return 0; | |
| 174 | 197 | } |
| 175 | 198 | |
| 176 | 199 | static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) |
| 177 | 200 | { |
| 178 | 201 | struct byt_gpio *vg = to_byt_gpio(chip); |
| 179 | 202 | void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG); |
| 180 | − u32 value; | |
| 181 | − bool special; | |
| 203 | + u32 value, gpio_mux; | |
| 182 | 204 | |
| 183 | 205 | /* |
| 184 | 206 | * In most cases, func pin mux 000 means GPIO function. |
| 185 | 207 | * But, some pins may have func pin mux 001 represents |
| 186 | − * GPIO function. Only allow user to export pin with | |
| 187 | − * func pin mux preset as GPIO function by BIOS/FW. | |
| 208 | + * GPIO function. | |
| 209 | + * | |
| 210 | + * Because there are devices out there where some pins were not | |
| 211 | + * configured correctly we allow changing the mux value from | |
| 212 | + * request (but print out warning about that). | |
| 188 | 213 | */ |
| 189 | 214 | value = readl(reg) & BYT_PIN_MUX; |
| 190 | − special = is_special_pin(vg, offset); | |
| 191 | − if ((special && value != 1) || (!special && value)) { | |
| 192 | − dev_err(&vg->pdev->dev, | |
| 193 | − "pin %u cannot be used as GPIO.\n", offset); | |
| 194 | − return -EINVAL; | |
| 215 | + gpio_mux = byt_get_gpio_mux(vg, offset); | |
| 216 | + if (WARN_ON(gpio_mux != value)) { | |
| 217 | + unsigned long flags; | |
| 218 | + | |
| 219 | + spin_lock_irqsave(&vg->lock, flags); | |
| 220 | + value = readl(reg) & ~BYT_PIN_MUX; | |
| 221 | + value |= gpio_mux; | |
| 222 | + writel(value, reg); | |
| 223 | + spin_unlock_irqrestore(&vg->lock, flags); | |
| 224 | + | |
| 225 | + dev_warn(&vg->pdev->dev, | |
| 226 | + "pin %u forcibly re-configured as GPIO\n", offset); | |
| 195 | 227 | } |
| 196 | 228 | |
| 197 | 229 | pm_runtime_get(&vg->pdev->dev); |
| @@ -202,14 +234,8 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset) · 4 unmodified lines | ||
| 202 | 234 | static void byt_gpio_free(struct gpio_chip *chip, unsigned offset) |
| 203 | 235 | { |
| 204 | 236 | struct byt_gpio *vg = to_byt_gpio(chip); |
| 205 | − void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); | |
| 206 | − u32 value; | |
| 207 | − | |
| 208 | − /* clear interrupt triggering */ | |
| 209 | − value = readl(reg); | |
| 210 | − value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); | |
| 211 | − writel(value, reg); | |
| 212 | 237 | |
| 238 | + byt_gpio_clear_triggering(vg, offset); | |
| 213 | 239 | pm_runtime_put(&vg->pdev->dev); |
| 214 | 240 | } |
| 215 | 241 | |
| @@ -236,23 +262,13 @@ static int byt_irq_type(struct irq_data *d, unsigned type) · 20 unmodified lines | ||
| 236 | 262 | value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | |
| 237 | 263 | BYT_TRIG_LVL); |
| 238 | 264 | |
| 239 | − switch (type) { | |
| 240 | − case IRQ_TYPE_LEVEL_HIGH: | |
| 241 | − value |= BYT_TRIG_LVL; | |
| 242 | − case IRQ_TYPE_EDGE_RISING: | |
| 243 | − value |= BYT_TRIG_POS; | |
| 244 | − break; | |
| 245 | − case IRQ_TYPE_LEVEL_LOW: | |
| 246 | − value |= BYT_TRIG_LVL; | |
| 247 | − case IRQ_TYPE_EDGE_FALLING: | |
| 248 | − value |= BYT_TRIG_NEG; | |
| 249 | − break; | |
| 250 | − case IRQ_TYPE_EDGE_BOTH: | |
| 251 | − value |= (BYT_TRIG_NEG | BYT_TRIG_POS); | |
| 252 | − break; | |
| 253 | − } | |
| 254 | 265 | writel(value, reg); |
| 255 | 266 | |
| 267 | + if (type & IRQ_TYPE_EDGE_BOTH) | |
| 268 | + __irq_set_handler_locked(d->irq, handle_edge_irq); | |
| 269 | + else if (type & IRQ_TYPE_LEVEL_MASK) | |
| 270 | + __irq_set_handler_locked(d->irq, handle_level_irq); | |
| 271 | + | |
| 256 | 272 | spin_unlock_irqrestore(&vg->lock, flags); |
| 257 | 273 | |
| 258 | 274 | return 0; |
| @@ -410,58 +426,80 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc) · 151 unmodified lines | ||
| 410 | 426 | struct irq_data *data = irq_desc_get_irq_data(desc); |
| 411 | 427 | struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc)); |
| 412 | 428 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
| 413 | − u32 base, pin, mask; | |
| 429 | + u32 base, pin; | |
| 414 | 430 | void __iomem *reg; |
| 415 | − u32 pending; | |
| 431 | + unsigned long pending; | |
| 416 | 432 | unsigned virq; |
| 417 | − int looplimit = 0; | |
| 418 | 433 | |
| 419 | 434 | /* check from GPIO controller which pin triggered the interrupt */ |
| 420 | 435 | for (base = 0; base < vg->chip.ngpio; base += 32) { |
| 421 | − | |
| 422 | 436 | reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG); |
| 423 | − | |
| 424 | − while ((pending = readl(reg))) { | |
| 425 | − pin = __ffs(pending); | |
| 426 | − mask = BIT(pin); | |
| 427 | − /* Clear before handling so we can't lose an edge */ | |
| 428 | − writel(mask, reg); | |
| 429 | − | |
| 437 | + pending = readl(reg); | |
| 438 | + for_each_set_bit(pin, &pending, 32) { | |
| 430 | 439 | virq = irq_find_mapping(vg->chip.irqdomain, base + pin); |
| 431 | 440 | generic_handle_irq(virq); |
| 432 | − | |
| 433 | − /* In case bios or user sets triggering incorretly a pin | |
| 434 | − * might remain in "interrupt triggered" state. | |
| 435 | − */ | |
| 436 | − if (looplimit++ > 32) { | |
| 437 | − dev_err(&vg->pdev->dev, | |
| 438 | − "Gpio %d interrupt flood, disabling\n", | |
| 439 | − base + pin); | |
| 440 | − | |
| 441 | − reg = byt_gpio_reg(&vg->chip, base + pin, | |
| 442 | − BYT_CONF0_REG); | |
| 443 | − mask = readl(reg); | |
| 444 | − mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS | | |
| 445 | − BYT_TRIG_LVL); | |
| 446 | − writel(mask, reg); | |
| 447 | − mask = readl(reg); /* flush */ | |
| 448 | − break; | |
| 449 | − } | |
| 450 | 441 | } |
| 451 | 442 | } |
| 452 | 443 | chip->irq_eoi(data); |
| 453 | 444 | } |
| 454 | 445 | |
| 446 | +static void byt_irq_ack(struct irq_data *d) | |
| 447 | +{ | |
| 448 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 449 | + struct byt_gpio *vg = to_byt_gpio(gc); | |
| 450 | + unsigned offset = irqd_to_hwirq(d); | |
| 451 | + void __iomem *reg; | |
| 452 | + | |
| 453 | + reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG); | |
| 454 | + writel(BIT(offset % 32), reg); | |
| 455 | +} | |
| 456 | + | |
| 455 | 457 | static void byt_irq_unmask(struct irq_data *d) |
| 456 | 458 | { |
| 459 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 460 | + struct byt_gpio *vg = to_byt_gpio(gc); | |
| 461 | + unsigned offset = irqd_to_hwirq(d); | |
| 462 | + unsigned long flags; | |
| 463 | + void __iomem *reg; | |
| 464 | + u32 value; | |
| 465 | + | |
| 466 | + spin_lock_irqsave(&vg->lock, flags); | |
| 467 | + | |
| 468 | + reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG); | |
| 469 | + value = readl(reg); | |
| 470 | + | |
| 471 | + switch (irqd_get_trigger_type(d)) { | |
| 472 | + case IRQ_TYPE_LEVEL_HIGH: | |
| 473 | + value |= BYT_TRIG_LVL; | |
| 474 | + case IRQ_TYPE_EDGE_RISING: | |
| 475 | + value |= BYT_TRIG_POS; | |
| 476 | + break; | |
| 477 | + case IRQ_TYPE_LEVEL_LOW: | |
| 478 | + value |= BYT_TRIG_LVL; | |
| 479 | + case IRQ_TYPE_EDGE_FALLING: | |
| 480 | + value |= BYT_TRIG_NEG; | |
| 481 | + break; | |
| 482 | + case IRQ_TYPE_EDGE_BOTH: | |
| 483 | + value |= (BYT_TRIG_NEG | BYT_TRIG_POS); | |
| 484 | + break; | |
| 485 | + } | |
| 486 | + | |
| 487 | + writel(value, reg); | |
| 488 | + | |
| 489 | + spin_unlock_irqrestore(&vg->lock, flags); | |
| 457 | 490 | } |
| 458 | 491 | |
| 459 | 492 | static void byt_irq_mask(struct irq_data *d) |
| 460 | 493 | { |
| 494 | + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
| 495 | + struct byt_gpio *vg = to_byt_gpio(gc); | |
| 496 | + | |
| 497 | + byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); | |
| 461 | 498 | } |
| 462 | 499 | |
| 463 | 500 | static struct irq_chip byt_irqchip = { |
| 464 | 501 | .name = "BYT-GPIO", |
| 502 | + .irq_ack = byt_irq_ack, | |
| 465 | 503 | .irq_mask = byt_irq_mask, |
| 466 | 504 | .irq_unmask = byt_irq_unmask, |
| 467 | 505 | .irq_set_type = byt_irq_type, |
| @@ -472,6 +510,21 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) · 4 unmodified lines | ||
| 472 | 510 | { |
| 473 | 511 | void __iomem *reg; |
| 474 | 512 | u32 base, value; |
| 513 | + int i; | |
| 514 | + | |
| 515 | + /* | |
| 516 | + * Clear interrupt triggers for all pins that are GPIOs and | |
| 517 | + * do not use direct IRQ mode. This will prevent spurious | |
| 518 | + * interrupts from misconfigured pins. | |
| 519 | + */ | |
| 520 | + for (i = 0; i < vg->chip.ngpio; i++) { | |
| 521 | + value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG)); | |
| 522 | + if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) && | |
| 523 | + !(value & BYT_DIRECT_IRQ_EN)) { | |
| 524 | + byt_gpio_clear_triggering(vg, i); | |
| 525 | + dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i); | |
| 526 | + } | |
| 527 | + } | |
| 475 | 528 | |
| 476 | 529 | /* clear interrupt status trigger registers */ |
| 477 | 530 | for (base = 0; base < vg->chip.ngpio; base += 32) { |
| @@ -541,6 +594,11 @@ static int byt_gpio_probe(struct platform_device *pdev) · 63 unmodified lines | ||
| 541 | 594 | gc->can_sleep = false; |
| 542 | 595 | gc->dev = dev; |
| 543 | 596 | |
| 597 | +#ifdef CONFIG_PM_SLEEP | |
| 598 | + vg->saved_context = devm_kcalloc(&pdev->dev, gc->ngpio, | |
| 599 | + sizeof(*vg->saved_context), GFP_KERNEL); | |
| 600 | +#endif | |
| 601 | + | |
| 544 | 602 | ret = gpiochip_add(gc); |
| 545 | 603 | if (ret) { |
| 546 | 604 | dev_err(&pdev->dev, "failed adding byt-gpio chip\n"); |
| @@ -569,6 +627,69 @@ static int byt_gpio_probe(struct platform_device *pdev) · 22 unmodified lines | ||
| 569 | 627 | return 0; |
| 570 | 628 | } |
| 571 | 629 | |
| 630 | +#ifdef CONFIG_PM_SLEEP | |
| 631 | +static int byt_gpio_suspend(struct device *dev) | |
| 632 | +{ | |
| 633 | + struct platform_device *pdev = to_platform_device(dev); | |
| 634 | + struct byt_gpio *vg = platform_get_drvdata(pdev); | |
| 635 | + int i; | |
| 636 | + | |
| 637 | + for (i = 0; i < vg->chip.ngpio; i++) { | |
| 638 | + void __iomem *reg; | |
| 639 | + u32 value; | |
| 640 | + | |
| 641 | + reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); | |
| 642 | + value = readl(reg) & BYT_CONF0_RESTORE_MASK; | |
| 643 | + vg->saved_context[i].conf0 = value; | |
| 644 | + | |
| 645 | + reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); | |
| 646 | + value = readl(reg) & BYT_VAL_RESTORE_MASK; | |
| 647 | + vg->saved_context[i].val = value; | |
| 648 | + } | |
| 649 | + | |
| 650 | + return 0; | |
| 651 | +} | |
| 652 | + | |
| 653 | +static int byt_gpio_resume(struct device *dev) | |
| 654 | +{ | |
| 655 | + struct platform_device *pdev = to_platform_device(dev); | |
| 656 | + struct byt_gpio *vg = platform_get_drvdata(pdev); | |
| 657 | + int i; | |
| 658 | + | |
| 659 | + for (i = 0; i < vg->chip.ngpio; i++) { | |
| 660 | + void __iomem *reg; | |
| 661 | + u32 value; | |
| 662 | + | |
| 663 | + reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG); | |
| 664 | + value = readl(reg); | |
| 665 | + if ((value & BYT_CONF0_RESTORE_MASK) != | |
| 666 | + vg->saved_context[i].conf0) { | |
| 667 | + value &= ~BYT_CONF0_RESTORE_MASK; | |
| 668 | + value |= vg->saved_context[i].conf0; | |
| 669 | + writel(value, reg); | |
| 670 | + dev_info(dev, "restored pin %d conf0 %#08x", i, value); | |
| 671 | + } | |
| 672 | + | |
| 673 | + reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG); | |
| 674 | + value = readl(reg); | |
| 675 | + if ((value & BYT_VAL_RESTORE_MASK) != | |
| 676 | + vg->saved_context[i].val) { | |
| 677 | + u32 v; | |
| 678 | + | |
| 679 | + v = value & ~BYT_VAL_RESTORE_MASK; | |
| 680 | + v |= vg->saved_context[i].val; | |
| 681 | + if (v != value) { | |
| 682 | + writel(v, reg); | |
| 683 | + dev_dbg(dev, "restored pin %d val %#08x\n", | |
| 684 | + i, v); | |
| 685 | + } | |
| 686 | + } | |
| 687 | + } | |
| 688 | + | |
| 689 | + return 0; | |
| 690 | +} | |
| 691 | +#endif | |
| 692 | + | |
| 572 | 693 | static int byt_gpio_runtime_suspend(struct device *dev) |
| 573 | 694 | { |
| 574 | 695 | return 0; |
| @@ -580,8 +701,9 @@ static int byt_gpio_runtime_resume(struct device *dev) · 5 unmodified lines | ||
| 580 | 701 | } |
| 581 | 702 | |
| 582 | 703 | static const struct dev_pm_ops byt_gpio_pm_ops = { |
| 583 | − .runtime_suspend = byt_gpio_runtime_suspend, | |
| 584 | − .runtime_resume = byt_gpio_runtime_resume, | |
| 704 | + SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) | |
| 705 | + SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, | |
| 706 | + NULL) | |
| 585 | 707 | }; |
| 586 | 708 | |
| 587 | 709 | static const struct acpi_device_id byt_gpio_acpi_match[] = { |
| @@ -1226,6 +1226,7 @@ static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned offset) · 1225 unmodified lines | ||
| 1226 | 1226 | static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned offset, |
| 1227 | 1227 | int value) |
| 1228 | 1228 | { |
| 1229 | + chv_gpio_set(chip, offset, value); | |
| 1229 | 1230 | return pinctrl_gpio_direction_output(chip->base + offset); |
| 1230 | 1231 | } |
| 1231 | 1232 | |
| @@ -1477,28 +1477,25 @@ static void gpio_irq_ack(struct irq_data *d) · 1476 unmodified lines | ||
| 1477 | 1477 | /* the interrupt is already cleared before by reading ISR */ |
| 1478 | 1478 | } |
| 1479 | 1479 | |
| 1480 | −static unsigned int gpio_irq_startup(struct irq_data *d) | |
| 1480 | +static int gpio_irq_request_res(struct irq_data *d) | |
| 1481 | 1481 | { |
| 1482 | 1482 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
| 1483 | 1483 | unsigned pin = d->hwirq; |
| 1484 | 1484 | int ret; |
| 1485 | 1485 | |
| 1486 | 1486 | ret = gpiochip_lock_as_irq(&at91_gpio->chip, pin); |
| 1487 | − if (ret) { | |
| 1487 | + if (ret) | |
| 1488 | 1488 | dev_err(at91_gpio->chip.dev, "unable to lock pind %lu IRQ\n", |
| 1489 | 1489 | d->hwirq); |
| 1490 | − return ret; | |
| 1491 | − } | |
| 1492 | − gpio_irq_unmask(d); | |
| 1493 | − return 0; | |
| 1490 | + | |
| 1491 | + return ret; | |
| 1494 | 1492 | } |
| 1495 | 1493 | |
| 1496 | −static void gpio_irq_shutdown(struct irq_data *d) | |
| 1494 | +static void gpio_irq_release_res(struct irq_data *d) | |
| 1497 | 1495 | { |
| 1498 | 1496 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); |
| 1499 | 1497 | unsigned pin = d->hwirq; |
| 1500 | 1498 | |
| 1501 | − gpio_irq_mask(d); | |
| 1502 | 1499 | gpiochip_unlock_as_irq(&at91_gpio->chip, pin); |
| 1503 | 1500 | } |
| 1504 | 1501 | |
| @@ -1577,8 +1574,8 @@ void at91_pinctrl_gpio_resume(void) · 72 unmodified lines | ||
| 1577 | 1574 | static struct irq_chip gpio_irqchip = { |
| 1578 | 1575 | .name = "GPIO", |
| 1579 | 1576 | .irq_ack = gpio_irq_ack, |
| 1580 | − .irq_startup = gpio_irq_startup, | |
| 1581 | − .irq_shutdown = gpio_irq_shutdown, | |
| 1577 | + .irq_request_resources = gpio_irq_request_res, | |
| 1578 | + .irq_release_resources = gpio_irq_release_res, | |
| 1582 | 1579 | .irq_disable = gpio_irq_mask, |
| 1583 | 1580 | .irq_mask = gpio_irq_mask, |
| 1584 | 1581 | .irq_unmask = gpio_irq_unmask, |
| @@ -1011,6 +1011,7 @@ static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = { · 1010 unmodified lines | ||
| 1011 | 1011 | .pins = sun4i_a10_pins, |
| 1012 | 1012 | .npins = ARRAY_SIZE(sun4i_a10_pins), |
| 1013 | 1013 | .irq_banks = 1, |
| 1014 | + .irq_read_needs_mux = true, | |
| 1014 | 1015 | }; |
| 1015 | 1016 | |
| 1016 | 1017 | static int sun4i_a10_pinctrl_probe(struct platform_device *pdev) |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/slab.h> |
| 30 | 30 | |
| 31 | 31 | #include "../core.h" |
| 32 | +#include "../../gpio/gpiolib.h" | |
| 32 | 33 | #include "pinctrl-sunxi.h" |
| 33 | 34 | |
| 34 | 35 | static struct irq_chip sunxi_pinctrl_edge_irq_chip; |
| @@ -464,10 +465,19 @@ static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip, · 429 unmodified lines | ||
| 464 | 465 | static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 465 | 466 | { |
| 466 | 467 | struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); |
| 467 | − | |
| 468 | 468 | u32 reg = sunxi_data_reg(offset); |
| 469 | 469 | u8 index = sunxi_data_offset(offset); |
| 470 | − u32 val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK; | |
| 470 | + u32 set_mux = pctl->desc->irq_read_needs_mux && | |
| 471 | + test_bit(FLAG_USED_AS_IRQ, &chip->desc[offset].flags); | |
| 472 | + u32 val; | |
| 473 | + | |
| 474 | + if (set_mux) | |
| 475 | + sunxi_pmx_set(pctl->pctl_dev, offset, SUN4I_FUNC_INPUT); | |
| 476 | + | |
| 477 | + val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK; | |
| 478 | + | |
| 479 | + if (set_mux) | |
| 480 | + sunxi_pmx_set(pctl->pctl_dev, offset, SUN4I_FUNC_IRQ); | |
| 471 | 481 | |
| 472 | 482 | return val; |
| 473 | 483 | } |
| @@ -77,6 +77,9 @@ · 76 unmodified lines | ||
| 77 | 77 | #define IRQ_LEVEL_LOW 0x03 |
| 78 | 78 | #define IRQ_EDGE_BOTH 0x04 |
| 79 | 79 | |
| 80 | +#define SUN4I_FUNC_INPUT 0 | |
| 81 | +#define SUN4I_FUNC_IRQ 6 | |
| 82 | + | |
| 80 | 83 | struct sunxi_desc_function { |
| 81 | 84 | const char *name; |
| 82 | 85 | u8 muxval; |
| @@ -94,6 +97,7 @@ struct sunxi_pinctrl_desc { · 11 unmodified lines | ||
| 94 | 97 | int npins; |
| 95 | 98 | unsigned pin_base; |
| 96 | 99 | unsigned irq_banks; |
| 100 | + bool irq_read_needs_mux; | |
| 97 | 101 | }; |
| 98 | 102 | |
| 99 | 103 | struct sunxi_pinctrl_function { |
| @@ -73,7 +73,7 @@ · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | #define TIME_WINDOW_MAX_MSEC 40000 |
| 75 | 75 | #define TIME_WINDOW_MIN_MSEC 250 |
| 76 | − | |
| 76 | +#define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */ | |
| 77 | 77 | enum unit_type { |
| 78 | 78 | ARBITRARY_UNIT, /* no translation */ |
| 79 | 79 | POWER_UNIT, |
| @@ -158,6 +158,7 @@ struct rapl_domain { · 78 unmodified lines | ||
| 158 | 158 | struct rapl_power_limit rpl[NR_POWER_LIMITS]; |
| 159 | 159 | u64 attr_map; /* track capabilities */ |
| 160 | 160 | unsigned int state; |
| 161 | + unsigned int domain_energy_unit; | |
| 161 | 162 | int package_id; |
| 162 | 163 | }; |
| 163 | 164 | #define power_zone_to_rapl_domain(_zone) \ |
| @@ -190,6 +191,7 @@ struct rapl_defaults { · 26 unmodified lines | ||
| 190 | 191 | void (*set_floor_freq)(struct rapl_domain *rd, bool mode); |
| 191 | 192 | u64 (*compute_time_window)(struct rapl_package *rp, u64 val, |
| 192 | 193 | bool to_raw); |
| 194 | + unsigned int dram_domain_energy_unit; | |
| 193 | 195 | }; |
| 194 | 196 | static struct rapl_defaults *rapl_defaults; |
| 195 | 197 | |
| @@ -227,7 +229,8 @@ static int rapl_read_data_raw(struct rapl_domain *rd, · 31 unmodified lines | ||
| 227 | 229 | static int rapl_write_data_raw(struct rapl_domain *rd, |
| 228 | 230 | enum rapl_primitives prim, |
| 229 | 231 | unsigned long long value); |
| 230 | −static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | |
| 232 | +static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, | |
| 233 | + enum unit_type type, u64 value, | |
| 231 | 234 | int to_raw); |
| 232 | 235 | static void package_power_limit_irq_save(int package_id); |
| 233 | 236 | |
| @@ -305,7 +308,9 @@ static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw) · 71 unmodified lines | ||
| 305 | 308 | |
| 306 | 309 | static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy) |
| 307 | 310 | { |
| 308 | − *energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); | |
| 311 | + struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev); | |
| 312 | + | |
| 313 | + *energy = rapl_unit_xlate(rd, 0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); | |
| 309 | 314 | return 0; |
| 310 | 315 | } |
| 311 | 316 | |
| @@ -639,6 +644,11 @@ static void rapl_init_domains(struct rapl_package *rp) · 327 unmodified lines | ||
| 639 | 644 | rd->msrs[4] = MSR_DRAM_POWER_INFO; |
| 640 | 645 | rd->rpl[0].prim_id = PL1_ENABLE; |
| 641 | 646 | rd->rpl[0].name = pl1_name; |
| 647 | + rd->domain_energy_unit = | |
| 648 | + rapl_defaults->dram_domain_energy_unit; | |
| 649 | + if (rd->domain_energy_unit) | |
| 650 | + pr_info("DRAM domain energy unit %dpj\n", | |
| 651 | + rd->domain_energy_unit); | |
| 642 | 652 | break; |
| 643 | 653 | } |
| 644 | 654 | if (mask) { |
| @@ -648,11 +658,13 @@ static void rapl_init_domains(struct rapl_package *rp) · 3 unmodified lines | ||
| 648 | 658 | } |
| 649 | 659 | } |
| 650 | 660 | |
| 651 | −static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | |
| 661 | +static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, | |
| 662 | + enum unit_type type, u64 value, | |
| 652 | 663 | int to_raw) |
| 653 | 664 | { |
| 654 | 665 | u64 units = 1; |
| 655 | 666 | struct rapl_package *rp; |
| 667 | + u64 scale = 1; | |
| 656 | 668 | |
| 657 | 669 | rp = find_package_by_id(package); |
| 658 | 670 | if (!rp) |
| @@ -663,7 +675,12 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, · 4 unmodified lines | ||
| 663 | 675 | units = rp->power_unit; |
| 664 | 676 | break; |
| 665 | 677 | case ENERGY_UNIT: |
| 666 | − units = rp->energy_unit; | |
| 678 | + scale = ENERGY_UNIT_SCALE; | |
| 679 | + /* per domain unit takes precedence */ | |
| 680 | + if (rd && rd->domain_energy_unit) | |
| 681 | + units = rd->domain_energy_unit; | |
| 682 | + else | |
| 683 | + units = rp->energy_unit; | |
| 667 | 684 | break; |
| 668 | 685 | case TIME_UNIT: |
| 669 | 686 | return rapl_defaults->compute_time_window(rp, value, to_raw); |
| @@ -673,11 +690,11 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, · 3 unmodified lines | ||
| 673 | 690 | }; |
| 674 | 691 | |
| 675 | 692 | if (to_raw) |
| 676 | − return div64_u64(value, units); | |
| 693 | + return div64_u64(value, units) * scale; | |
| 677 | 694 | |
| 678 | 695 | value *= units; |
| 679 | 696 | |
| 680 | − return value; | |
| 697 | + return div64_u64(value, scale); | |
| 681 | 698 | } |
| 682 | 699 | |
| 683 | 700 | /* in the order of enum rapl_primitives */ |
| @@ -773,7 +790,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, · 89 unmodified lines | ||
| 773 | 790 | final = value & rp->mask; |
| 774 | 791 | final = final >> rp->shift; |
| 775 | 792 | if (xlate) |
| 776 | − *data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0); | |
| 793 | + *data = rapl_unit_xlate(rd, rd->package_id, rp->unit, final, 0); | |
| 777 | 794 | else |
| 778 | 795 | *data = final; |
| 779 | 796 | |
| @@ -799,7 +816,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, · 19 unmodified lines | ||
| 799 | 816 | "failed to read msr 0x%x on cpu %d\n", msr, cpu); |
| 800 | 817 | return -EIO; |
| 801 | 818 | } |
| 802 | − value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1); | |
| 819 | + value = rapl_unit_xlate(rd, rd->package_id, rp->unit, value, 1); | |
| 803 | 820 | msr_val &= ~rp->mask; |
| 804 | 821 | msr_val |= value << rp->shift; |
| 805 | 822 | if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) { |
| @@ -818,7 +835,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, · 12 unmodified lines | ||
| 818 | 835 | * calculate units differ on different CPUs. |
| 819 | 836 | * We convert the units to below format based on CPUs. |
| 820 | 837 | * i.e. |
| 821 | − * energy unit: microJoules : Represented in microJoules by default | |
| 838 | + * energy unit: picoJoules : Represented in picoJoules by default | |
| 822 | 839 | * power unit : microWatts : Represented in milliWatts by default |
| 823 | 840 | * time unit : microseconds: Represented in seconds by default |
| 824 | 841 | */ |
| @@ -834,7 +851,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu) · 9 unmodified lines | ||
| 834 | 851 | } |
| 835 | 852 | |
| 836 | 853 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; |
| 837 | − rp->energy_unit = 1000000 / (1 << value); | |
| 854 | + rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value); | |
| 838 | 855 | |
| 839 | 856 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; |
| 840 | 857 | rp->power_unit = 1000000 / (1 << value); |
| @@ -842,7 +859,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu) · 1 unmodified line | ||
| 842 | 859 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; |
| 843 | 860 | rp->time_unit = 1000000 / (1 << value); |
| 844 | 861 | |
| 845 | − pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n", | |
| 862 | + pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n", | |
| 846 | 863 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); |
| 847 | 864 | |
| 848 | 865 | return 0; |
| @@ -859,7 +876,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu) · 10 unmodified lines | ||
| 859 | 876 | return -ENODEV; |
| 860 | 877 | } |
| 861 | 878 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; |
| 862 | − rp->energy_unit = 1 << value; | |
| 879 | + rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value; | |
| 863 | 880 | |
| 864 | 881 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; |
| 865 | 882 | rp->power_unit = (1 << value) * 1000; |
| @@ -867,7 +884,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu) · 1 unmodified line | ||
| 867 | 884 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; |
| 868 | 885 | rp->time_unit = 1000000 / (1 << value); |
| 869 | 886 | |
| 870 | − pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n", | |
| 887 | + pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n", | |
| 871 | 888 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); |
| 872 | 889 | |
| 873 | 890 | return 0; |
| @@ -1017,6 +1034,13 @@ static const struct rapl_defaults rapl_defaults_core = { · 143 unmodified lines | ||
| 1017 | 1034 | .compute_time_window = rapl_compute_time_window_core, |
| 1018 | 1035 | }; |
| 1019 | 1036 | |
| 1037 | +static const struct rapl_defaults rapl_defaults_hsw_server = { | |
| 1038 | + .check_unit = rapl_check_unit_core, | |
| 1039 | + .set_floor_freq = set_floor_freq_default, | |
| 1040 | + .compute_time_window = rapl_compute_time_window_core, | |
| 1041 | + .dram_domain_energy_unit = 15300, | |
| 1042 | +}; | |
| 1043 | + | |
| 1020 | 1044 | static const struct rapl_defaults rapl_defaults_atom = { |
| 1021 | 1045 | .check_unit = rapl_check_unit_atom, |
| 1022 | 1046 | .set_floor_freq = set_floor_freq_atom, |
| @@ -1037,7 +1061,7 @@ static const struct x86_cpu_id rapl_ids[] = { · 14 unmodified lines | ||
| 1037 | 1061 | RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ |
| 1038 | 1062 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ |
| 1039 | 1063 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ |
| 1040 | − RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ | |
| 1064 | + RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ | |
| 1041 | 1065 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ |
| 1042 | 1066 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ |
| 1043 | 1067 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ |
| @@ -1839,10 +1839,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev) · 1838 unmodified lines | ||
| 1839 | 1839 | } |
| 1840 | 1840 | |
| 1841 | 1841 | if (rdev->ena_pin) { |
| 1842 | − ret = regulator_ena_gpio_ctrl(rdev, true); | |
| 1843 | − if (ret < 0) | |
| 1844 | − return ret; | |
| 1845 | − rdev->ena_gpio_state = 1; | |
| 1842 | + if (!rdev->ena_gpio_state) { | |
| 1843 | + ret = regulator_ena_gpio_ctrl(rdev, true); | |
| 1844 | + if (ret < 0) | |
| 1845 | + return ret; | |
| 1846 | + rdev->ena_gpio_state = 1; | |
| 1847 | + } | |
| 1846 | 1848 | } else if (rdev->desc->ops->enable) { |
| 1847 | 1849 | ret = rdev->desc->ops->enable(rdev); |
| 1848 | 1850 | if (ret < 0) |
| @@ -1939,10 +1941,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev) · 90 unmodified lines | ||
| 1939 | 1941 | trace_regulator_disable(rdev_get_name(rdev)); |
| 1940 | 1942 | |
| 1941 | 1943 | if (rdev->ena_pin) { |
| 1942 | − ret = regulator_ena_gpio_ctrl(rdev, false); | |
| 1943 | − if (ret < 0) | |
| 1944 | − return ret; | |
| 1945 | − rdev->ena_gpio_state = 0; | |
| 1944 | + if (rdev->ena_gpio_state) { | |
| 1945 | + ret = regulator_ena_gpio_ctrl(rdev, false); | |
| 1946 | + if (ret < 0) | |
| 1947 | + return ret; | |
| 1948 | + rdev->ena_gpio_state = 0; | |
| 1949 | + } | |
| 1946 | 1950 | |
| 1947 | 1951 | } else if (rdev->desc->ops->disable) { |
| 1948 | 1952 | ret = rdev->desc->ops->disable(rdev); |
| @@ -3444,13 +3448,6 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, · 1495 unmodified lines | ||
| 3444 | 3448 | if (attr == &dev_attr_requested_microamps.attr) |
| 3445 | 3449 | return rdev->desc->type == REGULATOR_CURRENT ? mode : 0; |
| 3446 | 3450 | |
| 3447 | − /* all the other attributes exist to support constraints; | |
| 3448 | − * don't show them if there are no constraints, or if the | |
| 3449 | − * relevant supporting methods are missing. | |
| 3450 | − */ | |
| 3451 | − if (!rdev->constraints) | |
| 3452 | − return 0; | |
| 3453 | − | |
| 3454 | 3451 | /* constraints need specific supporting methods */ |
| 3455 | 3452 | if (attr == &dev_attr_min_microvolts.attr || |
| 3456 | 3453 | attr == &dev_attr_max_microvolts.attr) |
| @@ -3633,12 +3630,6 @@ regulator_register(const struct regulator_desc *regulator_desc, · 176 unmodified lines | ||
| 3633 | 3630 | config->ena_gpio, ret); |
| 3634 | 3631 | goto wash; |
| 3635 | 3632 | } |
| 3636 | − | |
| 3637 | − if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH) | |
| 3638 | − rdev->ena_gpio_state = 1; | |
| 3639 | − | |
| 3640 | − if (config->ena_gpio_invert) | |
| 3641 | − rdev->ena_gpio_state = !rdev->ena_gpio_state; | |
| 3642 | 3633 | } |
| 3643 | 3634 | |
| 3644 | 3635 | /* set regulator constraints */ |
| @@ -3807,9 +3798,11 @@ int regulator_suspend_finish(void) · 162 unmodified lines | ||
| 3807 | 3798 | list_for_each_entry(rdev, ®ulator_list, list) { |
| 3808 | 3799 | mutex_lock(&rdev->mutex); |
| 3809 | 3800 | if (rdev->use_count > 0 || rdev->constraints->always_on) { |
| 3810 | − error = _regulator_do_enable(rdev); | |
| 3811 | − if (error) | |
| 3812 | − ret = error; | |
| 3801 | + if (!_regulator_is_enabled(rdev)) { | |
| 3802 | + error = _regulator_do_enable(rdev); | |
| 3803 | + if (error) | |
| 3804 | + ret = error; | |
| 3805 | + } | |
| 3813 | 3806 | } else { |
| 3814 | 3807 | if (!have_full_constraints()) |
| 3815 | 3808 | goto unlock; |
| @@ -152,6 +152,15 @@ static int da9210_i2c_probe(struct i2c_client *i2c, · 151 unmodified lines | ||
| 152 | 152 | config.regmap = chip->regmap; |
| 153 | 153 | config.of_node = dev->of_node; |
| 154 | 154 | |
| 155 | + /* Mask all interrupt sources to deassert interrupt line */ | |
| 156 | + error = regmap_write(chip->regmap, DA9210_REG_MASK_A, ~0); | |
| 157 | + if (!error) | |
| 158 | + error = regmap_write(chip->regmap, DA9210_REG_MASK_B, ~0); | |
| 159 | + if (error) { | |
| 160 | + dev_err(&i2c->dev, "Failed to write to mask reg: %d\n", error); | |
| 161 | + return error; | |
| 162 | + } | |
| 163 | + | |
| 155 | 164 | rdev = devm_regulator_register(&i2c->dev, &da9210_reg, &config); |
| 156 | 165 | if (IS_ERR(rdev)) { |
| 157 | 166 | dev_err(&i2c->dev, "Failed to register DA9210 regulator\n"); |
| @@ -235,6 +235,7 @@ static const struct regulator_desc rk808_reg[] = { · 234 unmodified lines | ||
| 235 | 235 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 236 | 236 | .enable_reg = RK808_LDO_EN_REG, |
| 237 | 237 | .enable_mask = BIT(0), |
| 238 | + .enable_time = 400, | |
| 238 | 239 | .owner = THIS_MODULE, |
| 239 | 240 | }, { |
| 240 | 241 | .name = "LDO_REG2", |
| @@ -249,6 +250,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 249 | 250 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 250 | 251 | .enable_reg = RK808_LDO_EN_REG, |
| 251 | 252 | .enable_mask = BIT(1), |
| 253 | + .enable_time = 400, | |
| 252 | 254 | .owner = THIS_MODULE, |
| 253 | 255 | }, { |
| 254 | 256 | .name = "LDO_REG3", |
| @@ -263,6 +265,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 263 | 265 | .vsel_mask = RK808_BUCK4_VSEL_MASK, |
| 264 | 266 | .enable_reg = RK808_LDO_EN_REG, |
| 265 | 267 | .enable_mask = BIT(2), |
| 268 | + .enable_time = 400, | |
| 266 | 269 | .owner = THIS_MODULE, |
| 267 | 270 | }, { |
| 268 | 271 | .name = "LDO_REG4", |
| @@ -277,6 +280,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 277 | 280 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 278 | 281 | .enable_reg = RK808_LDO_EN_REG, |
| 279 | 282 | .enable_mask = BIT(3), |
| 283 | + .enable_time = 400, | |
| 280 | 284 | .owner = THIS_MODULE, |
| 281 | 285 | }, { |
| 282 | 286 | .name = "LDO_REG5", |
| @@ -291,6 +295,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 291 | 295 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 292 | 296 | .enable_reg = RK808_LDO_EN_REG, |
| 293 | 297 | .enable_mask = BIT(4), |
| 298 | + .enable_time = 400, | |
| 294 | 299 | .owner = THIS_MODULE, |
| 295 | 300 | }, { |
| 296 | 301 | .name = "LDO_REG6", |
| @@ -305,6 +310,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 305 | 310 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 306 | 311 | .enable_reg = RK808_LDO_EN_REG, |
| 307 | 312 | .enable_mask = BIT(5), |
| 313 | + .enable_time = 400, | |
| 308 | 314 | .owner = THIS_MODULE, |
| 309 | 315 | }, { |
| 310 | 316 | .name = "LDO_REG7", |
| @@ -319,6 +325,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 319 | 325 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 320 | 326 | .enable_reg = RK808_LDO_EN_REG, |
| 321 | 327 | .enable_mask = BIT(6), |
| 328 | + .enable_time = 400, | |
| 322 | 329 | .owner = THIS_MODULE, |
| 323 | 330 | }, { |
| 324 | 331 | .name = "LDO_REG8", |
| @@ -333,6 +340,7 @@ static const struct regulator_desc rk808_reg[] = { · 8 unmodified lines | ||
| 333 | 340 | .vsel_mask = RK808_LDO_VSEL_MASK, |
| 334 | 341 | .enable_reg = RK808_LDO_EN_REG, |
| 335 | 342 | .enable_mask = BIT(7), |
| 343 | + .enable_time = 400, | |
| 336 | 344 | .owner = THIS_MODULE, |
| 337 | 345 | }, { |
| 338 | 346 | .name = "SWITCH_REG1", |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/module.h> |
| 18 | 18 | #include <linux/init.h> |
| 19 | 19 | #include <linux/err.h> |
| 20 | +#include <linux/of.h> | |
| 20 | 21 | #include <linux/platform_device.h> |
| 21 | 22 | #include <linux/regulator/driver.h> |
| 22 | 23 | #include <linux/regulator/machine.h> |
| @@ -951,6 +951,7 @@ static int rpmsg_probe(struct virtio_device *vdev) · 950 unmodified lines | ||
| 951 | 951 | void *bufs_va; |
| 952 | 952 | int err = 0, i; |
| 953 | 953 | size_t total_buf_space; |
| 954 | + bool notify; | |
| 954 | 955 | |
| 955 | 956 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); |
| 956 | 957 | if (!vrp) |
| @@ -1030,8 +1031,22 @@ static int rpmsg_probe(struct virtio_device *vdev) · 73 unmodified lines | ||
| 1030 | 1031 | } |
| 1031 | 1032 | } |
| 1032 | 1033 | |
| 1034 | + /* | |
| 1035 | + * Prepare to kick but don't notify yet - we can't do this before | |
| 1036 | + * device is ready. | |
| 1037 | + */ | |
| 1038 | + notify = virtqueue_kick_prepare(vrp->rvq); | |
| 1039 | + | |
| 1040 | + /* From this point on, we can notify and get callbacks. */ | |
| 1041 | + virtio_device_ready(vdev); | |
| 1042 | + | |
| 1033 | 1043 | /* tell the remote processor it can start sending messages */ |
| 1034 | − virtqueue_kick(vrp->rvq); | |
| 1044 | + /* | |
| 1045 | + * this might be concurrent with callbacks, but we are only | |
| 1046 | + * doing notify, not a full kick here, so that's ok. | |
| 1047 | + */ | |
| 1048 | + if (notify) | |
| 1049 | + virtqueue_notify(vrp->rvq); | |
| 1035 | 1050 | |
| 1036 | 1051 | dev_info(&vdev->dev, "rpmsg host is online\n"); |
| 1037 | 1052 | |
| @@ -324,7 +324,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) · 323 unmodified lines | ||
| 324 | 324 | |
| 325 | 325 | ret = IRQ_HANDLED; |
| 326 | 326 | } |
| 327 | − spin_lock(&suspended_lock); | |
| 327 | + spin_unlock(&suspended_lock); | |
| 328 | 328 | |
| 329 | 329 | return ret; |
| 330 | 330 | } |
| @@ -849,6 +849,7 @@ static struct s3c_rtc_data const s3c2443_rtc_data = { · 848 unmodified lines | ||
| 849 | 849 | |
| 850 | 850 | static struct s3c_rtc_data const s3c6410_rtc_data = { |
| 851 | 851 | .max_user_freq = 32768, |
| 852 | + .needs_src_clk = true, | |
| 852 | 853 | .irq_handler = s3c6410_rtc_irq, |
| 853 | 854 | .set_freq = s3c6410_rtc_setfreq, |
| 854 | 855 | .enable_tick = s3c6410_rtc_enable_tick, |
| @@ -547,7 +547,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char · 546 unmodified lines | ||
| 547 | 547 | * parse input |
| 548 | 548 | */ |
| 549 | 549 | num_of_segments = 0; |
| 550 | − for (i = 0; ((buf[i] != '\0') && (buf[i] != '\n') && i < count); i++) { | |
| 550 | + for (i = 0; (i < count && (buf[i] != '\0') && (buf[i] != '\n')); i++) { | |
| 551 | 551 | for (j = i; (buf[j] != ':') && |
| 552 | 552 | (buf[j] != '\0') && |
| 553 | 553 | (buf[j] != '\n') && |
| @@ -92,7 +92,7 @@ bool scm_reserve_cluster(struct scm_request *scmrq) · 91 unmodified lines | ||
| 92 | 92 | add = 0; |
| 93 | 93 | continue; |
| 94 | 94 | } |
| 95 | − for (pos = 0; pos <= iter->aob->request.msb_count; pos++) { | |
| 95 | + for (pos = 0; pos < iter->aob->request.msb_count; pos++) { | |
| 96 | 96 | if (clusters_intersect(req, iter->request[pos]) && |
| 97 | 97 | (rq_data_dir(req) == WRITE || |
| 98 | 98 | rq_data_dir(iter->request[pos]) == WRITE)) { |
| @@ -500,6 +500,7 @@ static void sas_revalidate_domain(struct work_struct *work) · 499 unmodified lines | ||
| 500 | 500 | struct sas_discovery_event *ev = to_sas_discovery_event(work); |
| 501 | 501 | struct asd_sas_port *port = ev->port; |
| 502 | 502 | struct sas_ha_struct *ha = port->ha; |
| 503 | + struct domain_device *ddev = port->port_dev; | |
| 503 | 504 | |
| 504 | 505 | /* prevent revalidation from finding sata links in recovery */ |
| 505 | 506 | mutex_lock(&ha->disco_mutex); |
| @@ -514,8 +515,9 @@ static void sas_revalidate_domain(struct work_struct *work) · 8 unmodified lines | ||
| 514 | 515 | SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, |
| 515 | 516 | task_pid_nr(current)); |
| 516 | 517 | |
| 517 | − if (port->port_dev) | |
| 518 | − res = sas_ex_revalidate_domain(port->port_dev); | |
| 518 | + if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE || | |
| 519 | + ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE)) | |
| 520 | + res = sas_ex_revalidate_domain(ddev); | |
| 519 | 521 | |
| 520 | 522 | SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n", |
| 521 | 523 | port->id, task_pid_nr(current), res); |
| @@ -1596,7 +1596,7 @@ static int tcm_qla2xxx_check_initiator_node_acl( · 1595 unmodified lines | ||
| 1596 | 1596 | /* |
| 1597 | 1597 | * Finally register the new FC Nexus with TCM |
| 1598 | 1598 | */ |
| 1599 | − __transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess); | |
| 1599 | + transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess); | |
| 1600 | 1600 | |
| 1601 | 1601 | return 0; |
| 1602 | 1602 | } |
| @@ -764,17 +764,17 @@ static void atmel_spi_pdc_next_xfer(struct spi_master *master, · 763 unmodified lines | ||
| 764 | 764 | (unsigned long long)xfer->rx_dma); |
| 765 | 765 | } |
| 766 | 766 | |
| 767 | − /* REVISIT: We're waiting for ENDRX before we start the next | |
| 767 | + /* REVISIT: We're waiting for RXBUFF before we start the next | |
| 768 | 768 | * transfer because we need to handle some difficult timing |
| 769 | − * issues otherwise. If we wait for ENDTX in one transfer and | |
| 770 | − * then starts waiting for ENDRX in the next, it's difficult | |
| 771 | − * to tell the difference between the ENDRX interrupt we're | |
| 772 | − * actually waiting for and the ENDRX interrupt of the | |
| 769 | + * issues otherwise. If we wait for TXBUFE in one transfer and | |
| 770 | + * then starts waiting for RXBUFF in the next, it's difficult | |
| 771 | + * to tell the difference between the RXBUFF interrupt we're | |
| 772 | + * actually waiting for and the RXBUFF interrupt of the | |
| 773 | 773 | * previous transfer. |
| 774 | 774 | * |
| 775 | 775 | * It should be doable, though. Just not now... |
| 776 | 776 | */ |
| 777 | − spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); | |
| 777 | + spi_writel(as, IER, SPI_BIT(RXBUFF) | SPI_BIT(OVRES)); | |
| 778 | 778 | spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); |
| 779 | 779 | } |
| 780 | 780 | |
| @@ -139,6 +139,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws) · 138 unmodified lines | ||
| 139 | 139 | 1, |
| 140 | 140 | DMA_MEM_TO_DEV, |
| 141 | 141 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 142 | + if (!txdesc) | |
| 143 | + return NULL; | |
| 144 | + | |
| 142 | 145 | txdesc->callback = dw_spi_dma_tx_done; |
| 143 | 146 | txdesc->callback_param = dws; |
| 144 | 147 | |
| @@ -184,6 +187,9 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws) · 39 unmodified lines | ||
| 184 | 187 | 1, |
| 185 | 188 | DMA_DEV_TO_MEM, |
| 186 | 189 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 190 | + if (!rxdesc) | |
| 191 | + return NULL; | |
| 192 | + | |
| 187 | 193 | rxdesc->callback = dw_spi_dma_rx_done; |
| 188 | 194 | rxdesc->callback_param = dws; |
| 189 | 195 | |
| @@ -36,13 +36,13 @@ struct spi_pci_desc { · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | static struct spi_pci_desc spi_pci_mid_desc_1 = { |
| 38 | 38 | .setup = dw_spi_mid_init, |
| 39 | − .num_cs = 32, | |
| 39 | + .num_cs = 5, | |
| 40 | 40 | .bus_num = 0, |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | 43 | static struct spi_pci_desc spi_pci_mid_desc_2 = { |
| 44 | 44 | .setup = dw_spi_mid_init, |
| 45 | − .num_cs = 4, | |
| 45 | + .num_cs = 2, | |
| 46 | 46 | .bus_num = 1, |
| 47 | 47 | }; |
| 48 | 48 | |
| @@ -621,14 +621,14 @@ static void spi_hw_init(struct device *dev, struct dw_spi *dws) · 620 unmodified lines | ||
| 621 | 621 | if (!dws->fifo_len) { |
| 622 | 622 | u32 fifo; |
| 623 | 623 | |
| 624 | − for (fifo = 2; fifo <= 256; fifo++) { | |
| 624 | + for (fifo = 1; fifo < 256; fifo++) { | |
| 625 | 625 | dw_writew(dws, DW_SPI_TXFLTR, fifo); |
| 626 | 626 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) |
| 627 | 627 | break; |
| 628 | 628 | } |
| 629 | 629 | dw_writew(dws, DW_SPI_TXFLTR, 0); |
| 630 | 630 | |
| 631 | − dws->fifo_len = (fifo == 2) ? 0 : fifo - 1; | |
| 631 | + dws->fifo_len = (fifo == 1) ? 0 : fifo; | |
| 632 | 632 | dev_dbg(dev, "Detected FIFO size: %u bytes\n", dws->fifo_len); |
| 633 | 633 | } |
| 634 | 634 | } |
| @@ -459,6 +459,13 @@ static int img_spfi_transfer_one(struct spi_master *master, · 458 unmodified lines | ||
| 459 | 459 | unsigned long flags; |
| 460 | 460 | int ret; |
| 461 | 461 | |
| 462 | + if (xfer->len > SPFI_TRANSACTION_TSIZE_MASK) { | |
| 463 | + dev_err(spfi->dev, | |
| 464 | + "Transfer length (%d) is greater than the max supported (%d)", | |
| 465 | + xfer->len, SPFI_TRANSACTION_TSIZE_MASK); | |
| 466 | + return -EINVAL; | |
| 467 | + } | |
| 468 | + | |
| 462 | 469 | /* |
| 463 | 470 | * Stop all DMA and reset the controller if the previous transaction |
| 464 | 471 | * timed-out and never completed it's DMA. |
| @@ -534,12 +534,12 @@ static void giveback(struct pl022 *pl022) · 533 unmodified lines | ||
| 534 | 534 | pl022->cur_msg = NULL; |
| 535 | 535 | pl022->cur_transfer = NULL; |
| 536 | 536 | pl022->cur_chip = NULL; |
| 537 | − spi_finalize_current_message(pl022->master); | |
| 538 | 537 | |
| 539 | 538 | /* disable the SPI/SSP operation */ |
| 540 | 539 | writew((readw(SSP_CR1(pl022->virtbase)) & |
| 541 | 540 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); |
| 542 | 541 | |
| 542 | + spi_finalize_current_message(pl022->master); | |
| 543 | 543 | } |
| 544 | 544 | |
| 545 | 545 | /** |
| @@ -101,6 +101,7 @@ struct ti_qspi { · 100 unmodified lines | ||
| 101 | 101 | #define QSPI_FLEN(n) ((n - 1) << 0) |
| 102 | 102 | |
| 103 | 103 | /* STATUS REGISTER */ |
| 104 | +#define BUSY 0x01 | |
| 104 | 105 | #define WC 0x02 |
| 105 | 106 | |
| 106 | 107 | /* INTERRUPT REGISTER */ |
| @@ -199,6 +200,21 @@ static void ti_qspi_restore_ctx(struct ti_qspi *qspi) · 92 unmodified lines | ||
| 199 | 200 | ti_qspi_write(qspi, ctx_reg->clkctrl, QSPI_SPI_CLOCK_CNTRL_REG); |
| 200 | 201 | } |
| 201 | 202 | |
| 203 | +static inline u32 qspi_is_busy(struct ti_qspi *qspi) | |
| 204 | +{ | |
| 205 | + u32 stat; | |
| 206 | + unsigned long timeout = jiffies + QSPI_COMPLETION_TIMEOUT; | |
| 207 | + | |
| 208 | + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); | |
| 209 | + while ((stat & BUSY) && time_after(timeout, jiffies)) { | |
| 210 | + cpu_relax(); | |
| 211 | + stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); | |
| 212 | + } | |
| 213 | + | |
| 214 | + WARN(stat & BUSY, "qspi busy\n"); | |
| 215 | + return stat & BUSY; | |
| 216 | +} | |
| 217 | + | |
| 202 | 218 | static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) |
| 203 | 219 | { |
| 204 | 220 | int wlen, count; |
| @@ -211,6 +227,9 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) · 6 unmodified lines | ||
| 211 | 227 | wlen = t->bits_per_word >> 3; /* in bytes */ |
| 212 | 228 | |
| 213 | 229 | while (count) { |
| 230 | + if (qspi_is_busy(qspi)) | |
| 231 | + return -EBUSY; | |
| 232 | + | |
| 214 | 233 | switch (wlen) { |
| 215 | 234 | case 1: |
| 216 | 235 | dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", |
| @@ -266,6 +285,9 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) · 49 unmodified lines | ||
| 266 | 285 | |
| 267 | 286 | while (count) { |
| 268 | 287 | dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); |
| 288 | + if (qspi_is_busy(qspi)) | |
| 289 | + return -EBUSY; | |
| 290 | + | |
| 269 | 291 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); |
| 270 | 292 | if (!wait_for_completion_timeout(&qspi->transfer_complete, |
| 271 | 293 | QSPI_COMPLETION_TIMEOUT)) { |
| @@ -330,16 +330,6 @@ static void device_init_registers(struct vnt_private *pDevice) · 329 unmodified lines | ||
| 330 | 330 | /* zonetype initial */ |
| 331 | 331 | pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; |
| 332 | 332 | |
| 333 | − /* Get RFType */ | |
| 334 | − pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); | |
| 335 | − | |
| 336 | − /* force change RevID for VT3253 emu */ | |
| 337 | − if ((pDevice->byRFType & RF_EMU) != 0) | |
| 338 | − pDevice->byRevId = 0x80; | |
| 339 | − | |
| 340 | − pDevice->byRFType &= RF_MASK; | |
| 341 | − pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType); | |
| 342 | − | |
| 343 | 333 | if (!pDevice->bZoneRegExist) |
| 344 | 334 | pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; |
| 345 | 335 | |
| @@ -1187,12 +1177,14 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) · 841 unmodified lines | ||
| 1187 | 1177 | { |
| 1188 | 1178 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 1189 | 1179 | PSTxDesc head_td; |
| 1190 | − u32 dma_idx = TYPE_AC0DMA; | |
| 1180 | + u32 dma_idx; | |
| 1191 | 1181 | unsigned long flags; |
| 1192 | 1182 | |
| 1193 | 1183 | spin_lock_irqsave(&priv->lock, flags); |
| 1194 | 1184 | |
| 1195 | − if (!ieee80211_is_data(hdr->frame_control)) | |
| 1185 | + if (ieee80211_is_data(hdr->frame_control)) | |
| 1186 | + dma_idx = TYPE_AC0DMA; | |
| 1187 | + else | |
| 1196 | 1188 | dma_idx = TYPE_TXDMA0; |
| 1197 | 1189 | |
| 1198 | 1190 | if (AVAIL_TD(priv, dma_idx) < 1) { |
| @@ -1206,6 +1198,9 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) · 7 unmodified lines | ||
| 1206 | 1198 | |
| 1207 | 1199 | head_td->pTDInfo->skb = skb; |
| 1208 | 1200 | |
| 1201 | + if (dma_idx == TYPE_AC0DMA) | |
| 1202 | + head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; | |
| 1203 | + | |
| 1209 | 1204 | priv->iTDUsed[dma_idx]++; |
| 1210 | 1205 | |
| 1211 | 1206 | /* Take ownership */ |
| @@ -1234,13 +1229,10 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) · 22 unmodified lines | ||
| 1234 | 1229 | |
| 1235 | 1230 | head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma); |
| 1236 | 1231 | |
| 1237 | − if (dma_idx == TYPE_AC0DMA) { | |
| 1238 | − head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; | |
| 1239 | − | |
| 1232 | + if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) | |
| 1240 | 1233 | MACvTransmitAC0(priv->PortOffset); |
| 1241 | − } else { | |
| 1234 | + else | |
| 1242 | 1235 | MACvTransmit0(priv->PortOffset); |
| 1243 | − } | |
| 1244 | 1236 | |
| 1245 | 1237 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1246 | 1238 | |
| @@ -1778,6 +1770,12 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) · 531 unmodified lines | ||
| 1778 | 1770 | MACvInitialize(priv->PortOffset); |
| 1779 | 1771 | MACvReadEtherAddress(priv->PortOffset, priv->abyCurrentNetAddr); |
| 1780 | 1772 | |
| 1773 | + /* Get RFType */ | |
| 1774 | + priv->byRFType = SROMbyReadEmbedded(priv->PortOffset, EEP_OFS_RFTYPE); | |
| 1775 | + priv->byRFType &= RF_MASK; | |
| 1776 | + | |
| 1777 | + dev_dbg(&pcid->dev, "RF Type = %x\n", priv->byRFType); | |
| 1778 | + | |
| 1781 | 1779 | device_get_options(priv); |
| 1782 | 1780 | device_set_options(priv); |
| 1783 | 1781 | /* Mask out the options cannot be set to the chip */ |
| @@ -794,6 +794,7 @@ bool RFbSetPower( · 793 unmodified lines | ||
| 794 | 794 | break; |
| 795 | 795 | case RATE_6M: |
| 796 | 796 | case RATE_9M: |
| 797 | + case RATE_12M: | |
| 797 | 798 | case RATE_18M: |
| 798 | 799 | byPwr = priv->abyOFDMPwrTbl[uCH]; |
| 799 | 800 | if (priv->byRFType == RF_UW2452) |
| @@ -640,6 +640,7 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel) · 639 unmodified lines | ||
| 640 | 640 | break; |
| 641 | 641 | case RATE_6M: |
| 642 | 642 | case RATE_9M: |
| 643 | + case RATE_12M: | |
| 643 | 644 | case RATE_18M: |
| 644 | 645 | case RATE_24M: |
| 645 | 646 | case RATE_36M: |
| @@ -4256,11 +4256,17 @@ int iscsit_close_connection( · 4255 unmodified lines | ||
| 4256 | 4256 | pr_debug("Closing iSCSI connection CID %hu on SID:" |
| 4257 | 4257 | " %u\n", conn->cid, sess->sid); |
| 4258 | 4258 | /* |
| 4259 | − * Always up conn_logout_comp just in case the RX Thread is sleeping | |
| 4260 | − * and the logout response never got sent because the connection | |
| 4261 | − * failed. | |
| 4259 | + * Always up conn_logout_comp for the traditional TCP case just in case | |
| 4260 | + * the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout | |
| 4261 | + * response never got sent because the connection failed. | |
| 4262 | + * | |
| 4263 | + * However for iser-target, isert_wait4logout() is using conn_logout_comp | |
| 4264 | + * to signal logout response TX interrupt completion. Go ahead and skip | |
| 4265 | + * this for iser since isert_rx_opcode() does not wait on logout failure, | |
| 4266 | + * and to avoid iscsi_conn pointer dereference in iser-target code. | |
| 4262 | 4267 | */ |
| 4263 | − complete(&conn->conn_logout_comp); | |
| 4268 | + if (conn->conn_transport->transport_type == ISCSI_TCP) | |
| 4269 | + complete(&conn->conn_logout_comp); | |
| 4264 | 4270 | |
| 4265 | 4271 | iscsi_release_thread_set(conn); |
| 4266 | 4272 | |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <target/target_core_fabric.h> |
| 23 | 23 | |
| 24 | 24 | #include <target/iscsi/iscsi_target_core.h> |
| 25 | −#include <target/iscsi/iscsi_transport.h> | |
| 26 | 25 | #include "iscsi_target_seq_pdu_list.h" |
| 27 | 26 | #include "iscsi_target_tq.h" |
| 28 | 27 | #include "iscsi_target_erl0.h" |
| @@ -940,8 +939,7 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) · 911 unmodified lines | ||
| 940 | 939 | |
| 941 | 940 | if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) { |
| 942 | 941 | spin_unlock_bh(&conn->state_lock); |
| 943 | − if (conn->conn_transport->transport_type == ISCSI_TCP) | |
| 944 | − iscsit_close_connection(conn); | |
| 942 | + iscsit_close_connection(conn); | |
| 945 | 943 | return; |
| 946 | 944 | } |
| 947 | 945 | |
| @@ -953,11 +953,8 @@ static int tcm_loop_make_nexus( · 952 unmodified lines | ||
| 953 | 953 | transport_free_session(tl_nexus->se_sess); |
| 954 | 954 | goto out; |
| 955 | 955 | } |
| 956 | − /* | |
| 957 | − * Now, register the SAS I_T Nexus as active with the call to | |
| 958 | − * transport_register_session() | |
| 959 | − */ | |
| 960 | − __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, | |
| 956 | + /* Now, register the SAS I_T Nexus as active. */ | |
| 957 | + transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, | |
| 961 | 958 | tl_nexus->se_sess, tl_nexus); |
| 962 | 959 | tl_tpg->tl_nexus = tl_nexus; |
| 963 | 960 | pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated" |
| @@ -650,6 +650,18 @@ static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) · 649 unmodified lines | ||
| 650 | 650 | return aligned_max_sectors; |
| 651 | 651 | } |
| 652 | 652 | |
| 653 | +bool se_dev_check_wce(struct se_device *dev) | |
| 654 | +{ | |
| 655 | + bool wce = false; | |
| 656 | + | |
| 657 | + if (dev->transport->get_write_cache) | |
| 658 | + wce = dev->transport->get_write_cache(dev); | |
| 659 | + else if (dev->dev_attrib.emulate_write_cache > 0) | |
| 660 | + wce = true; | |
| 661 | + | |
| 662 | + return wce; | |
| 663 | +} | |
| 664 | + | |
| 653 | 665 | int se_dev_set_max_unmap_lba_count( |
| 654 | 666 | struct se_device *dev, |
| 655 | 667 | u32 max_unmap_lba_count) |
| @@ -767,6 +779,16 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) · 111 unmodified lines | ||
| 767 | 779 | pr_err("Illegal value %d\n", flag); |
| 768 | 780 | return -EINVAL; |
| 769 | 781 | } |
| 782 | + if (flag && | |
| 783 | + dev->transport->get_write_cache) { | |
| 784 | + pr_err("emulate_fua_write not supported for this device\n"); | |
| 785 | + return -EINVAL; | |
| 786 | + } | |
| 787 | + if (dev->export_count) { | |
| 788 | + pr_err("emulate_fua_write cannot be changed with active" | |
| 789 | + " exports: %d\n", dev->export_count); | |
| 790 | + return -EINVAL; | |
| 791 | + } | |
| 770 | 792 | dev->dev_attrib.emulate_fua_write = flag; |
| 771 | 793 | pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n", |
| 772 | 794 | dev, dev->dev_attrib.emulate_fua_write); |
| @@ -801,7 +823,11 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) · 28 unmodified lines | ||
| 801 | 823 | pr_err("emulate_write_cache not supported for this device\n"); |
| 802 | 824 | return -EINVAL; |
| 803 | 825 | } |
| 804 | − | |
| 826 | + if (dev->export_count) { | |
| 827 | + pr_err("emulate_write_cache cannot be changed with active" | |
| 828 | + " exports: %d\n", dev->export_count); | |
| 829 | + return -EINVAL; | |
| 830 | + } | |
| 805 | 831 | dev->dev_attrib.emulate_write_cache = flag; |
| 806 | 832 | pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n", |
| 807 | 833 | dev, dev->dev_attrib.emulate_write_cache); |
| @@ -1534,8 +1560,6 @@ int target_configure_device(struct se_device *dev) · 726 unmodified lines | ||
| 1534 | 1560 | ret = dev->transport->configure_device(dev); |
| 1535 | 1561 | if (ret) |
| 1536 | 1562 | goto out; |
| 1537 | − dev->dev_flags |= DF_CONFIGURED; | |
| 1538 | − | |
| 1539 | 1563 | /* |
| 1540 | 1564 | * XXX: there is not much point to have two different values here.. |
| 1541 | 1565 | */ |
| @@ -1597,6 +1621,8 @@ int target_configure_device(struct se_device *dev) · 55 unmodified lines | ||
| 1597 | 1621 | list_add_tail(&dev->g_dev_node, &g_device_list); |
| 1598 | 1622 | mutex_unlock(&g_device_mutex); |
| 1599 | 1623 | |
| 1624 | + dev->dev_flags |= DF_CONFIGURED; | |
| 1625 | + | |
| 1600 | 1626 | return 0; |
| 1601 | 1627 | |
| 1602 | 1628 | out_free_alua: |
| @@ -1121,7 +1121,7 @@ static u32 pscsi_get_device_type(struct se_device *dev) · 1120 unmodified lines | ||
| 1121 | 1121 | struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); |
| 1122 | 1122 | struct scsi_device *sd = pdv->pdv_sd; |
| 1123 | 1123 | |
| 1124 | − return sd->type; | |
| 1124 | + return (sd) ? sd->type : TYPE_NO_LUN; | |
| 1125 | 1125 | } |
| 1126 | 1126 | |
| 1127 | 1127 | static sector_t pscsi_get_blocks(struct se_device *dev) |
| @@ -708,8 +708,7 @@ sbc_check_dpofua(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb) · 707 unmodified lines | ||
| 708 | 708 | } |
| 709 | 709 | } |
| 710 | 710 | if (cdb[1] & 0x8) { |
| 711 | − if (!dev->dev_attrib.emulate_fua_write || | |
| 712 | − !dev->dev_attrib.emulate_write_cache) { | |
| 711 | + if (!dev->dev_attrib.emulate_fua_write || !se_dev_check_wce(dev)) { | |
| 713 | 712 | pr_err("Got CDB: 0x%02x with FUA bit set, but device" |
| 714 | 713 | " does not advertise support for FUA write\n", |
| 715 | 714 | cdb[0]); |
| @@ -454,19 +454,6 @@ check_scsi_name: · 453 unmodified lines | ||
| 454 | 454 | } |
| 455 | 455 | EXPORT_SYMBOL(spc_emulate_evpd_83); |
| 456 | 456 | |
| 457 | −static bool | |
| 458 | −spc_check_dev_wce(struct se_device *dev) | |
| 459 | −{ | |
| 460 | − bool wce = false; | |
| 461 | − | |
| 462 | − if (dev->transport->get_write_cache) | |
| 463 | − wce = dev->transport->get_write_cache(dev); | |
| 464 | − else if (dev->dev_attrib.emulate_write_cache > 0) | |
| 465 | − wce = true; | |
| 466 | − | |
| 467 | − return wce; | |
| 468 | −} | |
| 469 | − | |
| 470 | 457 | /* Extended INQUIRY Data VPD Page */ |
| 471 | 458 | static sense_reason_t |
| 472 | 459 | spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) |
| @@ -490,7 +477,7 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) · 17 unmodified lines | ||
| 490 | 477 | buf[5] = 0x07; |
| 491 | 478 | |
| 492 | 479 | /* If WriteCache emulation is enabled, set V_SUP */ |
| 493 | − if (spc_check_dev_wce(dev)) | |
| 480 | + if (se_dev_check_wce(dev)) | |
| 494 | 481 | buf[6] = 0x01; |
| 495 | 482 | /* If an LBA map is present set R_SUP */ |
| 496 | 483 | spin_lock(&cmd->se_dev->t10_alua.lba_map_lock); |
| @@ -897,7 +884,7 @@ static int spc_modesense_caching(struct se_cmd *cmd, u8 pc, u8 *p) · 400 unmodified lines | ||
| 897 | 884 | if (pc == 1) |
| 898 | 885 | goto out; |
| 899 | 886 | |
| 900 | − if (spc_check_dev_wce(dev)) | |
| 887 | + if (se_dev_check_wce(dev)) | |
| 901 | 888 | p[2] = 0x04; /* Write Cache Enable */ |
| 902 | 889 | p[12] = 0x20; /* Disabled Read Ahead */ |
| 903 | 890 | |
| @@ -1009,7 +996,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) · 105 unmodified lines | ||
| 1009 | 996 | (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) |
| 1010 | 997 | spc_modesense_write_protect(&buf[length], type); |
| 1011 | 998 | |
| 1012 | − if ((spc_check_dev_wce(dev)) && | |
| 999 | + if ((se_dev_check_wce(dev)) && | |
| 1013 | 1000 | (dev->dev_attrib.emulate_fua_write > 0)) |
| 1014 | 1001 | spc_modesense_dpofua(&buf[length], type); |
| 1015 | 1002 | |
| @@ -2389,6 +2389,10 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd, · 2388 unmodified lines | ||
| 2389 | 2389 | list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); |
| 2390 | 2390 | out: |
| 2391 | 2391 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
| 2392 | + | |
| 2393 | + if (ret && ack_kref) | |
| 2394 | + target_put_sess_cmd(se_sess, se_cmd); | |
| 2395 | + | |
| 2392 | 2396 | return ret; |
| 2393 | 2397 | } |
| 2394 | 2398 | EXPORT_SYMBOL(target_get_sess_cmd); |
| @@ -359,7 +359,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd) · 358 unmodified lines | ||
| 359 | 359 | ep = fc_seq_exch(seq); |
| 360 | 360 | if (ep) { |
| 361 | 361 | lport = ep->lp; |
| 362 | − if (lport && (ep->xid <= lport->lro_xid)) | |
| 362 | + if (lport && (ep->xid <= lport->lro_xid)) { | |
| 363 | 363 | /* |
| 364 | 364 | * "ddp_done" trigger invalidation of HW |
| 365 | 365 | * specific DDP context |
| @@ -374,6 +374,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd) · 8 unmodified lines | ||
| 374 | 374 | * identified using ep->xid) |
| 375 | 375 | */ |
| 376 | 376 | cmd->was_ddp_setup = 0; |
| 377 | + } | |
| 377 | 378 | } |
| 378 | 379 | } |
| 379 | 380 | } |
| @@ -119,7 +119,10 @@ static void dw8250_serial_out(struct uart_port *p, int offset, int value) · 118 unmodified lines | ||
| 119 | 119 | dw8250_force_idle(p); |
| 120 | 120 | writeb(value, p->membase + (UART_LCR << p->regshift)); |
| 121 | 121 | } |
| 122 | − dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 122 | + /* | |
| 123 | + * FIXME: this deadlocks if port->lock is already held | |
| 124 | + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 125 | + */ | |
| 123 | 126 | } |
| 124 | 127 | } |
| 125 | 128 | |
| @@ -163,7 +166,10 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value) · 37 unmodified lines | ||
| 163 | 166 | __raw_writeq(value & 0xff, |
| 164 | 167 | p->membase + (UART_LCR << p->regshift)); |
| 165 | 168 | } |
| 166 | − dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 169 | + /* | |
| 170 | + * FIXME: this deadlocks if port->lock is already held | |
| 171 | + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 172 | + */ | |
| 167 | 173 | } |
| 168 | 174 | } |
| 169 | 175 | #endif /* CONFIG_64BIT */ |
| @@ -187,7 +193,10 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value) · 17 unmodified lines | ||
| 187 | 193 | dw8250_force_idle(p); |
| 188 | 194 | writel(value, p->membase + (UART_LCR << p->regshift)); |
| 189 | 195 | } |
| 190 | − dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 196 | + /* | |
| 197 | + * FIXME: this deadlocks if port->lock is already held | |
| 198 | + * dev_err(p->dev, "Couldn't set LCR to %d\n", value); | |
| 199 | + */ | |
| 191 | 200 | } |
| 192 | 201 | } |
| 193 | 202 | |
| @@ -929,6 +929,13 @@ __acquires(hwep->lock) · 928 unmodified lines | ||
| 929 | 929 | return retval; |
| 930 | 930 | } |
| 931 | 931 | |
| 932 | +static int otg_a_alt_hnp_support(struct ci_hdrc *ci) | |
| 933 | +{ | |
| 934 | + dev_warn(&ci->gadget.dev, | |
| 935 | + "connect the device to an alternate port if you want HNP\n"); | |
| 936 | + return isr_setup_status_phase(ci); | |
| 937 | +} | |
| 938 | + | |
| 932 | 939 | /** |
| 933 | 940 | * isr_setup_packet_handler: setup packet handler |
| 934 | 941 | * @ci: UDC descriptor |
| @@ -1061,6 +1068,10 @@ __acquires(ci->lock) · 126 unmodified lines | ||
| 1061 | 1068 | ci); |
| 1062 | 1069 | } |
| 1063 | 1070 | break; |
| 1071 | + case USB_DEVICE_A_ALT_HNP_SUPPORT: | |
| 1072 | + if (ci_otg_is_fsm_mode(ci)) | |
| 1073 | + err = otg_a_alt_hnp_support(ci); | |
| 1074 | + break; | |
| 1064 | 1075 | default: |
| 1065 | 1076 | goto delegate; |
| 1066 | 1077 | } |
| @@ -150,9 +150,9 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) · 149 unmodified lines | ||
| 150 | 150 | break; |
| 151 | 151 | case OTG_STATE_B_PERIPHERAL: |
| 152 | 152 | otg_chrg_vbus(fsm, 0); |
| 153 | − otg_loc_conn(fsm, 1); | |
| 154 | 153 | otg_loc_sof(fsm, 0); |
| 155 | 154 | otg_set_protocol(fsm, PROTO_GADGET); |
| 155 | + otg_loc_conn(fsm, 1); | |
| 156 | 156 | break; |
| 157 | 157 | case OTG_STATE_B_WAIT_ACON: |
| 158 | 158 | otg_chrg_vbus(fsm, 0); |
| @@ -213,10 +213,10 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) · 54 unmodified lines | ||
| 213 | 213 | |
| 214 | 214 | break; |
| 215 | 215 | case OTG_STATE_A_PERIPHERAL: |
| 216 | − otg_loc_conn(fsm, 1); | |
| 217 | 216 | otg_loc_sof(fsm, 0); |
| 218 | 217 | otg_set_protocol(fsm, PROTO_GADGET); |
| 219 | 218 | otg_drv_vbus(fsm, 1); |
| 219 | + otg_loc_conn(fsm, 1); | |
| 220 | 220 | otg_add_timer(fsm, A_BIDL_ADIS); |
| 221 | 221 | break; |
| 222 | 222 | case OTG_STATE_A_WAIT_VFALL: |
| @@ -377,6 +377,9 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) · 376 unmodified lines | ||
| 377 | 377 | dwc2_is_host_mode(hsotg) ? "Host" : "Device", |
| 378 | 378 | dwc2_op_state_str(hsotg)); |
| 379 | 379 | |
| 380 | + if (hsotg->op_state == OTG_STATE_A_HOST) | |
| 381 | + dwc2_hcd_disconnect(hsotg); | |
| 382 | + | |
| 380 | 383 | /* Change to L3 (OFF) state */ |
| 381 | 384 | hsotg->lx_state = DWC2_L3; |
| 382 | 385 | |
| @@ -144,10 +144,9 @@ struct ffs_io_data { · 143 unmodified lines | ||
| 144 | 144 | bool read; |
| 145 | 145 | |
| 146 | 146 | struct kiocb *kiocb; |
| 147 | − const struct iovec *iovec; | |
| 148 | − unsigned long nr_segs; | |
| 149 | − char __user *buf; | |
| 150 | − size_t len; | |
| 147 | + struct iov_iter data; | |
| 148 | + const void *to_free; | |
| 149 | + char *buf; | |
| 151 | 150 | |
| 152 | 151 | struct mm_struct *mm; |
| 153 | 152 | struct work_struct work; |
| @@ -649,29 +648,10 @@ static void ffs_user_copy_worker(struct work_struct *work) · 495 unmodified lines | ||
| 649 | 648 | io_data->req->actual; |
| 650 | 649 | |
| 651 | 650 | if (io_data->read && ret > 0) { |
| 652 | − int i; | |
| 653 | − size_t pos = 0; | |
| 654 | − | |
| 655 | − /* | |
| 656 | − * Since req->length may be bigger than io_data->len (after | |
| 657 | − * being rounded up to maxpacketsize), we may end up with more | |
| 658 | − * data then user space has space for. | |
| 659 | − */ | |
| 660 | − ret = min_t(int, ret, io_data->len); | |
| 661 | − | |
| 662 | 651 | use_mm(io_data->mm); |
| 663 | − for (i = 0; i < io_data->nr_segs; i++) { | |
| 664 | − size_t len = min_t(size_t, ret - pos, | |
| 665 | − io_data->iovec[i].iov_len); | |
| 666 | − if (!len) | |
| 667 | − break; | |
| 668 | − if (unlikely(copy_to_user(io_data->iovec[i].iov_base, | |
| 669 | − &io_data->buf[pos], len))) { | |
| 670 | − ret = -EFAULT; | |
| 671 | − break; | |
| 672 | − } | |
| 673 | − pos += len; | |
| 674 | − } | |
| 652 | + ret = copy_to_iter(io_data->buf, ret, &io_data->data); | |
| 653 | + if (iov_iter_count(&io_data->data)) | |
| 654 | + ret = -EFAULT; | |
| 675 | 655 | unuse_mm(io_data->mm); |
| 676 | 656 | } |
| 677 | 657 | |
| @@ -684,7 +664,7 @@ static void ffs_user_copy_worker(struct work_struct *work) · 6 unmodified lines | ||
| 684 | 664 | |
| 685 | 665 | io_data->kiocb->private = NULL; |
| 686 | 666 | if (io_data->read) |
| 687 | − kfree(io_data->iovec); | |
| 667 | + kfree(io_data->to_free); | |
| 688 | 668 | kfree(io_data->buf); |
| 689 | 669 | kfree(io_data); |
| 690 | 670 | } |
| @@ -743,6 +723,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 52 unmodified lines | ||
| 743 | 723 | * before the waiting completes, so do not assign to 'gadget' earlier |
| 744 | 724 | */ |
| 745 | 725 | struct usb_gadget *gadget = epfile->ffs->gadget; |
| 726 | + size_t copied; | |
| 746 | 727 | |
| 747 | 728 | spin_lock_irq(&epfile->ffs->eps_lock); |
| 748 | 729 | /* In the meantime, endpoint got disabled or changed. */ |
| @@ -750,34 +731,21 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 1 unmodified line | ||
| 750 | 731 | spin_unlock_irq(&epfile->ffs->eps_lock); |
| 751 | 732 | return -ESHUTDOWN; |
| 752 | 733 | } |
| 734 | + data_len = iov_iter_count(&io_data->data); | |
| 753 | 735 | /* |
| 754 | 736 | * Controller may require buffer size to be aligned to |
| 755 | 737 | * maxpacketsize of an out endpoint. |
| 756 | 738 | */ |
| 757 | − data_len = io_data->read ? | |
| 758 | − usb_ep_align_maybe(gadget, ep->ep, io_data->len) : | |
| 759 | − io_data->len; | |
| 739 | + if (io_data->read) | |
| 740 | + data_len = usb_ep_align_maybe(gadget, ep->ep, data_len); | |
| 760 | 741 | spin_unlock_irq(&epfile->ffs->eps_lock); |
| 761 | 742 | |
| 762 | 743 | data = kmalloc(data_len, GFP_KERNEL); |
| 763 | 744 | if (unlikely(!data)) |
| 764 | 745 | return -ENOMEM; |
| 765 | − if (io_data->aio && !io_data->read) { | |
| 766 | − int i; | |
| 767 | − size_t pos = 0; | |
| 768 | − for (i = 0; i < io_data->nr_segs; i++) { | |
| 769 | − if (unlikely(copy_from_user(&data[pos], | |
| 770 | − io_data->iovec[i].iov_base, | |
| 771 | − io_data->iovec[i].iov_len))) { | |
| 772 | − ret = -EFAULT; | |
| 773 | − goto error; | |
| 774 | − } | |
| 775 | − pos += io_data->iovec[i].iov_len; | |
| 776 | − } | |
| 777 | − } else { | |
| 778 | − if (!io_data->read && | |
| 779 | − unlikely(__copy_from_user(data, io_data->buf, | |
| 780 | − io_data->len))) { | |
| 746 | + if (!io_data->read) { | |
| 747 | + copied = copy_from_iter(data, data_len, &io_data->data); | |
| 748 | + if (copied != data_len) { | |
| 781 | 749 | ret = -EFAULT; |
| 782 | 750 | goto error; |
| 783 | 751 | } |
| @@ -876,10 +844,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) · 92 unmodified lines | ||
| 876 | 844 | */ |
| 877 | 845 | ret = ep->status; |
| 878 | 846 | if (io_data->read && ret > 0) { |
| 879 | − ret = min_t(size_t, ret, io_data->len); | |
| 880 | − | |
| 881 | − if (unlikely(copy_to_user(io_data->buf, | |
| 882 | − data, ret))) | |
| 847 | + ret = copy_to_iter(data, ret, &io_data->data); | |
| 848 | + if (unlikely(iov_iter_count(&io_data->data))) | |
| 883 | 849 | ret = -EFAULT; |
| 884 | 850 | } |
| 885 | 851 | } |
| @@ -898,37 +864,6 @@ error: · 12 unmodified lines | ||
| 898 | 864 | return ret; |
| 899 | 865 | } |
| 900 | 866 | |
| 901 | −static ssize_t | |
| 902 | −ffs_epfile_write(struct file *file, const char __user *buf, size_t len, | |
| 903 | − loff_t *ptr) | |
| 904 | −{ | |
| 905 | − struct ffs_io_data io_data; | |
| 906 | − | |
| 907 | − ENTER(); | |
| 908 | − | |
| 909 | − io_data.aio = false; | |
| 910 | − io_data.read = false; | |
| 911 | − io_data.buf = (char * __user)buf; | |
| 912 | − io_data.len = len; | |
| 913 | − | |
| 914 | − return ffs_epfile_io(file, &io_data); | |
| 915 | −} | |
| 916 | − | |
| 917 | −static ssize_t | |
| 918 | −ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) | |
| 919 | −{ | |
| 920 | − struct ffs_io_data io_data; | |
| 921 | − | |
| 922 | − ENTER(); | |
| 923 | − | |
| 924 | − io_data.aio = false; | |
| 925 | − io_data.read = true; | |
| 926 | − io_data.buf = buf; | |
| 927 | − io_data.len = len; | |
| 928 | − | |
| 929 | − return ffs_epfile_io(file, &io_data); | |
| 930 | −} | |
| 931 | − | |
| 932 | 867 | static int |
| 933 | 868 | ffs_epfile_open(struct inode *inode, struct file *file) |
| 934 | 869 | { |
| @@ -965,67 +900,86 @@ static int ffs_aio_cancel(struct kiocb *kiocb) · 30 unmodified lines | ||
| 965 | 900 | return value; |
| 966 | 901 | } |
| 967 | 902 | |
| 968 | −static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, | |
| 969 | − const struct iovec *iovec, | |
| 970 | − unsigned long nr_segs, loff_t loff) | |
| 903 | +static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) | |
| 971 | 904 | { |
| 972 | − struct ffs_io_data *io_data; | |
| 905 | + struct ffs_io_data io_data, *p = &io_data; | |
| 906 | + ssize_t res; | |
| 973 | 907 | |
| 974 | 908 | ENTER(); |
| 975 | 909 | |
| 976 | − io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); | |
| 977 | − if (unlikely(!io_data)) | |
| 978 | − return -ENOMEM; | |
| 910 | + if (!is_sync_kiocb(kiocb)) { | |
| 911 | + p = kmalloc(sizeof(io_data), GFP_KERNEL); | |
| 912 | + if (unlikely(!p)) | |
| 913 | + return -ENOMEM; | |
| 914 | + p->aio = true; | |
| 915 | + } else { | |
| 916 | + p->aio = false; | |
| 917 | + } | |
| 979 | 918 | |
| 980 | − io_data->aio = true; | |
| 981 | − io_data->read = false; | |
| 982 | − io_data->kiocb = kiocb; | |
| 983 | − io_data->iovec = iovec; | |
| 984 | − io_data->nr_segs = nr_segs; | |
| 985 | − io_data->len = kiocb->ki_nbytes; | |
| 986 | − io_data->mm = current->mm; | |
| 919 | + p->read = false; | |
| 920 | + p->kiocb = kiocb; | |
| 921 | + p->data = *from; | |
| 922 | + p->mm = current->mm; | |
| 987 | 923 | |
| 988 | − kiocb->private = io_data; | |
| 924 | + kiocb->private = p; | |
| 989 | 925 | |
| 990 | 926 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); |
| 991 | 927 | |
| 992 | − return ffs_epfile_io(kiocb->ki_filp, io_data); | |
| 928 | + res = ffs_epfile_io(kiocb->ki_filp, p); | |
| 929 | + if (res == -EIOCBQUEUED) | |
| 930 | + return res; | |
| 931 | + if (p->aio) | |
| 932 | + kfree(p); | |
| 933 | + else | |
| 934 | + *from = p->data; | |
| 935 | + return res; | |
| 993 | 936 | } |
| 994 | 937 | |
| 995 | −static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, | |
| 996 | − const struct iovec *iovec, | |
| 997 | − unsigned long nr_segs, loff_t loff) | |
| 938 | +static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) | |
| 998 | 939 | { |
| 999 | − struct ffs_io_data *io_data; | |
| 1000 | − struct iovec *iovec_copy; | |
| 940 | + struct ffs_io_data io_data, *p = &io_data; | |
| 941 | + ssize_t res; | |
| 1001 | 942 | |
| 1002 | 943 | ENTER(); |
| 1003 | 944 | |
| 1004 | − iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL); | |
| 1005 | − if (unlikely(!iovec_copy)) | |
| 1006 | − return -ENOMEM; | |
| 1007 | − | |
| 1008 | − memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs); | |
| 1009 | − | |
| 1010 | − io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); | |
| 1011 | − if (unlikely(!io_data)) { | |
| 1012 | − kfree(iovec_copy); | |
| 1013 | − return -ENOMEM; | |
| 945 | + if (!is_sync_kiocb(kiocb)) { | |
| 946 | + p = kmalloc(sizeof(io_data), GFP_KERNEL); | |
| 947 | + if (unlikely(!p)) | |
| 948 | + return -ENOMEM; | |
| 949 | + p->aio = true; | |
| 950 | + } else { | |
| 951 | + p->aio = false; | |
| 1014 | 952 | } |
| 1015 | 953 | |
| 1016 | − io_data->aio = true; | |
| 1017 | − io_data->read = true; | |
| 1018 | − io_data->kiocb = kiocb; | |
| 1019 | − io_data->iovec = iovec_copy; | |
| 1020 | − io_data->nr_segs = nr_segs; | |
| 1021 | − io_data->len = kiocb->ki_nbytes; | |
| 1022 | − io_data->mm = current->mm; | |
| 954 | + p->read = true; | |
| 955 | + p->kiocb = kiocb; | |
| 956 | + if (p->aio) { | |
| 957 | + p->to_free = dup_iter(&p->data, to, GFP_KERNEL); | |
| 958 | + if (!p->to_free) { | |
| 959 | + kfree(p); | |
| 960 | + return -ENOMEM; | |
| 961 | + } | |
| 962 | + } else { | |
| 963 | + p->data = *to; | |
| 964 | + p->to_free = NULL; | |
| 965 | + } | |
| 966 | + p->mm = current->mm; | |
| 1023 | 967 | |
| 1024 | − kiocb->private = io_data; | |
| 968 | + kiocb->private = p; | |
| 1025 | 969 | |
| 1026 | 970 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); |
| 1027 | 971 | |
| 1028 | − return ffs_epfile_io(kiocb->ki_filp, io_data); | |
| 972 | + res = ffs_epfile_io(kiocb->ki_filp, p); | |
| 973 | + if (res == -EIOCBQUEUED) | |
| 974 | + return res; | |
| 975 | + | |
| 976 | + if (p->aio) { | |
| 977 | + kfree(p->to_free); | |
| 978 | + kfree(p); | |
| 979 | + } else { | |
| 980 | + *to = p->data; | |
| 981 | + } | |
| 982 | + return res; | |
| 1029 | 983 | } |
| 1030 | 984 | |
| 1031 | 985 | static int |
| @@ -1105,10 +1059,10 @@ static const struct file_operations ffs_epfile_operations = { · 73 unmodified lines | ||
| 1105 | 1059 | .llseek = no_llseek, |
| 1106 | 1060 | |
| 1107 | 1061 | .open = ffs_epfile_open, |
| 1108 | − .write = ffs_epfile_write, | |
| 1109 | − .read = ffs_epfile_read, | |
| 1110 | − .aio_write = ffs_epfile_aio_write, | |
| 1111 | − .aio_read = ffs_epfile_aio_read, | |
| 1062 | + .write = new_sync_write, | |
| 1063 | + .read = new_sync_read, | |
| 1064 | + .write_iter = ffs_epfile_write_iter, | |
| 1065 | + .read_iter = ffs_epfile_read_iter, | |
| 1112 | 1066 | .release = ffs_epfile_release, |
| 1113 | 1067 | .unlocked_ioctl = ffs_epfile_ioctl, |
| 1114 | 1068 | }; |
| @@ -289,8 +289,7 @@ static void disable_loopback(struct f_loopback *loop) · 288 unmodified lines | ||
| 289 | 289 | struct usb_composite_dev *cdev; |
| 290 | 290 | |
| 291 | 291 | cdev = loop->function.config->cdev; |
| 292 | − disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL, NULL, | |
| 293 | − NULL); | |
| 292 | + disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL); | |
| 294 | 293 | VDBG(cdev, "%s disabled\n", loop->function.name); |
| 295 | 294 | } |
| 296 | 295 | |
| @@ -23,15 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include "gadget_chips.h" |
| 24 | 24 | #include "u_f.h" |
| 25 | 25 | |
| 26 | −#define USB_MS_TO_SS_INTERVAL(x) USB_MS_TO_HS_INTERVAL(x) | |
| 27 | − | |
| 28 | −enum eptype { | |
| 29 | − EP_CONTROL = 0, | |
| 30 | − EP_BULK, | |
| 31 | − EP_ISOC, | |
| 32 | − EP_INTERRUPT, | |
| 33 | −}; | |
| 34 | − | |
| 35 | 26 | /* |
| 36 | 27 | * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral |
| 37 | 28 | * controller drivers. |
| @@ -64,8 +55,6 @@ struct f_sourcesink { · 26 unmodified lines | ||
| 64 | 55 | struct usb_ep *out_ep; |
| 65 | 56 | struct usb_ep *iso_in_ep; |
| 66 | 57 | struct usb_ep *iso_out_ep; |
| 67 | − struct usb_ep *int_in_ep; | |
| 68 | − struct usb_ep *int_out_ep; | |
| 69 | 58 | int cur_alt; |
| 70 | 59 | }; |
| 71 | 60 | |
| @@ -79,10 +68,6 @@ static unsigned isoc_interval; · 7 unmodified lines | ||
| 79 | 68 | static unsigned isoc_maxpacket; |
| 80 | 69 | static unsigned isoc_mult; |
| 81 | 70 | static unsigned isoc_maxburst; |
| 82 | −static unsigned int_interval; /* In ms */ | |
| 83 | −static unsigned int_maxpacket; | |
| 84 | −static unsigned int_mult; | |
| 85 | −static unsigned int_maxburst; | |
| 86 | 71 | static unsigned buflen; |
| 87 | 72 | |
| 88 | 73 | /*-------------------------------------------------------------------------*/ |
| @@ -107,16 +92,6 @@ static struct usb_interface_descriptor source_sink_intf_alt1 = { · 18 unmodified lines | ||
| 107 | 92 | /* .iInterface = DYNAMIC */ |
| 108 | 93 | }; |
| 109 | 94 | |
| 110 | −static struct usb_interface_descriptor source_sink_intf_alt2 = { | |
| 111 | − .bLength = USB_DT_INTERFACE_SIZE, | |
| 112 | − .bDescriptorType = USB_DT_INTERFACE, | |
| 113 | − | |
| 114 | − .bAlternateSetting = 2, | |
| 115 | − .bNumEndpoints = 2, | |
| 116 | − .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | |
| 117 | − /* .iInterface = DYNAMIC */ | |
| 118 | −}; | |
| 119 | − | |
| 120 | 95 | /* full speed support: */ |
| 121 | 96 | |
| 122 | 97 | static struct usb_endpoint_descriptor fs_source_desc = { |
| @@ -155,26 +130,6 @@ static struct usb_endpoint_descriptor fs_iso_sink_desc = { · 32 unmodified lines | ||
| 155 | 130 | .bInterval = 4, |
| 156 | 131 | }; |
| 157 | 132 | |
| 158 | −static struct usb_endpoint_descriptor fs_int_source_desc = { | |
| 159 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 160 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 161 | − | |
| 162 | − .bEndpointAddress = USB_DIR_IN, | |
| 163 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 164 | − .wMaxPacketSize = cpu_to_le16(64), | |
| 165 | − .bInterval = GZERO_INT_INTERVAL, | |
| 166 | −}; | |
| 167 | − | |
| 168 | −static struct usb_endpoint_descriptor fs_int_sink_desc = { | |
| 169 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 170 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 171 | − | |
| 172 | − .bEndpointAddress = USB_DIR_OUT, | |
| 173 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 174 | − .wMaxPacketSize = cpu_to_le16(64), | |
| 175 | − .bInterval = GZERO_INT_INTERVAL, | |
| 176 | −}; | |
| 177 | − | |
| 178 | 133 | static struct usb_descriptor_header *fs_source_sink_descs[] = { |
| 179 | 134 | (struct usb_descriptor_header *) &source_sink_intf_alt0, |
| 180 | 135 | (struct usb_descriptor_header *) &fs_sink_desc, |
| @@ -185,10 +140,6 @@ static struct usb_descriptor_header *fs_source_sink_descs[] = { · 4 unmodified lines | ||
| 185 | 140 | (struct usb_descriptor_header *) &fs_source_desc, |
| 186 | 141 | (struct usb_descriptor_header *) &fs_iso_sink_desc, |
| 187 | 142 | (struct usb_descriptor_header *) &fs_iso_source_desc, |
| 188 | − (struct usb_descriptor_header *) &source_sink_intf_alt2, | |
| 189 | −#define FS_ALT_IFC_2_OFFSET 8 | |
| 190 | − (struct usb_descriptor_header *) &fs_int_sink_desc, | |
| 191 | − (struct usb_descriptor_header *) &fs_int_source_desc, | |
| 192 | 143 | NULL, |
| 193 | 144 | }; |
| 194 | 145 | |
| @@ -228,24 +179,6 @@ static struct usb_endpoint_descriptor hs_iso_sink_desc = { · 33 unmodified lines | ||
| 228 | 179 | .bInterval = 4, |
| 229 | 180 | }; |
| 230 | 181 | |
| 231 | −static struct usb_endpoint_descriptor hs_int_source_desc = { | |
| 232 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 233 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 234 | − | |
| 235 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 236 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 237 | − .bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL), | |
| 238 | −}; | |
| 239 | − | |
| 240 | −static struct usb_endpoint_descriptor hs_int_sink_desc = { | |
| 241 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 242 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 243 | − | |
| 244 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 245 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 246 | − .bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL), | |
| 247 | −}; | |
| 248 | − | |
| 249 | 182 | static struct usb_descriptor_header *hs_source_sink_descs[] = { |
| 250 | 183 | (struct usb_descriptor_header *) &source_sink_intf_alt0, |
| 251 | 184 | (struct usb_descriptor_header *) &hs_source_desc, |
| @@ -256,10 +189,6 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = { · 4 unmodified lines | ||
| 256 | 189 | (struct usb_descriptor_header *) &hs_sink_desc, |
| 257 | 190 | (struct usb_descriptor_header *) &hs_iso_source_desc, |
| 258 | 191 | (struct usb_descriptor_header *) &hs_iso_sink_desc, |
| 259 | − (struct usb_descriptor_header *) &source_sink_intf_alt2, | |
| 260 | −#define HS_ALT_IFC_2_OFFSET 8 | |
| 261 | − (struct usb_descriptor_header *) &hs_int_source_desc, | |
| 262 | − (struct usb_descriptor_header *) &hs_int_sink_desc, | |
| 263 | 192 | NULL, |
| 264 | 193 | }; |
| 265 | 194 | |
| @@ -335,42 +264,6 @@ static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = { · 69 unmodified lines | ||
| 335 | 264 | .wBytesPerInterval = cpu_to_le16(1024), |
| 336 | 265 | }; |
| 337 | 266 | |
| 338 | −static struct usb_endpoint_descriptor ss_int_source_desc = { | |
| 339 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 340 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 341 | − | |
| 342 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 343 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 344 | − .bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL), | |
| 345 | −}; | |
| 346 | − | |
| 347 | −static struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = { | |
| 348 | − .bLength = USB_DT_SS_EP_COMP_SIZE, | |
| 349 | − .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | |
| 350 | − | |
| 351 | − .bMaxBurst = 0, | |
| 352 | − .bmAttributes = 0, | |
| 353 | − .wBytesPerInterval = cpu_to_le16(1024), | |
| 354 | −}; | |
| 355 | − | |
| 356 | −static struct usb_endpoint_descriptor ss_int_sink_desc = { | |
| 357 | − .bLength = USB_DT_ENDPOINT_SIZE, | |
| 358 | − .bDescriptorType = USB_DT_ENDPOINT, | |
| 359 | − | |
| 360 | − .bmAttributes = USB_ENDPOINT_XFER_INT, | |
| 361 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 362 | − .bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL), | |
| 363 | −}; | |
| 364 | − | |
| 365 | −static struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = { | |
| 366 | − .bLength = USB_DT_SS_EP_COMP_SIZE, | |
| 367 | − .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | |
| 368 | − | |
| 369 | − .bMaxBurst = 0, | |
| 370 | − .bmAttributes = 0, | |
| 371 | − .wBytesPerInterval = cpu_to_le16(1024), | |
| 372 | −}; | |
| 373 | − | |
| 374 | 267 | static struct usb_descriptor_header *ss_source_sink_descs[] = { |
| 375 | 268 | (struct usb_descriptor_header *) &source_sink_intf_alt0, |
| 376 | 269 | (struct usb_descriptor_header *) &ss_source_desc, |
| @@ -387,12 +280,6 @@ static struct usb_descriptor_header *ss_source_sink_descs[] = { · 10 unmodified lines | ||
| 387 | 280 | (struct usb_descriptor_header *) &ss_iso_source_comp_desc, |
| 388 | 281 | (struct usb_descriptor_header *) &ss_iso_sink_desc, |
| 389 | 282 | (struct usb_descriptor_header *) &ss_iso_sink_comp_desc, |
| 390 | − (struct usb_descriptor_header *) &source_sink_intf_alt2, | |
| 391 | −#define SS_ALT_IFC_2_OFFSET 14 | |
| 392 | − (struct usb_descriptor_header *) &ss_int_source_desc, | |
| 393 | − (struct usb_descriptor_header *) &ss_int_source_comp_desc, | |
| 394 | − (struct usb_descriptor_header *) &ss_int_sink_desc, | |
| 395 | − (struct usb_descriptor_header *) &ss_int_sink_comp_desc, | |
| 396 | 283 | NULL, |
| 397 | 284 | }; |
| 398 | 285 | |
| @@ -414,21 +301,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = { · 15 unmodified lines | ||
| 414 | 301 | }; |
| 415 | 302 | |
| 416 | 303 | /*-------------------------------------------------------------------------*/ |
| 417 | −static const char *get_ep_string(enum eptype ep_type) | |
| 418 | −{ | |
| 419 | − switch (ep_type) { | |
| 420 | − case EP_ISOC: | |
| 421 | − return "ISOC-"; | |
| 422 | − case EP_INTERRUPT: | |
| 423 | − return "INTERRUPT-"; | |
| 424 | − case EP_CONTROL: | |
| 425 | − return "CTRL-"; | |
| 426 | − case EP_BULK: | |
| 427 | − return "BULK-"; | |
| 428 | − default: | |
| 429 | − return "UNKNOWN-"; | |
| 430 | − } | |
| 431 | −} | |
| 432 | 304 | |
| 433 | 305 | static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) |
| 434 | 306 | { |
| @@ -456,8 +328,7 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) · 21 unmodified lines | ||
| 456 | 328 | |
| 457 | 329 | void disable_endpoints(struct usb_composite_dev *cdev, |
| 458 | 330 | struct usb_ep *in, struct usb_ep *out, |
| 459 | − struct usb_ep *iso_in, struct usb_ep *iso_out, | |
| 460 | − struct usb_ep *int_in, struct usb_ep *int_out) | |
| 331 | + struct usb_ep *iso_in, struct usb_ep *iso_out) | |
| 461 | 332 | { |
| 462 | 333 | disable_ep(cdev, in); |
| 463 | 334 | disable_ep(cdev, out); |
| @@ -465,10 +336,6 @@ void disable_endpoints(struct usb_composite_dev *cdev, · 1 unmodified line | ||
| 465 | 336 | disable_ep(cdev, iso_in); |
| 466 | 337 | if (iso_out) |
| 467 | 338 | disable_ep(cdev, iso_out); |
| 468 | − if (int_in) | |
| 469 | − disable_ep(cdev, int_in); | |
| 470 | − if (int_out) | |
| 471 | − disable_ep(cdev, int_out); | |
| 472 | 339 | } |
| 473 | 340 | |
| 474 | 341 | static int |
| @@ -485,7 +352,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) · 10 unmodified lines | ||
| 485 | 352 | return id; |
| 486 | 353 | source_sink_intf_alt0.bInterfaceNumber = id; |
| 487 | 354 | source_sink_intf_alt1.bInterfaceNumber = id; |
| 488 | − source_sink_intf_alt2.bInterfaceNumber = id; | |
| 489 | 355 | |
| 490 | 356 | /* allocate bulk endpoints */ |
| 491 | 357 | ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc); |
| @@ -546,55 +412,14 @@ no_iso: · 54 unmodified lines | ||
| 546 | 412 | if (isoc_maxpacket > 1024) |
| 547 | 413 | isoc_maxpacket = 1024; |
| 548 | 414 | |
| 549 | − /* sanity check the interrupt module parameters */ | |
| 550 | − if (int_interval < 1) | |
| 551 | − int_interval = 1; | |
| 552 | − if (int_interval > 4096) | |
| 553 | − int_interval = 4096; | |
| 554 | − if (int_mult > 2) | |
| 555 | − int_mult = 2; | |
| 556 | − if (int_maxburst > 15) | |
| 557 | − int_maxburst = 15; | |
| 558 | − | |
| 559 | − /* fill in the FS interrupt descriptors from the module parameters */ | |
| 560 | − fs_int_source_desc.wMaxPacketSize = int_maxpacket > 64 ? | |
| 561 | − 64 : int_maxpacket; | |
| 562 | − fs_int_source_desc.bInterval = int_interval > 255 ? | |
| 563 | − 255 : int_interval; | |
| 564 | − fs_int_sink_desc.wMaxPacketSize = int_maxpacket > 64 ? | |
| 565 | − 64 : int_maxpacket; | |
| 566 | − fs_int_sink_desc.bInterval = int_interval > 255 ? | |
| 567 | − 255 : int_interval; | |
| 568 | − | |
| 569 | − /* allocate int endpoints */ | |
| 570 | − ss->int_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_source_desc); | |
| 571 | − if (!ss->int_in_ep) | |
| 572 | − goto no_int; | |
| 573 | − ss->int_in_ep->driver_data = cdev; /* claim */ | |
| 574 | − | |
| 575 | − ss->int_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_sink_desc); | |
| 576 | − if (ss->int_out_ep) { | |
| 577 | − ss->int_out_ep->driver_data = cdev; /* claim */ | |
| 578 | − } else { | |
| 579 | − ss->int_in_ep->driver_data = NULL; | |
| 580 | − ss->int_in_ep = NULL; | |
| 581 | −no_int: | |
| 582 | − fs_source_sink_descs[FS_ALT_IFC_2_OFFSET] = NULL; | |
| 583 | − hs_source_sink_descs[HS_ALT_IFC_2_OFFSET] = NULL; | |
| 584 | − ss_source_sink_descs[SS_ALT_IFC_2_OFFSET] = NULL; | |
| 585 | − } | |
| 586 | − | |
| 587 | − if (int_maxpacket > 1024) | |
| 588 | − int_maxpacket = 1024; | |
| 589 | − | |
| 590 | 415 | /* support high speed hardware */ |
| 591 | 416 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; |
| 592 | 417 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; |
| 593 | 418 | |
| 594 | 419 | /* |
| 595 | − * Fill in the HS isoc and interrupt descriptors from the module | |
| 596 | − * parameters. We assume that the user knows what they are doing and | |
| 597 | − * won't give parameters that their UDC doesn't support. | |
| 420 | + * Fill in the HS isoc descriptors from the module parameters. | |
| 421 | + * We assume that the user knows what they are doing and won't | |
| 422 | + * give parameters that their UDC doesn't support. | |
| 598 | 423 | */ |
| 599 | 424 | hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket; |
| 600 | 425 | hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11; |
| @@ -607,17 +432,6 @@ no_int: · 6 unmodified lines | ||
| 607 | 432 | hs_iso_sink_desc.bInterval = isoc_interval; |
| 608 | 433 | hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; |
| 609 | 434 | |
| 610 | − hs_int_source_desc.wMaxPacketSize = int_maxpacket; | |
| 611 | − hs_int_source_desc.wMaxPacketSize |= int_mult << 11; | |
| 612 | − hs_int_source_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval); | |
| 613 | − hs_int_source_desc.bEndpointAddress = | |
| 614 | − fs_int_source_desc.bEndpointAddress; | |
| 615 | − | |
| 616 | − hs_int_sink_desc.wMaxPacketSize = int_maxpacket; | |
| 617 | − hs_int_sink_desc.wMaxPacketSize |= int_mult << 11; | |
| 618 | − hs_int_sink_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval); | |
| 619 | − hs_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress; | |
| 620 | − | |
| 621 | 435 | /* support super speed hardware */ |
| 622 | 436 | ss_source_desc.bEndpointAddress = |
| 623 | 437 | fs_source_desc.bEndpointAddress; |
| @@ -625,9 +439,9 @@ no_int: · 1 unmodified line | ||
| 625 | 439 | fs_sink_desc.bEndpointAddress; |
| 626 | 440 | |
| 627 | 441 | /* |
| 628 | − * Fill in the SS isoc and interrupt descriptors from the module | |
| 629 | − * parameters. We assume that the user knows what they are doing and | |
| 630 | − * won't give parameters that their UDC doesn't support. | |
| 442 | + * Fill in the SS isoc descriptors from the module parameters. | |
| 443 | + * We assume that the user knows what they are doing and won't | |
| 444 | + * give parameters that their UDC doesn't support. | |
| 631 | 445 | */ |
| 632 | 446 | ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket; |
| 633 | 447 | ss_iso_source_desc.bInterval = isoc_interval; |
| @@ -646,37 +460,17 @@ no_int: · 12 unmodified lines | ||
| 646 | 460 | isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); |
| 647 | 461 | ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; |
| 648 | 462 | |
| 649 | − ss_int_source_desc.wMaxPacketSize = int_maxpacket; | |
| 650 | − ss_int_source_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval); | |
| 651 | − ss_int_source_comp_desc.bmAttributes = int_mult; | |
| 652 | − ss_int_source_comp_desc.bMaxBurst = int_maxburst; | |
| 653 | − ss_int_source_comp_desc.wBytesPerInterval = | |
| 654 | − int_maxpacket * (int_mult + 1) * (int_maxburst + 1); | |
| 655 | − ss_int_source_desc.bEndpointAddress = | |
| 656 | − fs_int_source_desc.bEndpointAddress; | |
| 657 | − | |
| 658 | − ss_int_sink_desc.wMaxPacketSize = int_maxpacket; | |
| 659 | − ss_int_sink_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval); | |
| 660 | − ss_int_sink_comp_desc.bmAttributes = int_mult; | |
| 661 | − ss_int_sink_comp_desc.bMaxBurst = int_maxburst; | |
| 662 | − ss_int_sink_comp_desc.wBytesPerInterval = | |
| 663 | − int_maxpacket * (int_mult + 1) * (int_maxburst + 1); | |
| 664 | − ss_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress; | |
| 665 | − | |
| 666 | 463 | ret = usb_assign_descriptors(f, fs_source_sink_descs, |
| 667 | 464 | hs_source_sink_descs, ss_source_sink_descs); |
| 668 | 465 | if (ret) |
| 669 | 466 | return ret; |
| 670 | 467 | |
| 671 | − DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s, " | |
| 672 | − "INT-IN/%s, INT-OUT/%s\n", | |
| 468 | + DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n", | |
| 673 | 469 | (gadget_is_superspeed(c->cdev->gadget) ? "super" : |
| 674 | 470 | (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")), |
| 675 | 471 | f->name, ss->in_ep->name, ss->out_ep->name, |
| 676 | 472 | ss->iso_in_ep ? ss->iso_in_ep->name : "<none>", |
| 677 | − ss->iso_out_ep ? ss->iso_out_ep->name : "<none>", | |
| 678 | − ss->int_in_ep ? ss->int_in_ep->name : "<none>", | |
| 679 | − ss->int_out_ep ? ss->int_out_ep->name : "<none>"); | |
| 473 | + ss->iso_out_ep ? ss->iso_out_ep->name : "<none>"); | |
| 680 | 474 | return 0; |
| 681 | 475 | } |
| 682 | 476 | |
| @@ -807,15 +601,14 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) · 124 unmodified lines | ||
| 807 | 601 | } |
| 808 | 602 | |
| 809 | 603 | static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, |
| 810 | − enum eptype ep_type, int speed) | |
| 604 | + bool is_iso, int speed) | |
| 811 | 605 | { |
| 812 | 606 | struct usb_ep *ep; |
| 813 | 607 | struct usb_request *req; |
| 814 | 608 | int i, size, status; |
| 815 | 609 | |
| 816 | 610 | for (i = 0; i < 8; i++) { |
| 817 | − switch (ep_type) { | |
| 818 | − case EP_ISOC: | |
| 611 | + if (is_iso) { | |
| 819 | 612 | switch (speed) { |
| 820 | 613 | case USB_SPEED_SUPER: |
| 821 | 614 | size = isoc_maxpacket * (isoc_mult + 1) * |
| @@ -831,28 +624,9 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, · 9 unmodified lines | ||
| 831 | 624 | } |
| 832 | 625 | ep = is_in ? ss->iso_in_ep : ss->iso_out_ep; |
| 833 | 626 | req = ss_alloc_ep_req(ep, size); |
| 834 | − break; | |
| 835 | − case EP_INTERRUPT: | |
| 836 | − switch (speed) { | |
| 837 | − case USB_SPEED_SUPER: | |
| 838 | − size = int_maxpacket * (int_mult + 1) * | |
| 839 | − (int_maxburst + 1); | |
| 840 | − break; | |
| 841 | − case USB_SPEED_HIGH: | |
| 842 | − size = int_maxpacket * (int_mult + 1); | |
| 843 | − break; | |
| 844 | − default: | |
| 845 | − size = int_maxpacket > 1023 ? | |
| 846 | − 1023 : int_maxpacket; | |
| 847 | − break; | |
| 848 | − } | |
| 849 | − ep = is_in ? ss->int_in_ep : ss->int_out_ep; | |
| 850 | − req = ss_alloc_ep_req(ep, size); | |
| 851 | − break; | |
| 852 | − default: | |
| 627 | + } else { | |
| 853 | 628 | ep = is_in ? ss->in_ep : ss->out_ep; |
| 854 | 629 | req = ss_alloc_ep_req(ep, 0); |
| 855 | − break; | |
| 856 | 630 | } |
| 857 | 631 | |
| 858 | 632 | if (!req) |
| @@ -870,12 +644,12 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, · 11 unmodified lines | ||
| 870 | 644 | |
| 871 | 645 | cdev = ss->function.config->cdev; |
| 872 | 646 | ERROR(cdev, "start %s%s %s --> %d\n", |
| 873 | − get_ep_string(ep_type), is_in ? "IN" : "OUT", | |
| 874 | − ep->name, status); | |
| 647 | + is_iso ? "ISO-" : "", is_in ? "IN" : "OUT", | |
| 648 | + ep->name, status); | |
| 875 | 649 | free_ep_req(ep, req); |
| 876 | 650 | } |
| 877 | 651 | |
| 878 | − if (!(ep_type == EP_ISOC)) | |
| 652 | + if (!is_iso) | |
| 879 | 653 | break; |
| 880 | 654 | } |
| 881 | 655 | |
| @@ -888,7 +662,7 @@ static void disable_source_sink(struct f_sourcesink *ss) · 6 unmodified lines | ||
| 888 | 662 | |
| 889 | 663 | cdev = ss->function.config->cdev; |
| 890 | 664 | disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep, |
| 891 | − ss->iso_out_ep, ss->int_in_ep, ss->int_out_ep); | |
| 665 | + ss->iso_out_ep); | |
| 892 | 666 | VDBG(cdev, "%s disabled\n", ss->function.name); |
| 893 | 667 | } |
| 894 | 668 | |
| @@ -900,62 +674,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss, · 5 unmodified lines | ||
| 900 | 674 | int speed = cdev->gadget->speed; |
| 901 | 675 | struct usb_ep *ep; |
| 902 | 676 | |
| 903 | − if (alt == 2) { | |
| 904 | − /* Configure for periodic interrupt endpoint */ | |
| 905 | − ep = ss->int_in_ep; | |
| 906 | − if (ep) { | |
| 907 | − result = config_ep_by_speed(cdev->gadget, | |
| 908 | − &(ss->function), ep); | |
| 909 | − if (result) | |
| 910 | − return result; | |
| 911 | − | |
| 912 | − result = usb_ep_enable(ep); | |
| 913 | − if (result < 0) | |
| 914 | − return result; | |
| 915 | − | |
| 916 | − ep->driver_data = ss; | |
| 917 | − result = source_sink_start_ep(ss, true, EP_INTERRUPT, | |
| 918 | − speed); | |
| 919 | − if (result < 0) { | |
| 920 | −fail1: | |
| 921 | − ep = ss->int_in_ep; | |
| 922 | − if (ep) { | |
| 923 | − usb_ep_disable(ep); | |
| 924 | − ep->driver_data = NULL; | |
| 925 | − } | |
| 926 | − return result; | |
| 927 | − } | |
| 928 | − } | |
| 929 | − | |
| 930 | − /* | |
| 931 | − * one interrupt endpoint reads (sinks) anything OUT (from the | |
| 932 | − * host) | |
| 933 | − */ | |
| 934 | − ep = ss->int_out_ep; | |
| 935 | − if (ep) { | |
| 936 | − result = config_ep_by_speed(cdev->gadget, | |
| 937 | − &(ss->function), ep); | |
| 938 | − if (result) | |
| 939 | − goto fail1; | |
| 940 | − | |
| 941 | − result = usb_ep_enable(ep); | |
| 942 | − if (result < 0) | |
| 943 | − goto fail1; | |
| 944 | − | |
| 945 | − ep->driver_data = ss; | |
| 946 | − result = source_sink_start_ep(ss, false, EP_INTERRUPT, | |
| 947 | − speed); | |
| 948 | − if (result < 0) { | |
| 949 | − ep = ss->int_out_ep; | |
| 950 | − usb_ep_disable(ep); | |
| 951 | − ep->driver_data = NULL; | |
| 952 | − goto fail1; | |
| 953 | − } | |
| 954 | − } | |
| 955 | − | |
| 956 | − goto out; | |
| 957 | − } | |
| 958 | − | |
| 959 | 677 | /* one bulk endpoint writes (sources) zeroes IN (to the host) */ |
| 960 | 678 | ep = ss->in_ep; |
| 961 | 679 | result = config_ep_by_speed(cdev->gadget, &(ss->function), ep); |
| @@ -966,7 +684,7 @@ fail1: · 4 unmodified lines | ||
| 966 | 684 | return result; |
| 967 | 685 | ep->driver_data = ss; |
| 968 | 686 | |
| 969 | − result = source_sink_start_ep(ss, true, EP_BULK, speed); | |
| 687 | + result = source_sink_start_ep(ss, true, false, speed); | |
| 970 | 688 | if (result < 0) { |
| 971 | 689 | fail: |
| 972 | 690 | ep = ss->in_ep; |
| @@ -985,7 +703,7 @@ fail: · 12 unmodified lines | ||
| 985 | 703 | goto fail; |
| 986 | 704 | ep->driver_data = ss; |
| 987 | 705 | |
| 988 | − result = source_sink_start_ep(ss, false, EP_BULK, speed); | |
| 706 | + result = source_sink_start_ep(ss, false, false, speed); | |
| 989 | 707 | if (result < 0) { |
| 990 | 708 | fail2: |
| 991 | 709 | ep = ss->out_ep; |
| @@ -1008,7 +726,7 @@ fail2: · 16 unmodified lines | ||
| 1008 | 726 | goto fail2; |
| 1009 | 727 | ep->driver_data = ss; |
| 1010 | 728 | |
| 1011 | − result = source_sink_start_ep(ss, true, EP_ISOC, speed); | |
| 729 | + result = source_sink_start_ep(ss, true, true, speed); | |
| 1012 | 730 | if (result < 0) { |
| 1013 | 731 | fail3: |
| 1014 | 732 | ep = ss->iso_in_ep; |
| @@ -1031,14 +749,13 @@ fail3: · 16 unmodified lines | ||
| 1031 | 749 | goto fail3; |
| 1032 | 750 | ep->driver_data = ss; |
| 1033 | 751 | |
| 1034 | − result = source_sink_start_ep(ss, false, EP_ISOC, speed); | |
| 752 | + result = source_sink_start_ep(ss, false, true, speed); | |
| 1035 | 753 | if (result < 0) { |
| 1036 | 754 | usb_ep_disable(ep); |
| 1037 | 755 | ep->driver_data = NULL; |
| 1038 | 756 | goto fail3; |
| 1039 | 757 | } |
| 1040 | 758 | } |
| 1041 | − | |
| 1042 | 759 | out: |
| 1043 | 760 | ss->cur_alt = alt; |
| 1044 | 761 | |
| @@ -1054,8 +771,6 @@ static int sourcesink_set_alt(struct usb_function *f, · 9 unmodified lines | ||
| 1054 | 771 | |
| 1055 | 772 | if (ss->in_ep->driver_data) |
| 1056 | 773 | disable_source_sink(ss); |
| 1057 | − else if (alt == 2 && ss->int_in_ep->driver_data) | |
| 1058 | − disable_source_sink(ss); | |
| 1059 | 774 | return enable_source_sink(cdev, ss, alt); |
| 1060 | 775 | } |
| 1061 | 776 | |
| @@ -1168,10 +883,6 @@ static struct usb_function *source_sink_alloc_func( · 106 unmodified lines | ||
| 1168 | 883 | isoc_maxpacket = ss_opts->isoc_maxpacket; |
| 1169 | 884 | isoc_mult = ss_opts->isoc_mult; |
| 1170 | 885 | isoc_maxburst = ss_opts->isoc_maxburst; |
| 1171 | − int_interval = ss_opts->int_interval; | |
| 1172 | − int_maxpacket = ss_opts->int_maxpacket; | |
| 1173 | − int_mult = ss_opts->int_mult; | |
| 1174 | − int_maxburst = ss_opts->int_maxburst; | |
| 1175 | 886 | buflen = ss_opts->bulk_buflen; |
| 1176 | 887 | |
| 1177 | 888 | ss->function.name = "source/sink"; |
| @@ -1468,182 +1179,6 @@ static struct f_ss_opts_attribute f_ss_opts_bulk_buflen = · 290 unmodified lines | ||
| 1468 | 1179 | f_ss_opts_bulk_buflen_show, |
| 1469 | 1180 | f_ss_opts_bulk_buflen_store); |
| 1470 | 1181 | |
| 1471 | −static ssize_t f_ss_opts_int_interval_show(struct f_ss_opts *opts, char *page) | |
| 1472 | −{ | |
| 1473 | − int result; | |
| 1474 | − | |
| 1475 | − mutex_lock(&opts->lock); | |
| 1476 | − result = sprintf(page, "%u", opts->int_interval); | |
| 1477 | − mutex_unlock(&opts->lock); | |
| 1478 | − | |
| 1479 | − return result; | |
| 1480 | −} | |
| 1481 | − | |
| 1482 | −static ssize_t f_ss_opts_int_interval_store(struct f_ss_opts *opts, | |
| 1483 | − const char *page, size_t len) | |
| 1484 | −{ | |
| 1485 | − int ret; | |
| 1486 | − u32 num; | |
| 1487 | − | |
| 1488 | − mutex_lock(&opts->lock); | |
| 1489 | − if (opts->refcnt) { | |
| 1490 | − ret = -EBUSY; | |
| 1491 | − goto end; | |
| 1492 | − } | |
| 1493 | − | |
| 1494 | − ret = kstrtou32(page, 0, &num); | |
| 1495 | − if (ret) | |
| 1496 | − goto end; | |
| 1497 | − | |
| 1498 | − if (num > 4096) { | |
| 1499 | − ret = -EINVAL; | |
| 1500 | − goto end; | |
| 1501 | − } | |
| 1502 | − | |
| 1503 | − opts->int_interval = num; | |
| 1504 | − ret = len; | |
| 1505 | −end: | |
| 1506 | − mutex_unlock(&opts->lock); | |
| 1507 | − return ret; | |
| 1508 | −} | |
| 1509 | − | |
| 1510 | −static struct f_ss_opts_attribute f_ss_opts_int_interval = | |
| 1511 | − __CONFIGFS_ATTR(int_interval, S_IRUGO | S_IWUSR, | |
| 1512 | − f_ss_opts_int_interval_show, | |
| 1513 | − f_ss_opts_int_interval_store); | |
| 1514 | − | |
| 1515 | −static ssize_t f_ss_opts_int_maxpacket_show(struct f_ss_opts *opts, char *page) | |
| 1516 | −{ | |
| 1517 | − int result; | |
| 1518 | − | |
| 1519 | − mutex_lock(&opts->lock); | |
| 1520 | − result = sprintf(page, "%u", opts->int_maxpacket); | |
| 1521 | − mutex_unlock(&opts->lock); | |
| 1522 | − | |
| 1523 | − return result; | |
| 1524 | −} | |
| 1525 | − | |
| 1526 | −static ssize_t f_ss_opts_int_maxpacket_store(struct f_ss_opts *opts, | |
| 1527 | − const char *page, size_t len) | |
| 1528 | −{ | |
| 1529 | − int ret; | |
| 1530 | − u16 num; | |
| 1531 | − | |
| 1532 | − mutex_lock(&opts->lock); | |
| 1533 | − if (opts->refcnt) { | |
| 1534 | − ret = -EBUSY; | |
| 1535 | − goto end; | |
| 1536 | − } | |
| 1537 | − | |
| 1538 | − ret = kstrtou16(page, 0, &num); | |
| 1539 | − if (ret) | |
| 1540 | − goto end; | |
| 1541 | − | |
| 1542 | − if (num > 1024) { | |
| 1543 | − ret = -EINVAL; | |
| 1544 | − goto end; | |
| 1545 | − } | |
| 1546 | − | |
| 1547 | − opts->int_maxpacket = num; | |
| 1548 | − ret = len; | |
| 1549 | −end: | |
| 1550 | − mutex_unlock(&opts->lock); | |
| 1551 | − return ret; | |
| 1552 | −} | |
| 1553 | − | |
| 1554 | −static struct f_ss_opts_attribute f_ss_opts_int_maxpacket = | |
| 1555 | − __CONFIGFS_ATTR(int_maxpacket, S_IRUGO | S_IWUSR, | |
| 1556 | − f_ss_opts_int_maxpacket_show, | |
| 1557 | − f_ss_opts_int_maxpacket_store); | |
| 1558 | − | |
| 1559 | −static ssize_t f_ss_opts_int_mult_show(struct f_ss_opts *opts, char *page) | |
| 1560 | −{ | |
| 1561 | − int result; | |
| 1562 | − | |
| 1563 | − mutex_lock(&opts->lock); | |
| 1564 | − result = sprintf(page, "%u", opts->int_mult); | |
| 1565 | − mutex_unlock(&opts->lock); | |
| 1566 | − | |
| 1567 | − return result; | |
| 1568 | −} | |
| 1569 | − | |
| 1570 | −static ssize_t f_ss_opts_int_mult_store(struct f_ss_opts *opts, | |
| 1571 | − const char *page, size_t len) | |
| 1572 | −{ | |
| 1573 | − int ret; | |
| 1574 | − u8 num; | |
| 1575 | − | |
| 1576 | − mutex_lock(&opts->lock); | |
| 1577 | − if (opts->refcnt) { | |
| 1578 | − ret = -EBUSY; | |
| 1579 | − goto end; | |
| 1580 | − } | |
| 1581 | − | |
| 1582 | − ret = kstrtou8(page, 0, &num); | |
| 1583 | − if (ret) | |
| 1584 | − goto end; | |
| 1585 | − | |
| 1586 | − if (num > 2) { | |
| 1587 | − ret = -EINVAL; | |
| 1588 | − goto end; | |
| 1589 | − } | |
| 1590 | − | |
| 1591 | − opts->int_mult = num; | |
| 1592 | − ret = len; | |
| 1593 | −end: | |
| 1594 | − mutex_unlock(&opts->lock); | |
| 1595 | − return ret; | |
| 1596 | −} | |
| 1597 | − | |
| 1598 | −static struct f_ss_opts_attribute f_ss_opts_int_mult = | |
| 1599 | − __CONFIGFS_ATTR(int_mult, S_IRUGO | S_IWUSR, | |
| 1600 | − f_ss_opts_int_mult_show, | |
| 1601 | − f_ss_opts_int_mult_store); | |
| 1602 | − | |
| 1603 | −static ssize_t f_ss_opts_int_maxburst_show(struct f_ss_opts *opts, char *page) | |
| 1604 | −{ | |
| 1605 | − int result; | |
| 1606 | − | |
| 1607 | − mutex_lock(&opts->lock); | |
| 1608 | − result = sprintf(page, "%u", opts->int_maxburst); | |
| 1609 | − mutex_unlock(&opts->lock); | |
| 1610 | − | |
| 1611 | − return result; | |
| 1612 | −} | |
| 1613 | − | |
| 1614 | −static ssize_t f_ss_opts_int_maxburst_store(struct f_ss_opts *opts, | |
| 1615 | − const char *page, size_t len) | |
| 1616 | −{ | |
| 1617 | − int ret; | |
| 1618 | − u8 num; | |
| 1619 | − | |
| 1620 | − mutex_lock(&opts->lock); | |
| 1621 | − if (opts->refcnt) { | |
| 1622 | − ret = -EBUSY; | |
| 1623 | − goto end; | |
| 1624 | − } | |
| 1625 | − | |
| 1626 | − ret = kstrtou8(page, 0, &num); | |
| 1627 | − if (ret) | |
| 1628 | − goto end; | |
| 1629 | − | |
| 1630 | − if (num > 15) { | |
| 1631 | − ret = -EINVAL; | |
| 1632 | − goto end; | |
| 1633 | − } | |
| 1634 | − | |
| 1635 | − opts->int_maxburst = num; | |
| 1636 | − ret = len; | |
| 1637 | −end: | |
| 1638 | − mutex_unlock(&opts->lock); | |
| 1639 | − return ret; | |
| 1640 | −} | |
| 1641 | − | |
| 1642 | −static struct f_ss_opts_attribute f_ss_opts_int_maxburst = | |
| 1643 | − __CONFIGFS_ATTR(int_maxburst, S_IRUGO | S_IWUSR, | |
| 1644 | − f_ss_opts_int_maxburst_show, | |
| 1645 | − f_ss_opts_int_maxburst_store); | |
| 1646 | − | |
| 1647 | 1182 | static struct configfs_attribute *ss_attrs[] = { |
| 1648 | 1183 | &f_ss_opts_pattern.attr, |
| 1649 | 1184 | &f_ss_opts_isoc_interval.attr, |
| @@ -1651,10 +1186,6 @@ static struct configfs_attribute *ss_attrs[] = { · 1 unmodified line | ||
| 1651 | 1186 | &f_ss_opts_isoc_mult.attr, |
| 1652 | 1187 | &f_ss_opts_isoc_maxburst.attr, |
| 1653 | 1188 | &f_ss_opts_bulk_buflen.attr, |
| 1654 | − &f_ss_opts_int_interval.attr, | |
| 1655 | − &f_ss_opts_int_maxpacket.attr, | |
| 1656 | − &f_ss_opts_int_mult.attr, | |
| 1657 | − &f_ss_opts_int_maxburst.attr, | |
| 1658 | 1189 | NULL, |
| 1659 | 1190 | }; |
| 1660 | 1191 | |
| @@ -1684,8 +1215,6 @@ static struct usb_function_instance *source_sink_alloc_inst(void) · 23 unmodified lines | ||
| 1684 | 1215 | ss_opts->isoc_interval = GZERO_ISOC_INTERVAL; |
| 1685 | 1216 | ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET; |
| 1686 | 1217 | ss_opts->bulk_buflen = GZERO_BULK_BUFLEN; |
| 1687 | − ss_opts->int_interval = GZERO_INT_INTERVAL; | |
| 1688 | − ss_opts->int_maxpacket = GZERO_INT_MAXPACKET; | |
| 1689 | 1218 | |
| 1690 | 1219 | config_group_init_type_name(&ss_opts->func_inst.group, "", |
| 1691 | 1220 | &ss_func_type); |
| @@ -10,8 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #define GZERO_QLEN 32 |
| 11 | 11 | #define GZERO_ISOC_INTERVAL 4 |
| 12 | 12 | #define GZERO_ISOC_MAXPACKET 1024 |
| 13 | −#define GZERO_INT_INTERVAL 1 /* Default interrupt interval = 1 ms */ | |
| 14 | −#define GZERO_INT_MAXPACKET 1024 | |
| 15 | 13 | |
| 16 | 14 | struct usb_zero_options { |
| 17 | 15 | unsigned pattern; |
| @@ -19,10 +17,6 @@ struct usb_zero_options { · 1 unmodified line | ||
| 19 | 17 | unsigned isoc_maxpacket; |
| 20 | 18 | unsigned isoc_mult; |
| 21 | 19 | unsigned isoc_maxburst; |
| 22 | − unsigned int_interval; /* In ms */ | |
| 23 | − unsigned int_maxpacket; | |
| 24 | − unsigned int_mult; | |
| 25 | − unsigned int_maxburst; | |
| 26 | 20 | unsigned bulk_buflen; |
| 27 | 21 | unsigned qlen; |
| 28 | 22 | }; |
| @@ -34,10 +28,6 @@ struct f_ss_opts { · 5 unmodified lines | ||
| 34 | 28 | unsigned isoc_maxpacket; |
| 35 | 29 | unsigned isoc_mult; |
| 36 | 30 | unsigned isoc_maxburst; |
| 37 | − unsigned int_interval; /* In ms */ | |
| 38 | − unsigned int_maxpacket; | |
| 39 | − unsigned int_mult; | |
| 40 | − unsigned int_maxburst; | |
| 41 | 31 | unsigned bulk_buflen; |
| 42 | 32 | |
| 43 | 33 | /* |
| @@ -72,7 +62,6 @@ int lb_modinit(void); · 28 unmodified lines | ||
| 72 | 62 | void free_ep_req(struct usb_ep *ep, struct usb_request *req); |
| 73 | 63 | void disable_endpoints(struct usb_composite_dev *cdev, |
| 74 | 64 | struct usb_ep *in, struct usb_ep *out, |
| 75 | − struct usb_ep *iso_in, struct usb_ep *iso_out, | |
| 76 | − struct usb_ep *int_in, struct usb_ep *int_out); | |
| 65 | + struct usb_ep *iso_in, struct usb_ep *iso_out); | |
| 77 | 66 | |
| 78 | 67 | #endif /* __G_ZERO_H */ |
| @@ -74,6 +74,8 @@ MODULE_DESCRIPTION (DRIVER_DESC); · 73 unmodified lines | ||
| 74 | 74 | MODULE_AUTHOR ("David Brownell"); |
| 75 | 75 | MODULE_LICENSE ("GPL"); |
| 76 | 76 | |
| 77 | +static int ep_open(struct inode *, struct file *); | |
| 78 | + | |
| 77 | 79 | |
| 78 | 80 | /*----------------------------------------------------------------------*/ |
| 79 | 81 | |
| @@ -283,14 +285,15 @@ static void epio_complete (struct usb_ep *ep, struct usb_request *req) · 203 unmodified lines | ||
| 283 | 285 | * still need dev->lock to use epdata->ep. |
| 284 | 286 | */ |
| 285 | 287 | static int |
| 286 | −get_ready_ep (unsigned f_flags, struct ep_data *epdata) | |
| 288 | +get_ready_ep (unsigned f_flags, struct ep_data *epdata, bool is_write) | |
| 287 | 289 | { |
| 288 | 290 | int val; |
| 289 | 291 | |
| 290 | 292 | if (f_flags & O_NONBLOCK) { |
| 291 | 293 | if (!mutex_trylock(&epdata->lock)) |
| 292 | 294 | goto nonblock; |
| 293 | − if (epdata->state != STATE_EP_ENABLED) { | |
| 295 | + if (epdata->state != STATE_EP_ENABLED && | |
| 296 | + (!is_write || epdata->state != STATE_EP_READY)) { | |
| 294 | 297 | mutex_unlock(&epdata->lock); |
| 295 | 298 | nonblock: |
| 296 | 299 | val = -EAGAIN; |
| @@ -305,18 +308,20 @@ nonblock: · 8 unmodified lines | ||
| 305 | 308 | |
| 306 | 309 | switch (epdata->state) { |
| 307 | 310 | case STATE_EP_ENABLED: |
| 311 | + return 0; | |
| 312 | + case STATE_EP_READY: /* not configured yet */ | |
| 313 | + if (is_write) | |
| 314 | + return 0; | |
| 315 | + // FALLTHRU | |
| 316 | + case STATE_EP_UNBOUND: /* clean disconnect */ | |
| 308 | 317 | break; |
| 309 | 318 | // case STATE_EP_DISABLED: /* "can't happen" */ |
| 310 | − // case STATE_EP_READY: /* "can't happen" */ | |
| 311 | 319 | default: /* error! */ |
| 312 | 320 | pr_debug ("%s: ep %p not available, state %d\n", |
| 313 | 321 | shortname, epdata, epdata->state); |
| 314 | − // FALLTHROUGH | |
| 315 | − case STATE_EP_UNBOUND: /* clean disconnect */ | |
| 316 | − val = -ENODEV; | |
| 317 | − mutex_unlock(&epdata->lock); | |
| 318 | 322 | } |
| 319 | − return val; | |
| 323 | + mutex_unlock(&epdata->lock); | |
| 324 | + return -ENODEV; | |
| 320 | 325 | } |
| 321 | 326 | |
| 322 | 327 | static ssize_t |
| @@ -363,97 +368,6 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) · 40 unmodified lines | ||
| 363 | 368 | return value; |
| 364 | 369 | } |
| 365 | 370 | |
| 366 | − | |
| 367 | −/* handle a synchronous OUT bulk/intr/iso transfer */ | |
| 368 | −static ssize_t | |
| 369 | −ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |
| 370 | −{ | |
| 371 | − struct ep_data *data = fd->private_data; | |
| 372 | − void *kbuf; | |
| 373 | − ssize_t value; | |
| 374 | − | |
| 375 | − if ((value = get_ready_ep (fd->f_flags, data)) < 0) | |
| 376 | − return value; | |
| 377 | − | |
| 378 | − /* halt any endpoint by doing a "wrong direction" i/o call */ | |
| 379 | − if (usb_endpoint_dir_in(&data->desc)) { | |
| 380 | − if (usb_endpoint_xfer_isoc(&data->desc)) { | |
| 381 | − mutex_unlock(&data->lock); | |
| 382 | − return -EINVAL; | |
| 383 | − } | |
| 384 | − DBG (data->dev, "%s halt\n", data->name); | |
| 385 | − spin_lock_irq (&data->dev->lock); | |
| 386 | − if (likely (data->ep != NULL)) | |
| 387 | − usb_ep_set_halt (data->ep); | |
| 388 | − spin_unlock_irq (&data->dev->lock); | |
| 389 | − mutex_unlock(&data->lock); | |
| 390 | − return -EBADMSG; | |
| 391 | − } | |
| 392 | − | |
| 393 | − /* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */ | |
| 394 | − | |
| 395 | − value = -ENOMEM; | |
| 396 | − kbuf = kmalloc (len, GFP_KERNEL); | |
| 397 | − if (unlikely (!kbuf)) | |
| 398 | − goto free1; | |
| 399 | − | |
| 400 | − value = ep_io (data, kbuf, len); | |
| 401 | − VDEBUG (data->dev, "%s read %zu OUT, status %d\n", | |
| 402 | − data->name, len, (int) value); | |
| 403 | − if (value >= 0 && copy_to_user (buf, kbuf, value)) | |
| 404 | − value = -EFAULT; | |
| 405 | − | |
| 406 | −free1: | |
| 407 | − mutex_unlock(&data->lock); | |
| 408 | − kfree (kbuf); | |
| 409 | − return value; | |
| 410 | −} | |
| 411 | − | |
| 412 | −/* handle a synchronous IN bulk/intr/iso transfer */ | |
| 413 | −static ssize_t | |
| 414 | −ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |
| 415 | −{ | |
| 416 | − struct ep_data *data = fd->private_data; | |
| 417 | − void *kbuf; | |
| 418 | − ssize_t value; | |
| 419 | − | |
| 420 | − if ((value = get_ready_ep (fd->f_flags, data)) < 0) | |
| 421 | − return value; | |
| 422 | − | |
| 423 | − /* halt any endpoint by doing a "wrong direction" i/o call */ | |
| 424 | − if (!usb_endpoint_dir_in(&data->desc)) { | |
| 425 | − if (usb_endpoint_xfer_isoc(&data->desc)) { | |
| 426 | − mutex_unlock(&data->lock); | |
| 427 | − return -EINVAL; | |
| 428 | − } | |
| 429 | − DBG (data->dev, "%s halt\n", data->name); | |
| 430 | − spin_lock_irq (&data->dev->lock); | |
| 431 | − if (likely (data->ep != NULL)) | |
| 432 | − usb_ep_set_halt (data->ep); | |
| 433 | − spin_unlock_irq (&data->dev->lock); | |
| 434 | − mutex_unlock(&data->lock); | |
| 435 | − return -EBADMSG; | |
| 436 | − } | |
| 437 | − | |
| 438 | − /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ | |
| 439 | − | |
| 440 | − value = -ENOMEM; | |
| 441 | − kbuf = memdup_user(buf, len); | |
| 442 | − if (IS_ERR(kbuf)) { | |
| 443 | − value = PTR_ERR(kbuf); | |
| 444 | − kbuf = NULL; | |
| 445 | − goto free1; | |
| 446 | − } | |
| 447 | − | |
| 448 | − value = ep_io (data, kbuf, len); | |
| 449 | − VDEBUG (data->dev, "%s write %zu IN, status %d\n", | |
| 450 | − data->name, len, (int) value); | |
| 451 | −free1: | |
| 452 | − mutex_unlock(&data->lock); | |
| 453 | − kfree (kbuf); | |
| 454 | − return value; | |
| 455 | −} | |
| 456 | − | |
| 457 | 371 | static int |
| 458 | 372 | ep_release (struct inode *inode, struct file *fd) |
| 459 | 373 | { |
| @@ -481,7 +395,7 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value) · 21 unmodified lines | ||
| 481 | 395 | struct ep_data *data = fd->private_data; |
| 482 | 396 | int status; |
| 483 | 397 | |
| 484 | − if ((status = get_ready_ep (fd->f_flags, data)) < 0) | |
| 398 | + if ((status = get_ready_ep (fd->f_flags, data, false)) < 0) | |
| 485 | 399 | return status; |
| 486 | 400 | |
| 487 | 401 | spin_lock_irq (&data->dev->lock); |
| @@ -517,8 +431,8 @@ struct kiocb_priv { · 29 unmodified lines | ||
| 517 | 431 | struct mm_struct *mm; |
| 518 | 432 | struct work_struct work; |
| 519 | 433 | void *buf; |
| 520 | − const struct iovec *iv; | |
| 521 | − unsigned long nr_segs; | |
| 434 | + struct iov_iter to; | |
| 435 | + const void *to_free; | |
| 522 | 436 | unsigned actual; |
| 523 | 437 | }; |
| 524 | 438 | |
| @@ -541,35 +455,6 @@ static int ep_aio_cancel(struct kiocb *iocb) · 16 unmodified lines | ||
| 541 | 455 | return value; |
| 542 | 456 | } |
| 543 | 457 | |
| 544 | −static ssize_t ep_copy_to_user(struct kiocb_priv *priv) | |
| 545 | −{ | |
| 546 | − ssize_t len, total; | |
| 547 | − void *to_copy; | |
| 548 | − int i; | |
| 549 | − | |
| 550 | − /* copy stuff into user buffers */ | |
| 551 | − total = priv->actual; | |
| 552 | − len = 0; | |
| 553 | − to_copy = priv->buf; | |
| 554 | − for (i=0; i < priv->nr_segs; i++) { | |
| 555 | − ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); | |
| 556 | − | |
| 557 | − if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) { | |
| 558 | − if (len == 0) | |
| 559 | − len = -EFAULT; | |
| 560 | − break; | |
| 561 | − } | |
| 562 | − | |
| 563 | − total -= this; | |
| 564 | − len += this; | |
| 565 | − to_copy += this; | |
| 566 | − if (total == 0) | |
| 567 | − break; | |
| 568 | − } | |
| 569 | − | |
| 570 | − return len; | |
| 571 | −} | |
| 572 | − | |
| 573 | 458 | static void ep_user_copy_worker(struct work_struct *work) |
| 574 | 459 | { |
| 575 | 460 | struct kiocb_priv *priv = container_of(work, struct kiocb_priv, work); |
| @@ -578,13 +463,16 @@ static void ep_user_copy_worker(struct work_struct *work) · 2 unmodified lines | ||
| 578 | 463 | size_t ret; |
| 579 | 464 | |
| 580 | 465 | use_mm(mm); |
| 581 | − ret = ep_copy_to_user(priv); | |
| 466 | + ret = copy_to_iter(priv->buf, priv->actual, &priv->to); | |
| 582 | 467 | unuse_mm(mm); |
| 468 | + if (!ret) | |
| 469 | + ret = -EFAULT; | |
| 583 | 470 | |
| 584 | 471 | /* completing the iocb can drop the ctx and mm, don't touch mm after */ |
| 585 | 472 | aio_complete(iocb, ret, ret); |
| 586 | 473 | |
| 587 | 474 | kfree(priv->buf); |
| 475 | + kfree(priv->to_free); | |
| 588 | 476 | kfree(priv); |
| 589 | 477 | } |
| 590 | 478 | |
| @@ -603,8 +491,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · 12 unmodified lines | ||
| 603 | 491 | * don't need to copy anything to userspace, so we can |
| 604 | 492 | * complete the aio request immediately. |
| 605 | 493 | */ |
| 606 | − if (priv->iv == NULL || unlikely(req->actual == 0)) { | |
| 494 | + if (priv->to_free == NULL || unlikely(req->actual == 0)) { | |
| 607 | 495 | kfree(req->buf); |
| 496 | + kfree(priv->to_free); | |
| 608 | 497 | kfree(priv); |
| 609 | 498 | iocb->private = NULL; |
| 610 | 499 | /* aio_complete() reports bytes-transferred _and_ faults */ |
| @@ -618,6 +507,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · 7 unmodified lines | ||
| 618 | 507 | |
| 619 | 508 | priv->buf = req->buf; |
| 620 | 509 | priv->actual = req->actual; |
| 510 | + INIT_WORK(&priv->work, ep_user_copy_worker); | |
| 621 | 511 | schedule_work(&priv->work); |
| 622 | 512 | } |
| 623 | 513 | spin_unlock(&epdata->dev->lock); |
| @@ -626,38 +516,17 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · 2 unmodified lines | ||
| 626 | 516 | put_ep(epdata); |
| 627 | 517 | } |
| 628 | 518 | |
| 629 | −static ssize_t | |
| 630 | −ep_aio_rwtail( | |
| 631 | − struct kiocb *iocb, | |
| 632 | − char *buf, | |
| 633 | − size_t len, | |
| 634 | − struct ep_data *epdata, | |
| 635 | − const struct iovec *iv, | |
| 636 | − unsigned long nr_segs | |
| 637 | −) | |
| 519 | +static ssize_t ep_aio(struct kiocb *iocb, | |
| 520 | + struct kiocb_priv *priv, | |
| 521 | + struct ep_data *epdata, | |
| 522 | + char *buf, | |
| 523 | + size_t len) | |
| 638 | 524 | { |
| 639 | − struct kiocb_priv *priv; | |
| 640 | − struct usb_request *req; | |
| 641 | − ssize_t value; | |
| 525 | + struct usb_request *req; | |
| 526 | + ssize_t value; | |
| 642 | 527 | |
| 643 | − priv = kmalloc(sizeof *priv, GFP_KERNEL); | |
| 644 | − if (!priv) { | |
| 645 | − value = -ENOMEM; | |
| 646 | −fail: | |
| 647 | − kfree(buf); | |
| 648 | − return value; | |
| 649 | − } | |
| 650 | 528 | iocb->private = priv; |
| 651 | 529 | priv->iocb = iocb; |
| 652 | − priv->iv = iv; | |
| 653 | − priv->nr_segs = nr_segs; | |
| 654 | − INIT_WORK(&priv->work, ep_user_copy_worker); | |
| 655 | − | |
| 656 | − value = get_ready_ep(iocb->ki_filp->f_flags, epdata); | |
| 657 | − if (unlikely(value < 0)) { | |
| 658 | − kfree(priv); | |
| 659 | − goto fail; | |
| 660 | − } | |
| 661 | 530 | |
| 662 | 531 | kiocb_set_cancel_fn(iocb, ep_aio_cancel); |
| 663 | 532 | get_ep(epdata); |
| @@ -669,75 +538,154 @@ fail: · 5 unmodified lines | ||
| 669 | 538 | * allocate or submit those if the host disconnected. |
| 670 | 539 | */ |
| 671 | 540 | spin_lock_irq(&epdata->dev->lock); |
| 672 | − if (likely(epdata->ep)) { | |
| 673 | − req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); | |
| 674 | − if (likely(req)) { | |
| 675 | − priv->req = req; | |
| 676 | − req->buf = buf; | |
| 677 | − req->length = len; | |
| 678 | − req->complete = ep_aio_complete; | |
| 679 | − req->context = iocb; | |
| 680 | − value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC); | |
| 681 | − if (unlikely(0 != value)) | |
| 682 | − usb_ep_free_request(epdata->ep, req); | |
| 683 | − } else | |
| 684 | − value = -EAGAIN; | |
| 685 | − } else | |
| 686 | − value = -ENODEV; | |
| 687 | − spin_unlock_irq(&epdata->dev->lock); | |
| 541 | + value = -ENODEV; | |
| 542 | + if (unlikely(epdata->ep)) | |
| 543 | + goto fail; | |
| 688 | 544 | |
| 689 | − mutex_unlock(&epdata->lock); | |
| 545 | + req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); | |
| 546 | + value = -ENOMEM; | |
| 547 | + if (unlikely(!req)) | |
| 548 | + goto fail; | |
| 690 | 549 | |
| 691 | − if (unlikely(value)) { | |
| 692 | − kfree(priv); | |
| 693 | − put_ep(epdata); | |
| 694 | − } else | |
| 695 | − value = -EIOCBQUEUED; | |
| 550 | + priv->req = req; | |
| 551 | + req->buf = buf; | |
| 552 | + req->length = len; | |
| 553 | + req->complete = ep_aio_complete; | |
| 554 | + req->context = iocb; | |
| 555 | + value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC); | |
| 556 | + if (unlikely(0 != value)) { | |
| 557 | + usb_ep_free_request(epdata->ep, req); | |
| 558 | + goto fail; | |
| 559 | + } | |
| 560 | + spin_unlock_irq(&epdata->dev->lock); | |
| 561 | + return -EIOCBQUEUED; | |
| 562 | + | |
| 563 | +fail: | |
| 564 | + spin_unlock_irq(&epdata->dev->lock); | |
| 565 | + kfree(priv->to_free); | |
| 566 | + kfree(priv); | |
| 567 | + put_ep(epdata); | |
| 696 | 568 | return value; |
| 697 | 569 | } |
| 698 | 570 | |
| 699 | 571 | static ssize_t |
| 700 | −ep_aio_read(struct kiocb *iocb, const struct iovec *iov, | |
| 701 | − unsigned long nr_segs, loff_t o) | |
| 572 | +ep_read_iter(struct kiocb *iocb, struct iov_iter *to) | |
| 702 | 573 | { |
| 703 | − struct ep_data *epdata = iocb->ki_filp->private_data; | |
| 704 | − char *buf; | |
| 574 | + struct file *file = iocb->ki_filp; | |
| 575 | + struct ep_data *epdata = file->private_data; | |
| 576 | + size_t len = iov_iter_count(to); | |
| 577 | + ssize_t value; | |
| 578 | + char *buf; | |
| 705 | 579 | |
| 706 | − if (unlikely(usb_endpoint_dir_in(&epdata->desc))) | |
| 707 | − return -EINVAL; | |
| 580 | + if ((value = get_ready_ep(file->f_flags, epdata, false)) < 0) | |
| 581 | + return value; | |
| 708 | 582 | |
| 709 | − buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL); | |
| 710 | − if (unlikely(!buf)) | |
| 711 | − return -ENOMEM; | |
| 583 | + /* halt any endpoint by doing a "wrong direction" i/o call */ | |
| 584 | + if (usb_endpoint_dir_in(&epdata->desc)) { | |
| 585 | + if (usb_endpoint_xfer_isoc(&epdata->desc) || | |
| 586 | + !is_sync_kiocb(iocb)) { | |
| 587 | + mutex_unlock(&epdata->lock); | |
| 588 | + return -EINVAL; | |
| 589 | + } | |
| 590 | + DBG (epdata->dev, "%s halt\n", epdata->name); | |
| 591 | + spin_lock_irq(&epdata->dev->lock); | |
| 592 | + if (likely(epdata->ep != NULL)) | |
| 593 | + usb_ep_set_halt(epdata->ep); | |
| 594 | + spin_unlock_irq(&epdata->dev->lock); | |
| 595 | + mutex_unlock(&epdata->lock); | |
| 596 | + return -EBADMSG; | |
| 597 | + } | |
| 712 | 598 | |
| 713 | − return ep_aio_rwtail(iocb, buf, iocb->ki_nbytes, epdata, iov, nr_segs); | |
| 599 | + buf = kmalloc(len, GFP_KERNEL); | |
| 600 | + if (unlikely(!buf)) { | |
| 601 | + mutex_unlock(&epdata->lock); | |
| 602 | + return -ENOMEM; | |
| 603 | + } | |
| 604 | + if (is_sync_kiocb(iocb)) { | |
| 605 | + value = ep_io(epdata, buf, len); | |
| 606 | + if (value >= 0 && copy_to_iter(buf, value, to)) | |
| 607 | + value = -EFAULT; | |
| 608 | + } else { | |
| 609 | + struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); | |
| 610 | + value = -ENOMEM; | |
| 611 | + if (!priv) | |
| 612 | + goto fail; | |
| 613 | + priv->to_free = dup_iter(&priv->to, to, GFP_KERNEL); | |
| 614 | + if (!priv->to_free) { | |
| 615 | + kfree(priv); | |
| 616 | + goto fail; | |
| 617 | + } | |
| 618 | + value = ep_aio(iocb, priv, epdata, buf, len); | |
| 619 | + if (value == -EIOCBQUEUED) | |
| 620 | + buf = NULL; | |
| 621 | + } | |
| 622 | +fail: | |
| 623 | + kfree(buf); | |
| 624 | + mutex_unlock(&epdata->lock); | |
| 625 | + return value; | |
| 714 | 626 | } |
| 715 | 627 | |
| 628 | +static ssize_t ep_config(struct ep_data *, const char *, size_t); | |
| 629 | + | |
| 716 | 630 | static ssize_t |
| 717 | −ep_aio_write(struct kiocb *iocb, const struct iovec *iov, | |
| 718 | − unsigned long nr_segs, loff_t o) | |
| 631 | +ep_write_iter(struct kiocb *iocb, struct iov_iter *from) | |
| 719 | 632 | { |
| 720 | − struct ep_data *epdata = iocb->ki_filp->private_data; | |
| 721 | − char *buf; | |
| 722 | − size_t len = 0; | |
| 723 | − int i = 0; | |
| 633 | + struct file *file = iocb->ki_filp; | |
| 634 | + struct ep_data *epdata = file->private_data; | |
| 635 | + size_t len = iov_iter_count(from); | |
| 636 | + bool configured; | |
| 637 | + ssize_t value; | |
| 638 | + char *buf; | |
| 639 | + | |
| 640 | + if ((value = get_ready_ep(file->f_flags, epdata, true)) < 0) | |
| 641 | + return value; | |
| 724 | 642 | |
| 725 | − if (unlikely(!usb_endpoint_dir_in(&epdata->desc))) | |
| 726 | − return -EINVAL; | |
| 643 | + configured = epdata->state == STATE_EP_ENABLED; | |
| 727 | 644 | |
| 728 | − buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL); | |
| 729 | − if (unlikely(!buf)) | |
| 645 | + /* halt any endpoint by doing a "wrong direction" i/o call */ | |
| 646 | + if (configured && !usb_endpoint_dir_in(&epdata->desc)) { | |
| 647 | + if (usb_endpoint_xfer_isoc(&epdata->desc) || | |
| 648 | + !is_sync_kiocb(iocb)) { | |
| 649 | + mutex_unlock(&epdata->lock); | |
| 650 | + return -EINVAL; | |
| 651 | + } | |
| 652 | + DBG (epdata->dev, "%s halt\n", epdata->name); | |
| 653 | + spin_lock_irq(&epdata->dev->lock); | |
| 654 | + if (likely(epdata->ep != NULL)) | |
| 655 | + usb_ep_set_halt(epdata->ep); | |
| 656 | + spin_unlock_irq(&epdata->dev->lock); | |
| 657 | + mutex_unlock(&epdata->lock); | |
| 658 | + return -EBADMSG; | |
| 659 | + } | |
| 660 | + | |
| 661 | + buf = kmalloc(len, GFP_KERNEL); | |
| 662 | + if (unlikely(!buf)) { | |
| 663 | + mutex_unlock(&epdata->lock); | |
| 730 | 664 | return -ENOMEM; |
| 665 | + } | |
| 731 | 666 | |
| 732 | − for (i=0; i < nr_segs; i++) { | |
| 733 | − if (unlikely(copy_from_user(&buf[len], iov[i].iov_base, | |
| 734 | − iov[i].iov_len) != 0)) { | |
| 735 | − kfree(buf); | |
| 736 | − return -EFAULT; | |
| 667 | + if (unlikely(copy_from_iter(buf, len, from) != len)) { | |
| 668 | + value = -EFAULT; | |
| 669 | + goto out; | |
| 670 | + } | |
| 671 | + | |
| 672 | + if (unlikely(!configured)) { | |
| 673 | + value = ep_config(epdata, buf, len); | |
| 674 | + } else if (is_sync_kiocb(iocb)) { | |
| 675 | + value = ep_io(epdata, buf, len); | |
| 676 | + } else { | |
| 677 | + struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); | |
| 678 | + value = -ENOMEM; | |
| 679 | + if (priv) { | |
| 680 | + value = ep_aio(iocb, priv, epdata, buf, len); | |
| 681 | + if (value == -EIOCBQUEUED) | |
| 682 | + buf = NULL; | |
| 737 | 683 | } |
| 738 | − len += iov[i].iov_len; | |
| 739 | 684 | } |
| 740 | − return ep_aio_rwtail(iocb, buf, len, epdata, NULL, 0); | |
| 685 | +out: | |
| 686 | + kfree(buf); | |
| 687 | + mutex_unlock(&epdata->lock); | |
| 688 | + return value; | |
| 741 | 689 | } |
| 742 | 690 | |
| 743 | 691 | /*----------------------------------------------------------------------*/ |
| @@ -745,15 +693,15 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov, · 1 unmodified line | ||
| 745 | 693 | /* used after endpoint configuration */ |
| 746 | 694 | static const struct file_operations ep_io_operations = { |
| 747 | 695 | .owner = THIS_MODULE, |
| 748 | − .llseek = no_llseek, | |
| 749 | 696 | |
| 750 | − .read = ep_read, | |
| 751 | − .write = ep_write, | |
| 752 | − .unlocked_ioctl = ep_ioctl, | |
| 697 | + .open = ep_open, | |
| 753 | 698 | .release = ep_release, |
| 754 | − | |
| 755 | − .aio_read = ep_aio_read, | |
| 756 | − .aio_write = ep_aio_write, | |
| 699 | + .llseek = no_llseek, | |
| 700 | + .read = new_sync_read, | |
| 701 | + .write = new_sync_write, | |
| 702 | + .unlocked_ioctl = ep_ioctl, | |
| 703 | + .read_iter = ep_read_iter, | |
| 704 | + .write_iter = ep_write_iter, | |
| 757 | 705 | }; |
| 758 | 706 | |
| 759 | 707 | /* ENDPOINT INITIALIZATION |
| @@ -770,17 +718,12 @@ static const struct file_operations ep_io_operations = { · 10 unmodified lines | ||
| 770 | 718 | * speed descriptor, then optional high speed descriptor. |
| 771 | 719 | */ |
| 772 | 720 | static ssize_t |
| 773 | −ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |
| 721 | +ep_config (struct ep_data *data, const char *buf, size_t len) | |
| 774 | 722 | { |
| 775 | − struct ep_data *data = fd->private_data; | |
| 776 | 723 | struct usb_ep *ep; |
| 777 | 724 | u32 tag; |
| 778 | 725 | int value, length = len; |
| 779 | 726 | |
| 780 | − value = mutex_lock_interruptible(&data->lock); | |
| 781 | − if (value < 0) | |
| 782 | − return value; | |
| 783 | − | |
| 784 | 727 | if (data->state != STATE_EP_READY) { |
| 785 | 728 | value = -EL2HLT; |
| 786 | 729 | goto fail; |
| @@ -791,9 +734,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 4 unmodified lines | ||
| 791 | 734 | goto fail0; |
| 792 | 735 | |
| 793 | 736 | /* we might need to change message format someday */ |
| 794 | − if (copy_from_user (&tag, buf, 4)) { | |
| 795 | − goto fail1; | |
| 796 | − } | |
| 737 | + memcpy(&tag, buf, 4); | |
| 797 | 738 | if (tag != 1) { |
| 798 | 739 | DBG(data->dev, "config %s, bad tag %d\n", data->name, tag); |
| 799 | 740 | goto fail0; |
| @@ -806,19 +747,15 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 6 unmodified lines | ||
| 806 | 747 | */ |
| 807 | 748 | |
| 808 | 749 | /* full/low speed descriptor, then high speed */ |
| 809 | − if (copy_from_user (&data->desc, buf, USB_DT_ENDPOINT_SIZE)) { | |
| 810 | − goto fail1; | |
| 811 | − } | |
| 750 | + memcpy(&data->desc, buf, USB_DT_ENDPOINT_SIZE); | |
| 812 | 751 | if (data->desc.bLength != USB_DT_ENDPOINT_SIZE |
| 813 | 752 | || data->desc.bDescriptorType != USB_DT_ENDPOINT) |
| 814 | 753 | goto fail0; |
| 815 | 754 | if (len != USB_DT_ENDPOINT_SIZE) { |
| 816 | 755 | if (len != 2 * USB_DT_ENDPOINT_SIZE) |
| 817 | 756 | goto fail0; |
| 818 | − if (copy_from_user (&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE, | |
| 819 | − USB_DT_ENDPOINT_SIZE)) { | |
| 820 | − goto fail1; | |
| 821 | − } | |
| 757 | + memcpy(&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE, | |
| 758 | + USB_DT_ENDPOINT_SIZE); | |
| 822 | 759 | if (data->hs_desc.bLength != USB_DT_ENDPOINT_SIZE |
| 823 | 760 | || data->hs_desc.bDescriptorType |
| 824 | 761 | != USB_DT_ENDPOINT) { |
| @@ -840,24 +777,20 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 15 unmodified lines | ||
| 840 | 777 | case USB_SPEED_LOW: |
| 841 | 778 | case USB_SPEED_FULL: |
| 842 | 779 | ep->desc = &data->desc; |
| 843 | − value = usb_ep_enable(ep); | |
| 844 | − if (value == 0) | |
| 845 | − data->state = STATE_EP_ENABLED; | |
| 846 | 780 | break; |
| 847 | 781 | case USB_SPEED_HIGH: |
| 848 | 782 | /* fails if caller didn't provide that descriptor... */ |
| 849 | 783 | ep->desc = &data->hs_desc; |
| 850 | − value = usb_ep_enable(ep); | |
| 851 | − if (value == 0) | |
| 852 | − data->state = STATE_EP_ENABLED; | |
| 853 | 784 | break; |
| 854 | 785 | default: |
| 855 | 786 | DBG(data->dev, "unconnected, %s init abandoned\n", |
| 856 | 787 | data->name); |
| 857 | 788 | value = -EINVAL; |
| 789 | + goto gone; | |
| 858 | 790 | } |
| 791 | + value = usb_ep_enable(ep); | |
| 859 | 792 | if (value == 0) { |
| 860 | − fd->f_op = &ep_io_operations; | |
| 793 | + data->state = STATE_EP_ENABLED; | |
| 861 | 794 | value = length; |
| 862 | 795 | } |
| 863 | 796 | gone: |
| @@ -867,14 +800,10 @@ fail: · 3 unmodified lines | ||
| 867 | 800 | data->desc.bDescriptorType = 0; |
| 868 | 801 | data->hs_desc.bDescriptorType = 0; |
| 869 | 802 | } |
| 870 | − mutex_unlock(&data->lock); | |
| 871 | 803 | return value; |
| 872 | 804 | fail0: |
| 873 | 805 | value = -EINVAL; |
| 874 | 806 | goto fail; |
| 875 | −fail1: | |
| 876 | − value = -EFAULT; | |
| 877 | − goto fail; | |
| 878 | 807 | } |
| 879 | 808 | |
| 880 | 809 | static int |
| @@ -902,15 +831,6 @@ ep_open (struct inode *inode, struct file *fd) · 21 unmodified lines | ||
| 902 | 831 | return value; |
| 903 | 832 | } |
| 904 | 833 | |
| 905 | −/* used before endpoint configuration */ | |
| 906 | −static const struct file_operations ep_config_operations = { | |
| 907 | − .llseek = no_llseek, | |
| 908 | − | |
| 909 | − .open = ep_open, | |
| 910 | − .write = ep_config, | |
| 911 | − .release = ep_release, | |
| 912 | −}; | |
| 913 | − | |
| 914 | 834 | /*----------------------------------------------------------------------*/ |
| 915 | 835 | |
| 916 | 836 | /* EP0 IMPLEMENTATION can be partly in userspace. |
| @@ -989,6 +909,10 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) · 72 unmodified lines | ||
| 989 | 909 | enum ep0_state state; |
| 990 | 910 | |
| 991 | 911 | spin_lock_irq (&dev->lock); |
| 912 | + if (dev->state <= STATE_DEV_OPENED) { | |
| 913 | + retval = -EINVAL; | |
| 914 | + goto done; | |
| 915 | + } | |
| 992 | 916 | |
| 993 | 917 | /* report fd mode change before acting on it */ |
| 994 | 918 | if (dev->setup_abort) { |
| @@ -1187,8 +1111,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 192 unmodified lines | ||
| 1187 | 1111 | struct dev_data *dev = fd->private_data; |
| 1188 | 1112 | ssize_t retval = -ESRCH; |
| 1189 | 1113 | |
| 1190 | − spin_lock_irq (&dev->lock); | |
| 1191 | − | |
| 1192 | 1114 | /* report fd mode change before acting on it */ |
| 1193 | 1115 | if (dev->setup_abort) { |
| 1194 | 1116 | dev->setup_abort = 0; |
| @@ -1234,7 +1156,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 39 unmodified lines | ||
| 1234 | 1156 | } else |
| 1235 | 1157 | DBG (dev, "fail %s, state %d\n", __func__, dev->state); |
| 1236 | 1158 | |
| 1237 | − spin_unlock_irq (&dev->lock); | |
| 1238 | 1159 | return retval; |
| 1239 | 1160 | } |
| 1240 | 1161 | |
| @@ -1281,6 +1202,9 @@ ep0_poll (struct file *fd, poll_table *wait) · 40 unmodified lines | ||
| 1281 | 1202 | struct dev_data *dev = fd->private_data; |
| 1282 | 1203 | int mask = 0; |
| 1283 | 1204 | |
| 1205 | + if (dev->state <= STATE_DEV_OPENED) | |
| 1206 | + return DEFAULT_POLLMASK; | |
| 1207 | + | |
| 1284 | 1208 | poll_wait(fd, &dev->wait, wait); |
| 1285 | 1209 | |
| 1286 | 1210 | spin_lock_irq (&dev->lock); |
| @@ -1316,19 +1240,6 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) · 29 unmodified lines | ||
| 1316 | 1240 | return ret; |
| 1317 | 1241 | } |
| 1318 | 1242 | |
| 1319 | −/* used after device configuration */ | |
| 1320 | −static const struct file_operations ep0_io_operations = { | |
| 1321 | − .owner = THIS_MODULE, | |
| 1322 | − .llseek = no_llseek, | |
| 1323 | − | |
| 1324 | − .read = ep0_read, | |
| 1325 | − .write = ep0_write, | |
| 1326 | − .fasync = ep0_fasync, | |
| 1327 | − .poll = ep0_poll, | |
| 1328 | − .unlocked_ioctl = dev_ioctl, | |
| 1329 | − .release = dev_release, | |
| 1330 | −}; | |
| 1331 | − | |
| 1332 | 1243 | /*----------------------------------------------------------------------*/ |
| 1333 | 1244 | |
| 1334 | 1245 | /* The in-kernel gadget driver handles most ep0 issues, in particular |
| @@ -1650,7 +1561,7 @@ static int activate_ep_files (struct dev_data *dev) · 315 unmodified lines | ||
| 1650 | 1561 | goto enomem1; |
| 1651 | 1562 | |
| 1652 | 1563 | data->dentry = gadgetfs_create_file (dev->sb, data->name, |
| 1653 | − data, &ep_config_operations); | |
| 1564 | + data, &ep_io_operations); | |
| 1654 | 1565 | if (!data->dentry) |
| 1655 | 1566 | goto enomem2; |
| 1656 | 1567 | list_add_tail (&data->epfiles, &dev->epfiles); |
| @@ -1852,6 +1763,14 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 195 unmodified lines | ||
| 1852 | 1763 | u32 tag; |
| 1853 | 1764 | char *kbuf; |
| 1854 | 1765 | |
| 1766 | + spin_lock_irq(&dev->lock); | |
| 1767 | + if (dev->state > STATE_DEV_OPENED) { | |
| 1768 | + value = ep0_write(fd, buf, len, ptr); | |
| 1769 | + spin_unlock_irq(&dev->lock); | |
| 1770 | + return value; | |
| 1771 | + } | |
| 1772 | + spin_unlock_irq(&dev->lock); | |
| 1773 | + | |
| 1855 | 1774 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) |
| 1856 | 1775 | return -EINVAL; |
| 1857 | 1776 | |
| @@ -1925,7 +1844,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) · 67 unmodified lines | ||
| 1925 | 1844 | * on, they can work ... except in cleanup paths that |
| 1926 | 1845 | * kick in after the ep0 descriptor is closed. |
| 1927 | 1846 | */ |
| 1928 | − fd->f_op = &ep0_io_operations; | |
| 1929 | 1847 | value = len; |
| 1930 | 1848 | } |
| 1931 | 1849 | return value; |
| @@ -1956,12 +1874,14 @@ dev_open (struct inode *inode, struct file *fd) · 24 unmodified lines | ||
| 1956 | 1874 | return value; |
| 1957 | 1875 | } |
| 1958 | 1876 | |
| 1959 | −static const struct file_operations dev_init_operations = { | |
| 1877 | +static const struct file_operations ep0_operations = { | |
| 1960 | 1878 | .llseek = no_llseek, |
| 1961 | 1879 | |
| 1962 | 1880 | .open = dev_open, |
| 1881 | + .read = ep0_read, | |
| 1963 | 1882 | .write = dev_config, |
| 1964 | 1883 | .fasync = ep0_fasync, |
| 1884 | + .poll = ep0_poll, | |
| 1965 | 1885 | .unlocked_ioctl = dev_ioctl, |
| 1966 | 1886 | .release = dev_release, |
| 1967 | 1887 | }; |
| @@ -2077,7 +1997,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) · 109 unmodified lines | ||
| 2077 | 1997 | goto Enomem; |
| 2078 | 1998 | |
| 2079 | 1999 | dev->sb = sb; |
| 2080 | − dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &dev_init_operations); | |
| 2000 | + dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &ep0_operations); | |
| 2081 | 2001 | if (!dev->dentry) { |
| 2082 | 2002 | put_dev(dev); |
| 2083 | 2003 | goto Enomem; |
| @@ -1740,10 +1740,9 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name) · 1739 unmodified lines | ||
| 1740 | 1740 | goto err_session; |
| 1741 | 1741 | } |
| 1742 | 1742 | /* |
| 1743 | − * Now register the TCM vHost virtual I_T Nexus as active with the | |
| 1744 | − * call to __transport_register_session() | |
| 1743 | + * Now register the TCM vHost virtual I_T Nexus as active. | |
| 1745 | 1744 | */ |
| 1746 | − __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1745 | + transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1747 | 1746 | tv_nexus->tvn_se_sess, tv_nexus); |
| 1748 | 1747 | tpg->tpg_nexus = tv_nexus; |
| 1749 | 1748 | mutex_unlock(&tpg->tpg_mutex); |
| @@ -68,8 +68,6 @@ static struct usb_zero_options gzero_options = { · 67 unmodified lines | ||
| 68 | 68 | .isoc_maxpacket = GZERO_ISOC_MAXPACKET, |
| 69 | 69 | .bulk_buflen = GZERO_BULK_BUFLEN, |
| 70 | 70 | .qlen = GZERO_QLEN, |
| 71 | − .int_interval = GZERO_INT_INTERVAL, | |
| 72 | − .int_maxpacket = GZERO_INT_MAXPACKET, | |
| 73 | 71 | }; |
| 74 | 72 | |
| 75 | 73 | /*-------------------------------------------------------------------------*/ |
| @@ -268,21 +266,6 @@ module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint, · 192 unmodified lines | ||
| 268 | 266 | S_IRUGO|S_IWUSR); |
| 269 | 267 | MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)"); |
| 270 | 268 | |
| 271 | −module_param_named(int_interval, gzero_options.int_interval, uint, | |
| 272 | − S_IRUGO|S_IWUSR); | |
| 273 | −MODULE_PARM_DESC(int_interval, "1 - 16"); | |
| 274 | − | |
| 275 | −module_param_named(int_maxpacket, gzero_options.int_maxpacket, uint, | |
| 276 | − S_IRUGO|S_IWUSR); | |
| 277 | −MODULE_PARM_DESC(int_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); | |
| 278 | − | |
| 279 | −module_param_named(int_mult, gzero_options.int_mult, uint, S_IRUGO|S_IWUSR); | |
| 280 | −MODULE_PARM_DESC(int_mult, "0 - 2 (hs/ss only)"); | |
| 281 | − | |
| 282 | −module_param_named(int_maxburst, gzero_options.int_maxburst, uint, | |
| 283 | − S_IRUGO|S_IWUSR); | |
| 284 | −MODULE_PARM_DESC(int_maxburst, "0 - 15 (ss only)"); | |
| 285 | − | |
| 286 | 269 | static struct usb_function *func_lb; |
| 287 | 270 | static struct usb_function_instance *func_inst_lb; |
| 288 | 271 | |
| @@ -318,10 +301,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev) · 29 unmodified lines | ||
| 318 | 301 | ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; |
| 319 | 302 | ss_opts->isoc_mult = gzero_options.isoc_mult; |
| 320 | 303 | ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; |
| 321 | − ss_opts->int_interval = gzero_options.int_interval; | |
| 322 | − ss_opts->int_maxpacket = gzero_options.int_maxpacket; | |
| 323 | − ss_opts->int_mult = gzero_options.int_mult; | |
| 324 | − ss_opts->int_maxburst = gzero_options.int_maxburst; | |
| 325 | 304 | ss_opts->bulk_buflen = gzero_options.bulk_buflen; |
| 326 | 305 | |
| 327 | 306 | func_ss = usb_get_function(func_inst_ss); |
| @@ -34,7 +34,6 @@ static const char hcd_name[] = "ehci-atmel"; · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | struct atmel_ehci_priv { |
| 36 | 36 | struct clk *iclk; |
| 37 | − struct clk *fclk; | |
| 38 | 37 | struct clk *uclk; |
| 39 | 38 | bool clocked; |
| 40 | 39 | }; |
| @@ -51,12 +50,9 @@ static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci) · 10 unmodified lines | ||
| 51 | 50 | { |
| 52 | 51 | if (atmel_ehci->clocked) |
| 53 | 52 | return; |
| 54 | − if (IS_ENABLED(CONFIG_COMMON_CLK)) { | |
| 55 | − clk_set_rate(atmel_ehci->uclk, 48000000); | |
| 56 | − clk_prepare_enable(atmel_ehci->uclk); | |
| 57 | − } | |
| 53 | + | |
| 54 | + clk_prepare_enable(atmel_ehci->uclk); | |
| 58 | 55 | clk_prepare_enable(atmel_ehci->iclk); |
| 59 | − clk_prepare_enable(atmel_ehci->fclk); | |
| 60 | 56 | atmel_ehci->clocked = true; |
| 61 | 57 | } |
| 62 | 58 | |
| @@ -64,10 +60,9 @@ static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci) · 1 unmodified line | ||
| 64 | 60 | { |
| 65 | 61 | if (!atmel_ehci->clocked) |
| 66 | 62 | return; |
| 67 | − clk_disable_unprepare(atmel_ehci->fclk); | |
| 63 | + | |
| 68 | 64 | clk_disable_unprepare(atmel_ehci->iclk); |
| 69 | − if (IS_ENABLED(CONFIG_COMMON_CLK)) | |
| 70 | − clk_disable_unprepare(atmel_ehci->uclk); | |
| 65 | + clk_disable_unprepare(atmel_ehci->uclk); | |
| 71 | 66 | atmel_ehci->clocked = false; |
| 72 | 67 | } |
| 73 | 68 | |
| @@ -146,20 +141,13 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) · 72 unmodified lines | ||
| 146 | 141 | retval = -ENOENT; |
| 147 | 142 | goto fail_request_resource; |
| 148 | 143 | } |
| 149 | − atmel_ehci->fclk = devm_clk_get(&pdev->dev, "uhpck"); | |
| 150 | − if (IS_ERR(atmel_ehci->fclk)) { | |
| 151 | − dev_err(&pdev->dev, "Error getting function clock\n"); | |
| 152 | − retval = -ENOENT; | |
| 144 | + | |
| 145 | + atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk"); | |
| 146 | + if (IS_ERR(atmel_ehci->uclk)) { | |
| 147 | + dev_err(&pdev->dev, "failed to get uclk\n"); | |
| 148 | + retval = PTR_ERR(atmel_ehci->uclk); | |
| 153 | 149 | goto fail_request_resource; |
| 154 | 150 | } |
| 155 | − if (IS_ENABLED(CONFIG_COMMON_CLK)) { | |
| 156 | − atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk"); | |
| 157 | − if (IS_ERR(atmel_ehci->uclk)) { | |
| 158 | − dev_err(&pdev->dev, "failed to get uclk\n"); | |
| 159 | − retval = PTR_ERR(atmel_ehci->uclk); | |
| 160 | − goto fail_request_resource; | |
| 161 | − } | |
| 162 | − } | |
| 163 | 151 | |
| 164 | 152 | ehci = hcd_to_ehci(hcd); |
| 165 | 153 | /* registers start at offset 0x0 */ |
| @@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, · 1728 unmodified lines | ||
| 1729 | 1729 | if (!command) |
| 1730 | 1730 | return; |
| 1731 | 1731 | |
| 1732 | − ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED; | |
| 1732 | + ep->ep_state |= EP_HALTED; | |
| 1733 | 1733 | ep->stopped_stream = stream_id; |
| 1734 | 1734 | |
| 1735 | 1735 | xhci_queue_reset_ep(xhci, command, slot_id, ep_index); |
| @@ -1338,12 +1338,6 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) · 1337 unmodified lines | ||
| 1338 | 1338 | goto exit; |
| 1339 | 1339 | } |
| 1340 | 1340 | |
| 1341 | − /* Reject urb if endpoint is in soft reset, queue must stay empty */ | |
| 1342 | − if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) { | |
| 1343 | − xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n"); | |
| 1344 | − ret = -EINVAL; | |
| 1345 | − } | |
| 1346 | − | |
| 1347 | 1341 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) |
| 1348 | 1342 | size = urb->number_of_packets; |
| 1349 | 1343 | else |
| @@ -2954,36 +2948,23 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, · 1604 unmodified lines | ||
| 2954 | 2948 | } |
| 2955 | 2949 | } |
| 2956 | 2950 | |
| 2957 | −/* Called after clearing a halted device. USB core should have sent the control | |
| 2951 | +/* Called when clearing halted device. The core should have sent the control | |
| 2958 | 2952 | * message to clear the device halt condition. The host side of the halt should |
| 2959 | − * already be cleared with a reset endpoint command issued immediately when the | |
| 2960 | − * STALL tx event was received. | |
| 2953 | + * already be cleared with a reset endpoint command issued when the STALL tx | |
| 2954 | + * event was received. | |
| 2955 | + * | |
| 2956 | + * Context: in_interrupt | |
| 2961 | 2957 | */ |
| 2962 | 2958 | |
| 2963 | 2959 | void xhci_endpoint_reset(struct usb_hcd *hcd, |
| 2964 | 2960 | struct usb_host_endpoint *ep) |
| 2965 | 2961 | { |
| 2966 | 2962 | struct xhci_hcd *xhci; |
| 2967 | − struct usb_device *udev; | |
| 2968 | − struct xhci_virt_device *virt_dev; | |
| 2969 | − struct xhci_virt_ep *virt_ep; | |
| 2970 | − struct xhci_input_control_ctx *ctrl_ctx; | |
| 2971 | − struct xhci_command *command; | |
| 2972 | − unsigned int ep_index, ep_state; | |
| 2973 | − unsigned long flags; | |
| 2974 | − u32 ep_flag; | |
| 2975 | 2963 | |
| 2976 | 2964 | xhci = hcd_to_xhci(hcd); |
| 2977 | − udev = (struct usb_device *) ep->hcpriv; | |
| 2978 | − if (!ep->hcpriv) | |
| 2979 | − return; | |
| 2980 | − virt_dev = xhci->devs[udev->slot_id]; | |
| 2981 | − ep_index = xhci_get_endpoint_index(&ep->desc); | |
| 2982 | − virt_ep = &virt_dev->eps[ep_index]; | |
| 2983 | − ep_state = virt_ep->ep_state; | |
| 2984 | 2965 | |
| 2985 | 2966 | /* |
| 2986 | − * Implement the config ep command in xhci 4.6.8 additional note: | |
| 2967 | + * We might need to implement the config ep cmd in xhci 4.8.1 note: | |
| 2987 | 2968 | * The Reset Endpoint Command may only be issued to endpoints in the |
| 2988 | 2969 | * Halted state. If software wishes reset the Data Toggle or Sequence |
| 2989 | 2970 | * Number of an endpoint that isn't in the Halted state, then software |
| @@ -2991,72 +2972,9 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, · 1 unmodified line | ||
| 2991 | 2972 | * for the target endpoint. that is in the Stopped state. |
| 2992 | 2973 | */ |
| 2993 | 2974 | |
| 2994 | − if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) { | |
| 2995 | − virt_ep->ep_state &= ~EP_RECENTLY_HALTED; | |
| 2996 | − xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n"); | |
| 2997 | − return; | |
| 2998 | − } | |
| 2999 | − | |
| 3000 | − /* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */ | |
| 3001 | − if (usb_endpoint_xfer_control(&ep->desc) || | |
| 3002 | − usb_endpoint_xfer_isoc(&ep->desc)) | |
| 3003 | − return; | |
| 3004 | − | |
| 3005 | − ep_flag = xhci_get_endpoint_flag(&ep->desc); | |
| 3006 | − | |
| 3007 | − if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG) | |
| 3008 | − return; | |
| 3009 | − | |
| 3010 | − command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT); | |
| 3011 | − if (!command) { | |
| 3012 | − xhci_err(xhci, "Could not allocate xHCI command structure.\n"); | |
| 3013 | − return; | |
| 3014 | − } | |
| 3015 | − | |
| 3016 | − spin_lock_irqsave(&xhci->lock, flags); | |
| 3017 | − | |
| 3018 | − /* block ringing ep doorbell */ | |
| 3019 | − virt_ep->ep_state |= EP_CONFIG_PENDING; | |
| 3020 | − | |
| 3021 | − /* | |
| 3022 | − * Make sure endpoint ring is empty before resetting the toggle/seq. | |
| 3023 | − * Driver is required to synchronously cancel all transfer request. | |
| 3024 | − * | |
| 3025 | − * xhci 4.6.6 says we can issue a configure endpoint command on a | |
| 3026 | − * running endpoint ring as long as it's idle (queue empty) | |
| 3027 | − */ | |
| 3028 | − | |
| 3029 | − if (!list_empty(&virt_ep->ring->td_list)) { | |
| 3030 | − dev_err(&udev->dev, "EP not empty, refuse reset\n"); | |
| 3031 | − spin_unlock_irqrestore(&xhci->lock, flags); | |
| 3032 | − goto cleanup; | |
| 3033 | − } | |
| 3034 | − | |
| 3035 | − xhci_dbg(xhci, "Reset toggle/seq for slot %d, ep_index: %d\n", | |
| 3036 | − udev->slot_id, ep_index); | |
| 3037 | − | |
| 3038 | − ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); | |
| 3039 | − if (!ctrl_ctx) { | |
| 3040 | − xhci_err(xhci, "Could not get input context, bad type. virt_dev: %p, in_ctx %p\n", | |
| 3041 | − virt_dev, virt_dev->in_ctx); | |
| 3042 | − spin_unlock_irqrestore(&xhci->lock, flags); | |
| 3043 | − goto cleanup; | |
| 3044 | − } | |
| 3045 | − xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, | |
| 3046 | − virt_dev->out_ctx, ctrl_ctx, | |
| 3047 | − ep_flag, ep_flag); | |
| 3048 | − xhci_endpoint_copy(xhci, command->in_ctx, virt_dev->out_ctx, ep_index); | |
| 3049 | − | |
| 3050 | − xhci_queue_configure_endpoint(xhci, command, command->in_ctx->dma, | |
| 3051 | − udev->slot_id, false); | |
| 3052 | − xhci_ring_cmd_db(xhci); | |
| 3053 | − spin_unlock_irqrestore(&xhci->lock, flags); | |
| 3054 | − | |
| 3055 | − wait_for_completion(command->completion); | |
| 3056 | − | |
| 3057 | −cleanup: | |
| 3058 | − virt_ep->ep_state &= ~EP_CONFIG_PENDING; | |
| 3059 | − xhci_free_command(xhci, command); | |
| 2975 | + /* For now just print debug to follow the situation */ | |
| 2976 | + xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n", | |
| 2977 | + ep->desc.bEndpointAddress); | |
| 3060 | 2978 | } |
| 3061 | 2979 | |
| 3062 | 2980 | static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, |
| @@ -865,8 +865,6 @@ struct xhci_virt_ep { · 864 unmodified lines | ||
| 865 | 865 | #define EP_HAS_STREAMS (1 << 4) |
| 866 | 866 | /* Transitioning the endpoint to not using streams, don't enqueue URBs */ |
| 867 | 867 | #define EP_GETTING_NO_STREAMS (1 << 5) |
| 868 | −#define EP_RECENTLY_HALTED (1 << 6) | |
| 869 | −#define EP_CONFIG_PENDING (1 << 7) | |
| 870 | 868 | /* ---- Related to URB cancellation ---- */ |
| 871 | 869 | struct list_head cancelled_td_list; |
| 872 | 870 | struct xhci_td *stopped_td; |
| @@ -151,8 +151,7 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags, · 150 unmodified lines | ||
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) { |
| 154 | − ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED | | |
| 155 | − IRQF_DISABLED); | |
| 154 | + ret = isp1760_udc_register(isp, irq, irqflags); | |
| 156 | 155 | if (ret < 0) { |
| 157 | 156 | isp1760_hcd_unregister(&isp->hcd); |
| 158 | 157 | return ret; |
| @@ -1191,6 +1191,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, · 1190 unmodified lines | ||
| 1191 | 1191 | struct usb_gadget_driver *driver) |
| 1192 | 1192 | { |
| 1193 | 1193 | struct isp1760_udc *udc = gadget_to_udc(gadget); |
| 1194 | + unsigned long flags; | |
| 1194 | 1195 | |
| 1195 | 1196 | /* The hardware doesn't support low speed. */ |
| 1196 | 1197 | if (driver->max_speed < USB_SPEED_FULL) { |
| @@ -1198,7 +1199,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, · 1 unmodified line | ||
| 1198 | 1199 | return -EINVAL; |
| 1199 | 1200 | } |
| 1200 | 1201 | |
| 1201 | − spin_lock(&udc->lock); | |
| 1202 | + spin_lock_irqsave(&udc->lock, flags); | |
| 1202 | 1203 | |
| 1203 | 1204 | if (udc->driver) { |
| 1204 | 1205 | dev_err(udc->isp->dev, "UDC already has a gadget driver\n"); |
| @@ -1208,7 +1209,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, · 3 unmodified lines | ||
| 1208 | 1209 | |
| 1209 | 1210 | udc->driver = driver; |
| 1210 | 1211 | |
| 1211 | − spin_unlock(&udc->lock); | |
| 1212 | + spin_unlock_irqrestore(&udc->lock, flags); | |
| 1212 | 1213 | |
| 1213 | 1214 | dev_dbg(udc->isp->dev, "starting UDC with driver %s\n", |
| 1214 | 1215 | driver->function); |
| @@ -1232,6 +1233,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget, · 17 unmodified lines | ||
| 1232 | 1233 | static int isp1760_udc_stop(struct usb_gadget *gadget) |
| 1233 | 1234 | { |
| 1234 | 1235 | struct isp1760_udc *udc = gadget_to_udc(gadget); |
| 1236 | + unsigned long flags; | |
| 1235 | 1237 | |
| 1236 | 1238 | dev_dbg(udc->isp->dev, "%s\n", __func__); |
| 1237 | 1239 | |
| @@ -1239,9 +1241,9 @@ static int isp1760_udc_stop(struct usb_gadget *gadget) · 1 unmodified line | ||
| 1239 | 1241 | |
| 1240 | 1242 | isp1760_udc_write(udc, DC_MODE, 0); |
| 1241 | 1243 | |
| 1242 | − spin_lock(&udc->lock); | |
| 1244 | + spin_lock_irqsave(&udc->lock, flags); | |
| 1243 | 1245 | udc->driver = NULL; |
| 1244 | − spin_unlock(&udc->lock); | |
| 1246 | + spin_unlock_irqrestore(&udc->lock, flags); | |
| 1245 | 1247 | |
| 1246 | 1248 | return 0; |
| 1247 | 1249 | } |
| @@ -1411,7 +1413,7 @@ static int isp1760_udc_init(struct isp1760_udc *udc) · 163 unmodified lines | ||
| 1411 | 1413 | return -ENODEV; |
| 1412 | 1414 | } |
| 1413 | 1415 | |
| 1414 | − if (chipid != 0x00011582) { | |
| 1416 | + if (chipid != 0x00011582 && chipid != 0x00158210) { | |
| 1415 | 1417 | dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid); |
| 1416 | 1418 | return -ENODEV; |
| 1417 | 1419 | } |
| @@ -1451,8 +1453,8 @@ int isp1760_udc_register(struct isp1760_device *isp, int irq, · 33 unmodified lines | ||
| 1451 | 1453 | |
| 1452 | 1454 | sprintf(udc->irqname, "%s (udc)", devname); |
| 1453 | 1455 | |
| 1454 | − ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | IRQF_DISABLED | | |
| 1455 | − irqflags, udc->irqname, udc); | |
| 1456 | + ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | irqflags, | |
| 1457 | + udc->irqname, udc); | |
| 1456 | 1458 | if (ret < 0) |
| 1457 | 1459 | goto error; |
| 1458 | 1460 | |
| @@ -79,7 +79,8 @@ config USB_MUSB_TUSB6010 · 78 unmodified lines | ||
| 79 | 79 | |
| 80 | 80 | config USB_MUSB_OMAP2PLUS |
| 81 | 81 | tristate "OMAP2430 and onwards" |
| 82 | − depends on ARCH_OMAP2PLUS && USB && OMAP_CONTROL_PHY | |
| 82 | + depends on ARCH_OMAP2PLUS && USB | |
| 83 | + depends on OMAP_CONTROL_PHY || !OMAP_CONTROL_PHY | |
| 83 | 84 | select GENERIC_PHY |
| 84 | 85 | |
| 85 | 86 | config USB_MUSB_AM35X |
| @@ -126,6 +126,9 @@ struct phy_control *am335x_get_phy_control(struct device *dev) · 125 unmodified lines | ||
| 126 | 126 | return NULL; |
| 127 | 127 | |
| 128 | 128 | dev = bus_find_device(&platform_bus_type, NULL, node, match); |
| 129 | + if (!dev) | |
| 130 | + return NULL; | |
| 131 | + | |
| 129 | 132 | ctrl_usb = dev_get_drvdata(dev); |
| 130 | 133 | if (!ctrl_usb) |
| 131 | 134 | return NULL; |
| @@ -113,6 +113,13 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, · 112 unmodified lines | ||
| 113 | 113 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 114 | 114 | US_FL_NO_ATA_1X), |
| 115 | 115 | |
| 116 | +/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */ | |
| 117 | +UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, | |
| 118 | + "Initio Corporation", | |
| 119 | + "", | |
| 120 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 121 | + US_FL_NO_ATA_1X), | |
| 122 | + | |
| 116 | 123 | /* Reported-by: Tom Arild Naess <tanaess@gmail.com> */ |
| 117 | 124 | UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999, |
| 118 | 125 | "JMicron", |
| @@ -868,12 +868,14 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags, · 867 unmodified lines | ||
| 868 | 868 | func = vfio_pci_set_err_trigger; |
| 869 | 869 | break; |
| 870 | 870 | } |
| 871 | + break; | |
| 871 | 872 | case VFIO_PCI_REQ_IRQ_INDEX: |
| 872 | 873 | switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) { |
| 873 | 874 | case VFIO_IRQ_SET_ACTION_TRIGGER: |
| 874 | 875 | func = vfio_pci_set_req_trigger; |
| 875 | 876 | break; |
| 876 | 877 | } |
| 878 | + break; | |
| 877 | 879 | } |
| 878 | 880 | |
| 879 | 881 | if (!func) |
| @@ -1956,10 +1956,9 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, · 1955 unmodified lines | ||
| 1956 | 1956 | goto out; |
| 1957 | 1957 | } |
| 1958 | 1958 | /* |
| 1959 | − * Now register the TCM vhost virtual I_T Nexus as active with the | |
| 1960 | − * call to __transport_register_session() | |
| 1959 | + * Now register the TCM vhost virtual I_T Nexus as active. | |
| 1961 | 1960 | */ |
| 1962 | − __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1961 | + transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1963 | 1962 | tv_nexus->tvn_se_sess, tv_nexus); |
| 1964 | 1963 | tpg->tpg_nexus = tv_nexus; |
| 1965 | 1964 | |
| @@ -599,6 +599,9 @@ static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint, · 598 unmodified lines | ||
| 599 | 599 | |
| 600 | 600 | len = clcdfb_snprintf_mode(NULL, 0, mode); |
| 601 | 601 | name = devm_kzalloc(dev, len + 1, GFP_KERNEL); |
| 602 | + if (!name) | |
| 603 | + return -ENOMEM; | |
| 604 | + | |
| 602 | 605 | clcdfb_snprintf_mode(name, len + 1, mode); |
| 603 | 606 | mode->name = name; |
| 604 | 607 | |
| @@ -624,9 +624,6 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, · 623 unmodified lines | ||
| 624 | 624 | int num = 0, i, first = 1; |
| 625 | 625 | int ver, rev; |
| 626 | 626 | |
| 627 | − ver = edid[EDID_STRUCT_VERSION]; | |
| 628 | − rev = edid[EDID_STRUCT_REVISION]; | |
| 629 | − | |
| 630 | 627 | mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); |
| 631 | 628 | if (mode == NULL) |
| 632 | 629 | return NULL; |
| @@ -637,6 +634,9 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, · 4 unmodified lines | ||
| 637 | 634 | return NULL; |
| 638 | 635 | } |
| 639 | 636 | |
| 637 | + ver = edid[EDID_STRUCT_VERSION]; | |
| 638 | + rev = edid[EDID_STRUCT_REVISION]; | |
| 639 | + | |
| 640 | 640 | *dbsize = 0; |
| 641 | 641 | |
| 642 | 642 | DPRINTK(" Detailed Timings\n"); |
| @@ -28,44 +28,22 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <video/omapdss.h> |
| 29 | 29 | #include "dss.h" |
| 30 | 30 | |
| 31 | −static struct omap_dss_device *to_dss_device_sysfs(struct device *dev) | |
| 31 | +static ssize_t display_name_show(struct omap_dss_device *dssdev, char *buf) | |
| 32 | 32 | { |
| 33 | − struct omap_dss_device *dssdev = NULL; | |
| 34 | − | |
| 35 | − for_each_dss_dev(dssdev) { | |
| 36 | − if (dssdev->dev == dev) { | |
| 37 | − omap_dss_put_device(dssdev); | |
| 38 | − return dssdev; | |
| 39 | − } | |
| 40 | − } | |
| 41 | − | |
| 42 | − return NULL; | |
| 43 | −} | |
| 44 | − | |
| 45 | −static ssize_t display_name_show(struct device *dev, | |
| 46 | − struct device_attribute *attr, char *buf) | |
| 47 | −{ | |
| 48 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 49 | − | |
| 50 | 33 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 51 | 34 | dssdev->name ? |
| 52 | 35 | dssdev->name : ""); |
| 53 | 36 | } |
| 54 | 37 | |
| 55 | −static ssize_t display_enabled_show(struct device *dev, | |
| 56 | − struct device_attribute *attr, char *buf) | |
| 38 | +static ssize_t display_enabled_show(struct omap_dss_device *dssdev, char *buf) | |
| 57 | 39 | { |
| 58 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 59 | − | |
| 60 | 40 | return snprintf(buf, PAGE_SIZE, "%d\n", |
| 61 | 41 | omapdss_device_is_enabled(dssdev)); |
| 62 | 42 | } |
| 63 | 43 | |
| 64 | −static ssize_t display_enabled_store(struct device *dev, | |
| 65 | − struct device_attribute *attr, | |
| 44 | +static ssize_t display_enabled_store(struct omap_dss_device *dssdev, | |
| 66 | 45 | const char *buf, size_t size) |
| 67 | 46 | { |
| 68 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 69 | 47 | int r; |
| 70 | 48 | bool enable; |
| 71 | 49 | |
| @@ -90,19 +68,16 @@ static ssize_t display_enabled_store(struct device *dev, · 18 unmodified lines | ||
| 90 | 68 | return size; |
| 91 | 69 | } |
| 92 | 70 | |
| 93 | −static ssize_t display_tear_show(struct device *dev, | |
| 94 | − struct device_attribute *attr, char *buf) | |
| 71 | +static ssize_t display_tear_show(struct omap_dss_device *dssdev, char *buf) | |
| 95 | 72 | { |
| 96 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 97 | 73 | return snprintf(buf, PAGE_SIZE, "%d\n", |
| 98 | 74 | dssdev->driver->get_te ? |
| 99 | 75 | dssdev->driver->get_te(dssdev) : 0); |
| 100 | 76 | } |
| 101 | 77 | |
| 102 | −static ssize_t display_tear_store(struct device *dev, | |
| 103 | − struct device_attribute *attr, const char *buf, size_t size) | |
| 78 | +static ssize_t display_tear_store(struct omap_dss_device *dssdev, | |
| 79 | + const char *buf, size_t size) | |
| 104 | 80 | { |
| 105 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 106 | 81 | int r; |
| 107 | 82 | bool te; |
| 108 | 83 | |
| @@ -120,10 +95,8 @@ static ssize_t display_tear_store(struct device *dev, · 11 unmodified lines | ||
| 120 | 95 | return size; |
| 121 | 96 | } |
| 122 | 97 | |
| 123 | −static ssize_t display_timings_show(struct device *dev, | |
| 124 | − struct device_attribute *attr, char *buf) | |
| 98 | +static ssize_t display_timings_show(struct omap_dss_device *dssdev, char *buf) | |
| 125 | 99 | { |
| 126 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 127 | 100 | struct omap_video_timings t; |
| 128 | 101 | |
| 129 | 102 | if (!dssdev->driver->get_timings) |
| @@ -137,10 +110,9 @@ static ssize_t display_timings_show(struct device *dev, · 7 unmodified lines | ||
| 137 | 110 | t.y_res, t.vfp, t.vbp, t.vsw); |
| 138 | 111 | } |
| 139 | 112 | |
| 140 | −static ssize_t display_timings_store(struct device *dev, | |
| 141 | − struct device_attribute *attr, const char *buf, size_t size) | |
| 113 | +static ssize_t display_timings_store(struct omap_dss_device *dssdev, | |
| 114 | + const char *buf, size_t size) | |
| 142 | 115 | { |
| 143 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 144 | 116 | struct omap_video_timings t = dssdev->panel.timings; |
| 145 | 117 | int r, found; |
| 146 | 118 | |
| @@ -176,10 +148,8 @@ static ssize_t display_timings_store(struct device *dev, · 29 unmodified lines | ||
| 176 | 148 | return size; |
| 177 | 149 | } |
| 178 | 150 | |
| 179 | −static ssize_t display_rotate_show(struct device *dev, | |
| 180 | − struct device_attribute *attr, char *buf) | |
| 151 | +static ssize_t display_rotate_show(struct omap_dss_device *dssdev, char *buf) | |
| 181 | 152 | { |
| 182 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 183 | 153 | int rotate; |
| 184 | 154 | if (!dssdev->driver->get_rotate) |
| 185 | 155 | return -ENOENT; |
| @@ -187,10 +157,9 @@ static ssize_t display_rotate_show(struct device *dev, · 1 unmodified line | ||
| 187 | 157 | return snprintf(buf, PAGE_SIZE, "%u\n", rotate); |
| 188 | 158 | } |
| 189 | 159 | |
| 190 | −static ssize_t display_rotate_store(struct device *dev, | |
| 191 | − struct device_attribute *attr, const char *buf, size_t size) | |
| 160 | +static ssize_t display_rotate_store(struct omap_dss_device *dssdev, | |
| 161 | + const char *buf, size_t size) | |
| 192 | 162 | { |
| 193 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 194 | 163 | int rot, r; |
| 195 | 164 | |
| 196 | 165 | if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) |
| @@ -207,10 +176,8 @@ static ssize_t display_rotate_store(struct device *dev, · 10 unmodified lines | ||
| 207 | 176 | return size; |
| 208 | 177 | } |
| 209 | 178 | |
| 210 | −static ssize_t display_mirror_show(struct device *dev, | |
| 211 | − struct device_attribute *attr, char *buf) | |
| 179 | +static ssize_t display_mirror_show(struct omap_dss_device *dssdev, char *buf) | |
| 212 | 180 | { |
| 213 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 214 | 181 | int mirror; |
| 215 | 182 | if (!dssdev->driver->get_mirror) |
| 216 | 183 | return -ENOENT; |
| @@ -218,10 +185,9 @@ static ssize_t display_mirror_show(struct device *dev, · 1 unmodified line | ||
| 218 | 185 | return snprintf(buf, PAGE_SIZE, "%u\n", mirror); |
| 219 | 186 | } |
| 220 | 187 | |
| 221 | −static ssize_t display_mirror_store(struct device *dev, | |
| 222 | − struct device_attribute *attr, const char *buf, size_t size) | |
| 188 | +static ssize_t display_mirror_store(struct omap_dss_device *dssdev, | |
| 189 | + const char *buf, size_t size) | |
| 223 | 190 | { |
| 224 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 225 | 191 | int r; |
| 226 | 192 | bool mirror; |
| 227 | 193 | |
| @@ -239,10 +205,8 @@ static ssize_t display_mirror_store(struct device *dev, · 11 unmodified lines | ||
| 239 | 205 | return size; |
| 240 | 206 | } |
| 241 | 207 | |
| 242 | −static ssize_t display_wss_show(struct device *dev, | |
| 243 | − struct device_attribute *attr, char *buf) | |
| 208 | +static ssize_t display_wss_show(struct omap_dss_device *dssdev, char *buf) | |
| 244 | 209 | { |
| 245 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 246 | 210 | unsigned int wss; |
| 247 | 211 | |
| 248 | 212 | if (!dssdev->driver->get_wss) |
| @@ -253,10 +217,9 @@ static ssize_t display_wss_show(struct device *dev, · 4 unmodified lines | ||
| 253 | 217 | return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); |
| 254 | 218 | } |
| 255 | 219 | |
| 256 | −static ssize_t display_wss_store(struct device *dev, | |
| 257 | − struct device_attribute *attr, const char *buf, size_t size) | |
| 220 | +static ssize_t display_wss_store(struct omap_dss_device *dssdev, | |
| 221 | + const char *buf, size_t size) | |
| 258 | 222 | { |
| 259 | − struct omap_dss_device *dssdev = to_dss_device_sysfs(dev); | |
| 260 | 223 | u32 wss; |
| 261 | 224 | int r; |
| 262 | 225 | |
| @@ -277,50 +240,94 @@ static ssize_t display_wss_store(struct device *dev, · 14 unmodified lines | ||
| 277 | 240 | return size; |
| 278 | 241 | } |
| 279 | 242 | |
| 280 | −static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL); | |
| 281 | −static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, | |
| 243 | +struct display_attribute { | |
| 244 | + struct attribute attr; | |
| 245 | + ssize_t (*show)(struct omap_dss_device *, char *); | |
| 246 | + ssize_t (*store)(struct omap_dss_device *, const char *, size_t); | |
| 247 | +}; | |
| 248 | + | |
| 249 | +#define DISPLAY_ATTR(_name, _mode, _show, _store) \ | |
| 250 | + struct display_attribute display_attr_##_name = \ | |
| 251 | + __ATTR(_name, _mode, _show, _store) | |
| 252 | + | |
| 253 | +static DISPLAY_ATTR(name, S_IRUGO, display_name_show, NULL); | |
| 254 | +static DISPLAY_ATTR(display_name, S_IRUGO, display_name_show, NULL); | |
| 255 | +static DISPLAY_ATTR(enabled, S_IRUGO|S_IWUSR, | |
| 282 | 256 | display_enabled_show, display_enabled_store); |
| 283 | −static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, | |
| 257 | +static DISPLAY_ATTR(tear_elim, S_IRUGO|S_IWUSR, | |
| 284 | 258 | display_tear_show, display_tear_store); |
| 285 | −static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, | |
| 259 | +static DISPLAY_ATTR(timings, S_IRUGO|S_IWUSR, | |
| 286 | 260 | display_timings_show, display_timings_store); |
| 287 | −static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR, | |
| 261 | +static DISPLAY_ATTR(rotate, S_IRUGO|S_IWUSR, | |
| 288 | 262 | display_rotate_show, display_rotate_store); |
| 289 | −static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR, | |
| 263 | +static DISPLAY_ATTR(mirror, S_IRUGO|S_IWUSR, | |
| 290 | 264 | display_mirror_show, display_mirror_store); |
| 291 | −static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, | |
| 265 | +static DISPLAY_ATTR(wss, S_IRUGO|S_IWUSR, | |
| 292 | 266 | display_wss_show, display_wss_store); |
| 293 | 267 | |
| 294 | −static const struct attribute *display_sysfs_attrs[] = { | |
| 295 | − &dev_attr_display_name.attr, | |
| 296 | − &dev_attr_enabled.attr, | |
| 297 | − &dev_attr_tear_elim.attr, | |
| 298 | − &dev_attr_timings.attr, | |
| 299 | − &dev_attr_rotate.attr, | |
| 300 | − &dev_attr_mirror.attr, | |
| 301 | − &dev_attr_wss.attr, | |
| 268 | +static struct attribute *display_sysfs_attrs[] = { | |
| 269 | + &display_attr_name.attr, | |
| 270 | + &display_attr_display_name.attr, | |
| 271 | + &display_attr_enabled.attr, | |
| 272 | + &display_attr_tear_elim.attr, | |
| 273 | + &display_attr_timings.attr, | |
| 274 | + &display_attr_rotate.attr, | |
| 275 | + &display_attr_mirror.attr, | |
| 276 | + &display_attr_wss.attr, | |
| 302 | 277 | NULL |
| 303 | 278 | }; |
| 304 | 279 | |
| 280 | +static ssize_t display_attr_show(struct kobject *kobj, struct attribute *attr, | |
| 281 | + char *buf) | |
| 282 | +{ | |
| 283 | + struct omap_dss_device *dssdev; | |
| 284 | + struct display_attribute *display_attr; | |
| 285 | + | |
| 286 | + dssdev = container_of(kobj, struct omap_dss_device, kobj); | |
| 287 | + display_attr = container_of(attr, struct display_attribute, attr); | |
| 288 | + | |
| 289 | + if (!display_attr->show) | |
| 290 | + return -ENOENT; | |
| 291 | + | |
| 292 | + return display_attr->show(dssdev, buf); | |
| 293 | +} | |
| 294 | + | |
| 295 | +static ssize_t display_attr_store(struct kobject *kobj, struct attribute *attr, | |
| 296 | + const char *buf, size_t size) | |
| 297 | +{ | |
| 298 | + struct omap_dss_device *dssdev; | |
| 299 | + struct display_attribute *display_attr; | |
| 300 | + | |
| 301 | + dssdev = container_of(kobj, struct omap_dss_device, kobj); | |
| 302 | + display_attr = container_of(attr, struct display_attribute, attr); | |
| 303 | + | |
| 304 | + if (!display_attr->store) | |
| 305 | + return -ENOENT; | |
| 306 | + | |
| 307 | + return display_attr->store(dssdev, buf, size); | |
| 308 | +} | |
| 309 | + | |
| 310 | +static const struct sysfs_ops display_sysfs_ops = { | |
| 311 | + .show = display_attr_show, | |
| 312 | + .store = display_attr_store, | |
| 313 | +}; | |
| 314 | + | |
| 315 | +static struct kobj_type display_ktype = { | |
| 316 | + .sysfs_ops = &display_sysfs_ops, | |
| 317 | + .default_attrs = display_sysfs_attrs, | |
| 318 | +}; | |
| 319 | + | |
| 305 | 320 | int display_init_sysfs(struct platform_device *pdev) |
| 306 | 321 | { |
| 307 | 322 | struct omap_dss_device *dssdev = NULL; |
| 308 | 323 | int r; |
| 309 | 324 | |
| 310 | 325 | for_each_dss_dev(dssdev) { |
| 311 | − struct kobject *kobj = &dssdev->dev->kobj; | |
| 312 | − | |
| 313 | − r = sysfs_create_files(kobj, display_sysfs_attrs); | |
| 326 | + r = kobject_init_and_add(&dssdev->kobj, &display_ktype, | |
| 327 | + &pdev->dev.kobj, dssdev->alias); | |
| 314 | 328 | if (r) { |
| 315 | 329 | DSSERR("failed to create sysfs files\n"); |
| 316 | − goto err; | |
| 317 | − } | |
| 318 | − | |
| 319 | − r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias); | |
| 320 | − if (r) { | |
| 321 | − sysfs_remove_files(kobj, display_sysfs_attrs); | |
| 322 | − | |
| 323 | − DSSERR("failed to create sysfs display link\n"); | |
| 330 | + omap_dss_put_device(dssdev); | |
| 324 | 331 | goto err; |
| 325 | 332 | } |
| 326 | 333 | } |
| @@ -338,8 +345,12 @@ void display_uninit_sysfs(struct platform_device *pdev) · 11 unmodified lines | ||
| 338 | 345 | struct omap_dss_device *dssdev = NULL; |
| 339 | 346 | |
| 340 | 347 | for_each_dss_dev(dssdev) { |
| 341 | − sysfs_remove_link(&pdev->dev.kobj, dssdev->alias); | |
| 342 | − sysfs_remove_files(&dssdev->dev->kobj, | |
| 343 | − display_sysfs_attrs); | |
| 348 | + if (kobject_name(&dssdev->kobj) == NULL) | |
| 349 | + continue; | |
| 350 | + | |
| 351 | + kobject_del(&dssdev->kobj); | |
| 352 | + kobject_put(&dssdev->kobj); | |
| 353 | + | |
| 354 | + memset(&dssdev->kobj, 0, sizeof(dssdev->kobj)); | |
| 344 | 355 | } |
| 345 | 356 | } |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/module.h> |
| 30 | 30 | #include <linux/balloon_compaction.h> |
| 31 | 31 | #include <linux/oom.h> |
| 32 | +#include <linux/wait.h> | |
| 32 | 33 | |
| 33 | 34 | /* |
| 34 | 35 | * Balloon device works in 4K page units. So each page is pointed to by |
| @@ -334,17 +335,25 @@ static int virtballoon_oom_notify(struct notifier_block *self, · 299 unmodified lines | ||
| 334 | 335 | static int balloon(void *_vballoon) |
| 335 | 336 | { |
| 336 | 337 | struct virtio_balloon *vb = _vballoon; |
| 338 | + DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
| 337 | 339 | |
| 338 | 340 | set_freezable(); |
| 339 | 341 | while (!kthread_should_stop()) { |
| 340 | 342 | s64 diff; |
| 341 | 343 | |
| 342 | 344 | try_to_freeze(); |
| 343 | − wait_event_interruptible(vb->config_change, | |
| 344 | − (diff = towards_target(vb)) != 0 | |
| 345 | − || vb->need_stats_update | |
| 346 | − || kthread_should_stop() | |
| 347 | − || freezing(current)); | |
| 345 | + | |
| 346 | + add_wait_queue(&vb->config_change, &wait); | |
| 347 | + for (;;) { | |
| 348 | + if ((diff = towards_target(vb)) != 0 || | |
| 349 | + vb->need_stats_update || | |
| 350 | + kthread_should_stop() || | |
| 351 | + freezing(current)) | |
| 352 | + break; | |
| 353 | + wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); | |
| 354 | + } | |
| 355 | + remove_wait_queue(&vb->config_change, &wait); | |
| 356 | + | |
| 348 | 357 | if (vb->need_stats_update) |
| 349 | 358 | stats_handle_request(vb); |
| 350 | 359 | if (diff > 0) |
| @@ -499,6 +508,8 @@ static int virtballoon_probe(struct virtio_device *vdev) · 148 unmodified lines | ||
| 499 | 508 | if (err < 0) |
| 500 | 509 | goto out_oom_notify; |
| 501 | 510 | |
| 511 | + virtio_device_ready(vdev); | |
| 512 | + | |
| 502 | 513 | vb->thread = kthread_run(balloon, vb, "vballoon"); |
| 503 | 514 | if (IS_ERR(vb->thread)) { |
| 504 | 515 | err = PTR_ERR(vb->thread); |
| @@ -156,22 +156,95 @@ static void vm_get(struct virtio_device *vdev, unsigned offset, · 155 unmodified lines | ||
| 156 | 156 | void *buf, unsigned len) |
| 157 | 157 | { |
| 158 | 158 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 159 | − u8 *ptr = buf; | |
| 160 | − int i; | |
| 159 | + void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG; | |
| 160 | + u8 b; | |
| 161 | + __le16 w; | |
| 162 | + __le32 l; | |
| 161 | 163 | |
| 162 | − for (i = 0; i < len; i++) | |
| 163 | − ptr[i] = readb(vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); | |
| 164 | + if (vm_dev->version == 1) { | |
| 165 | + u8 *ptr = buf; | |
| 166 | + int i; | |
| 167 | + | |
| 168 | + for (i = 0; i < len; i++) | |
| 169 | + ptr[i] = readb(base + offset + i); | |
| 170 | + return; | |
| 171 | + } | |
| 172 | + | |
| 173 | + switch (len) { | |
| 174 | + case 1: | |
| 175 | + b = readb(base + offset); | |
| 176 | + memcpy(buf, &b, sizeof b); | |
| 177 | + break; | |
| 178 | + case 2: | |
| 179 | + w = cpu_to_le16(readw(base + offset)); | |
| 180 | + memcpy(buf, &w, sizeof w); | |
| 181 | + break; | |
| 182 | + case 4: | |
| 183 | + l = cpu_to_le32(readl(base + offset)); | |
| 184 | + memcpy(buf, &l, sizeof l); | |
| 185 | + break; | |
| 186 | + case 8: | |
| 187 | + l = cpu_to_le32(readl(base + offset)); | |
| 188 | + memcpy(buf, &l, sizeof l); | |
| 189 | + l = cpu_to_le32(ioread32(base + offset + sizeof l)); | |
| 190 | + memcpy(buf + sizeof l, &l, sizeof l); | |
| 191 | + break; | |
| 192 | + default: | |
| 193 | + BUG(); | |
| 194 | + } | |
| 164 | 195 | } |
| 165 | 196 | |
| 166 | 197 | static void vm_set(struct virtio_device *vdev, unsigned offset, |
| 167 | 198 | const void *buf, unsigned len) |
| 168 | 199 | { |
| 169 | 200 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); |
| 170 | − const u8 *ptr = buf; | |
| 171 | − int i; | |
| 201 | + void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG; | |
| 202 | + u8 b; | |
| 203 | + __le16 w; | |
| 204 | + __le32 l; | |
| 172 | 205 | |
| 173 | − for (i = 0; i < len; i++) | |
| 174 | − writeb(ptr[i], vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); | |
| 206 | + if (vm_dev->version == 1) { | |
| 207 | + const u8 *ptr = buf; | |
| 208 | + int i; | |
| 209 | + | |
| 210 | + for (i = 0; i < len; i++) | |
| 211 | + writeb(ptr[i], base + offset + i); | |
| 212 | + | |
| 213 | + return; | |
| 214 | + } | |
| 215 | + | |
| 216 | + switch (len) { | |
| 217 | + case 1: | |
| 218 | + memcpy(&b, buf, sizeof b); | |
| 219 | + writeb(b, base + offset); | |
| 220 | + break; | |
| 221 | + case 2: | |
| 222 | + memcpy(&w, buf, sizeof w); | |
| 223 | + writew(le16_to_cpu(w), base + offset); | |
| 224 | + break; | |
| 225 | + case 4: | |
| 226 | + memcpy(&l, buf, sizeof l); | |
| 227 | + writel(le32_to_cpu(l), base + offset); | |
| 228 | + break; | |
| 229 | + case 8: | |
| 230 | + memcpy(&l, buf, sizeof l); | |
| 231 | + writel(le32_to_cpu(l), base + offset); | |
| 232 | + memcpy(&l, buf + sizeof l, sizeof l); | |
| 233 | + writel(le32_to_cpu(l), base + offset + sizeof l); | |
| 234 | + break; | |
| 235 | + default: | |
| 236 | + BUG(); | |
| 237 | + } | |
| 238 | +} | |
| 239 | + | |
| 240 | +static u32 vm_generation(struct virtio_device *vdev) | |
| 241 | +{ | |
| 242 | + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); | |
| 243 | + | |
| 244 | + if (vm_dev->version == 1) | |
| 245 | + return 0; | |
| 246 | + else | |
| 247 | + return readl(vm_dev->base + VIRTIO_MMIO_CONFIG_GENERATION); | |
| 175 | 248 | } |
| 176 | 249 | |
| 177 | 250 | static u8 vm_get_status(struct virtio_device *vdev) |
| @@ -440,6 +513,7 @@ static const char *vm_bus_name(struct virtio_device *vdev) · 262 unmodified lines | ||
| 440 | 513 | static const struct virtio_config_ops virtio_mmio_config_ops = { |
| 441 | 514 | .get = vm_get, |
| 442 | 515 | .set = vm_set, |
| 516 | + .generation = vm_generation, | |
| 443 | 517 | .get_status = vm_get_status, |
| 444 | 518 | .set_status = vm_set_status, |
| 445 | 519 | .reset = vm_reset, |
| @@ -526,20 +526,26 @@ static unsigned int __startup_pirq(unsigned int irq) · 525 unmodified lines | ||
| 526 | 526 | pirq_query_unmask(irq); |
| 527 | 527 | |
| 528 | 528 | rc = set_evtchn_to_irq(evtchn, irq); |
| 529 | − if (rc != 0) { | |
| 530 | − pr_err("irq%d: Failed to set port to irq mapping (%d)\n", | |
| 531 | − irq, rc); | |
| 532 | − xen_evtchn_close(evtchn); | |
| 533 | − return 0; | |
| 534 | − } | |
| 529 | + if (rc) | |
| 530 | + goto err; | |
| 531 | + | |
| 535 | 532 | bind_evtchn_to_cpu(evtchn, 0); |
| 536 | 533 | info->evtchn = evtchn; |
| 537 | 534 | |
| 535 | + rc = xen_evtchn_port_setup(info); | |
| 536 | + if (rc) | |
| 537 | + goto err; | |
| 538 | + | |
| 538 | 539 | out: |
| 539 | 540 | unmask_evtchn(evtchn); |
| 540 | 541 | eoi_pirq(irq_get_irq_data(irq)); |
| 541 | 542 | |
| 542 | 543 | return 0; |
| 544 | + | |
| 545 | +err: | |
| 546 | + pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc); | |
| 547 | + xen_evtchn_close(evtchn); | |
| 548 | + return 0; | |
| 543 | 549 | } |
| 544 | 550 | |
| 545 | 551 | static unsigned int startup_pirq(struct irq_data *data) |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include "conf_space.h" |
| 17 | 17 | #include "conf_space_quirks.h" |
| 18 | 18 | |
| 19 | −static bool permissive; | |
| 19 | +bool permissive; | |
| 20 | 20 | module_param(permissive, bool, 0644); |
| 21 | 21 | |
| 22 | 22 | /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, |
| @@ -64,6 +64,8 @@ struct config_field_entry { · 63 unmodified lines | ||
| 64 | 64 | void *data; |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | +extern bool permissive; | |
| 68 | + | |
| 67 | 69 | #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset) |
| 68 | 70 | |
| 69 | 71 | /* Add fields to a device - the add_fields macro expects to get a pointer to |
| @@ -11,6 +11,10 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "pciback.h" |
| 12 | 12 | #include "conf_space.h" |
| 13 | 13 | |
| 14 | +struct pci_cmd_info { | |
| 15 | + u16 val; | |
| 16 | +}; | |
| 17 | + | |
| 14 | 18 | struct pci_bar_info { |
| 15 | 19 | u32 val; |
| 16 | 20 | u32 len_val; |
| @@ -20,22 +24,36 @@ struct pci_bar_info { · 3 unmodified lines | ||
| 20 | 24 | #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO)) |
| 21 | 25 | #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER) |
| 22 | 26 | |
| 23 | −static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data) | |
| 27 | +/* Bits guests are allowed to control in permissive mode. */ | |
| 28 | +#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \ | |
| 29 | + PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \ | |
| 30 | + PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK) | |
| 31 | + | |
| 32 | +static void *command_init(struct pci_dev *dev, int offset) | |
| 24 | 33 | { |
| 25 | − int i; | |
| 26 | − int ret; | |
| 27 | − | |
| 28 | − ret = xen_pcibk_read_config_word(dev, offset, value, data); | |
| 29 | − if (!pci_is_enabled(dev)) | |
| 30 | − return ret; | |
| 31 | − | |
| 32 | − for (i = 0; i < PCI_ROM_RESOURCE; i++) { | |
| 33 | − if (dev->resource[i].flags & IORESOURCE_IO) | |
| 34 | − *value |= PCI_COMMAND_IO; | |
| 35 | − if (dev->resource[i].flags & IORESOURCE_MEM) | |
| 36 | − *value |= PCI_COMMAND_MEMORY; | |
| 34 | + struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); | |
| 35 | + int err; | |
| 36 | + | |
| 37 | + if (!cmd) | |
| 38 | + return ERR_PTR(-ENOMEM); | |
| 39 | + | |
| 40 | + err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val); | |
| 41 | + if (err) { | |
| 42 | + kfree(cmd); | |
| 43 | + return ERR_PTR(err); | |
| 37 | 44 | } |
| 38 | 45 | |
| 46 | + return cmd; | |
| 47 | +} | |
| 48 | + | |
| 49 | +static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data) | |
| 50 | +{ | |
| 51 | + int ret = pci_read_config_word(dev, offset, value); | |
| 52 | + const struct pci_cmd_info *cmd = data; | |
| 53 | + | |
| 54 | + *value &= PCI_COMMAND_GUEST; | |
| 55 | + *value |= cmd->val & ~PCI_COMMAND_GUEST; | |
| 56 | + | |
| 39 | 57 | return ret; |
| 40 | 58 | } |
| 41 | 59 | |
| @@ -43,6 +61,8 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) · 1 unmodified line | ||
| 43 | 61 | { |
| 44 | 62 | struct xen_pcibk_dev_data *dev_data; |
| 45 | 63 | int err; |
| 64 | + u16 val; | |
| 65 | + struct pci_cmd_info *cmd = data; | |
| 46 | 66 | |
| 47 | 67 | dev_data = pci_get_drvdata(dev); |
| 48 | 68 | if (!pci_is_enabled(dev) && is_enable_cmd(value)) { |
| @@ -83,6 +103,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) · 34 unmodified lines | ||
| 83 | 103 | } |
| 84 | 104 | } |
| 85 | 105 | |
| 106 | + cmd->val = value; | |
| 107 | + | |
| 108 | + if (!permissive && (!dev_data || !dev_data->permissive)) | |
| 109 | + return 0; | |
| 110 | + | |
| 111 | + /* Only allow the guest to control certain bits. */ | |
| 112 | + err = pci_read_config_word(dev, offset, &val); | |
| 113 | + if (err || val == value) | |
| 114 | + return err; | |
| 115 | + | |
| 116 | + value &= PCI_COMMAND_GUEST; | |
| 117 | + value |= val & ~PCI_COMMAND_GUEST; | |
| 118 | + | |
| 86 | 119 | return pci_write_config_word(dev, offset, value); |
| 87 | 120 | } |
| 88 | 121 | |
| @@ -282,6 +315,8 @@ static const struct config_field header_common[] = { · 193 unmodified lines | ||
| 282 | 315 | { |
| 283 | 316 | .offset = PCI_COMMAND, |
| 284 | 317 | .size = 2, |
| 318 | + .init = command_init, | |
| 319 | + .release = bar_release, | |
| 285 | 320 | .u.w.read = command_read, |
| 286 | 321 | .u.w.write = command_write, |
| 287 | 322 | }, |
| @@ -1659,11 +1659,8 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg, · 1658 unmodified lines | ||
| 1659 | 1659 | name); |
| 1660 | 1660 | goto out; |
| 1661 | 1661 | } |
| 1662 | − /* | |
| 1663 | − * Now register the TCM pvscsi virtual I_T Nexus as active with the | |
| 1664 | − * call to __transport_register_session() | |
| 1665 | − */ | |
| 1666 | − __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1662 | + /* Now register the TCM pvscsi virtual I_T Nexus as active. */ | |
| 1663 | + transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | |
| 1667 | 1664 | tv_nexus->tvn_se_sess, tv_nexus); |
| 1668 | 1665 | tpg->tpg_nexus = tv_nexus; |
| 1669 | 1666 | |
| @@ -3387,6 +3387,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, · 3386 unmodified lines | ||
| 3387 | 3387 | |
| 3388 | 3388 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
| 3389 | 3389 | struct btrfs_root *root); |
| 3390 | +int btrfs_setup_space_cache(struct btrfs_trans_handle *trans, | |
| 3391 | + struct btrfs_root *root); | |
| 3390 | 3392 | int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr); |
| 3391 | 3393 | int btrfs_free_block_groups(struct btrfs_fs_info *info); |
| 3392 | 3394 | int btrfs_read_block_groups(struct btrfs_root *root); |
| @@ -3909,6 +3911,9 @@ int btrfs_prealloc_file_range_trans(struct inode *inode, · 516 unmodified lines | ||
| 3909 | 3911 | loff_t actual_len, u64 *alloc_hint); |
| 3910 | 3912 | int btrfs_inode_check_errors(struct inode *inode); |
| 3911 | 3913 | extern const struct dentry_operations btrfs_dentry_operations; |
| 3914 | +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | |
| 3915 | +void btrfs_test_inode_set_ops(struct inode *inode); | |
| 3916 | +#endif | |
| 3912 | 3917 | |
| 3913 | 3918 | /* ioctl.c */ |
| 3914 | 3919 | long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
| @@ -3921,7 +3921,7 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, · 3920 unmodified lines | ||
| 3921 | 3921 | } |
| 3922 | 3922 | if (btrfs_super_sys_array_size(sb) < sizeof(struct btrfs_disk_key) |
| 3923 | 3923 | + sizeof(struct btrfs_chunk)) { |
| 3924 | − printk(KERN_ERR "BTRFS: system chunk array too small %u < %lu\n", | |
| 3924 | + printk(KERN_ERR "BTRFS: system chunk array too small %u < %zu\n", | |
| 3925 | 3925 | btrfs_super_sys_array_size(sb), |
| 3926 | 3926 | sizeof(struct btrfs_disk_key) |
| 3927 | 3927 | + sizeof(struct btrfs_chunk)); |
| @@ -3325,6 +3325,32 @@ out: · 3324 unmodified lines | ||
| 3325 | 3325 | return ret; |
| 3326 | 3326 | } |
| 3327 | 3327 | |
| 3328 | +int btrfs_setup_space_cache(struct btrfs_trans_handle *trans, | |
| 3329 | + struct btrfs_root *root) | |
| 3330 | +{ | |
| 3331 | + struct btrfs_block_group_cache *cache, *tmp; | |
| 3332 | + struct btrfs_transaction *cur_trans = trans->transaction; | |
| 3333 | + struct btrfs_path *path; | |
| 3334 | + | |
| 3335 | + if (list_empty(&cur_trans->dirty_bgs) || | |
| 3336 | + !btrfs_test_opt(root, SPACE_CACHE)) | |
| 3337 | + return 0; | |
| 3338 | + | |
| 3339 | + path = btrfs_alloc_path(); | |
| 3340 | + if (!path) | |
| 3341 | + return -ENOMEM; | |
| 3342 | + | |
| 3343 | + /* Could add new block groups, use _safe just in case */ | |
| 3344 | + list_for_each_entry_safe(cache, tmp, &cur_trans->dirty_bgs, | |
| 3345 | + dirty_list) { | |
| 3346 | + if (cache->disk_cache_state == BTRFS_DC_CLEAR) | |
| 3347 | + cache_save_setup(cache, trans, path); | |
| 3348 | + } | |
| 3349 | + | |
| 3350 | + btrfs_free_path(path); | |
| 3351 | + return 0; | |
| 3352 | +} | |
| 3353 | + | |
| 3328 | 3354 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
| 3329 | 3355 | struct btrfs_root *root) |
| 3330 | 3356 | { |
| @@ -5110,7 +5136,11 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) · 1779 unmodified lines | ||
| 5110 | 5136 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
| 5111 | 5137 | |
| 5112 | 5138 | spin_lock(&BTRFS_I(inode)->lock); |
| 5113 | − BTRFS_I(inode)->outstanding_extents++; | |
| 5139 | + nr_extents = (unsigned)div64_u64(num_bytes + | |
| 5140 | + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 5141 | + BTRFS_MAX_EXTENT_SIZE); | |
| 5142 | + BTRFS_I(inode)->outstanding_extents += nr_extents; | |
| 5143 | + nr_extents = 0; | |
| 5114 | 5144 | |
| 5115 | 5145 | if (BTRFS_I(inode)->outstanding_extents > |
| 5116 | 5146 | BTRFS_I(inode)->reserved_extents) |
| @@ -5255,6 +5285,9 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) · 138 unmodified lines | ||
| 5255 | 5285 | if (dropped > 0) |
| 5256 | 5286 | to_free += btrfs_calc_trans_metadata_size(root, dropped); |
| 5257 | 5287 | |
| 5288 | + if (btrfs_test_is_dummy_root(root)) | |
| 5289 | + return; | |
| 5290 | + | |
| 5258 | 5291 | trace_btrfs_space_reservation(root->fs_info, "delalloc", |
| 5259 | 5292 | btrfs_ino(inode), to_free, 0); |
| 5260 | 5293 | if (root->fs_info->quota_enabled) { |
| @@ -4968,6 +4968,12 @@ static int release_extent_buffer(struct extent_buffer *eb) · 4967 unmodified lines | ||
| 4968 | 4968 | |
| 4969 | 4969 | /* Should be safe to release our pages at this point */ |
| 4970 | 4970 | btrfs_release_extent_buffer_page(eb); |
| 4971 | +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | |
| 4972 | + if (unlikely(test_bit(EXTENT_BUFFER_DUMMY, &eb->bflags))) { | |
| 4973 | + __free_extent_buffer(eb); | |
| 4974 | + return 1; | |
| 4975 | + } | |
| 4976 | +#endif | |
| 4971 | 4977 | call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); |
| 4972 | 4978 | return 1; |
| 4973 | 4979 | } |
| @@ -108,6 +108,13 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start, · 107 unmodified lines | ||
| 108 | 108 | |
| 109 | 109 | static int btrfs_dirty_inode(struct inode *inode); |
| 110 | 110 | |
| 111 | +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | |
| 112 | +void btrfs_test_inode_set_ops(struct inode *inode) | |
| 113 | +{ | |
| 114 | + BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | |
| 115 | +} | |
| 116 | +#endif | |
| 117 | + | |
| 111 | 118 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, |
| 112 | 119 | struct inode *inode, struct inode *dir, |
| 113 | 120 | const struct qstr *qstr) |
| @@ -1542,30 +1549,17 @@ static void btrfs_split_extent_hook(struct inode *inode, · 1428 unmodified lines | ||
| 1542 | 1549 | u64 new_size; |
| 1543 | 1550 | |
| 1544 | 1551 | /* |
| 1545 | − * We need the largest size of the remaining extent to see if we | |
| 1546 | − * need to add a new outstanding extent. Think of the following | |
| 1547 | − * case | |
| 1548 | − * | |
| 1549 | − * [MEAX_EXTENT_SIZEx2 - 4k][4k] | |
| 1550 | − * | |
| 1551 | − * The new_size would just be 4k and we'd think we had enough | |
| 1552 | − * outstanding extents for this if we only took one side of the | |
| 1553 | − * split, same goes for the other direction. We need to see if | |
| 1554 | − * the larger size still is the same amount of extents as the | |
| 1555 | − * original size, because if it is we need to add a new | |
| 1556 | − * outstanding extent. But if we split up and the larger size | |
| 1557 | − * is less than the original then we are good to go since we've | |
| 1558 | − * already accounted for the extra extent in our original | |
| 1559 | − * accounting. | |
| 1552 | + * See the explanation in btrfs_merge_extent_hook, the same | |
| 1553 | + * applies here, just in reverse. | |
| 1560 | 1554 | */ |
| 1561 | 1555 | new_size = orig->end - split + 1; |
| 1562 | − if ((split - orig->start) > new_size) | |
| 1563 | − new_size = split - orig->start; | |
| 1564 | − | |
| 1565 | − num_extents = div64_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1556 | + num_extents = div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1566 | 1557 | BTRFS_MAX_EXTENT_SIZE); |
| 1567 | − if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1568 | − BTRFS_MAX_EXTENT_SIZE) < num_extents) | |
| 1558 | + new_size = split - orig->start; | |
| 1559 | + num_extents += div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1560 | + BTRFS_MAX_EXTENT_SIZE); | |
| 1561 | + if (div64_u64(size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1562 | + BTRFS_MAX_EXTENT_SIZE) >= num_extents) | |
| 1569 | 1563 | return; |
| 1570 | 1564 | } |
| 1571 | 1565 | |
| @@ -1591,8 +1585,10 @@ static void btrfs_merge_extent_hook(struct inode *inode, · 19 unmodified lines | ||
| 1591 | 1585 | if (!(other->state & EXTENT_DELALLOC)) |
| 1592 | 1586 | return; |
| 1593 | 1587 | |
| 1594 | − old_size = other->end - other->start + 1; | |
| 1595 | − new_size = old_size + (new->end - new->start + 1); | |
| 1588 | + if (new->start > other->start) | |
| 1589 | + new_size = new->end - other->start + 1; | |
| 1590 | + else | |
| 1591 | + new_size = other->end - new->start + 1; | |
| 1596 | 1592 | |
| 1597 | 1593 | /* we're not bigger than the max, unreserve the space and go */ |
| 1598 | 1594 | if (new_size <= BTRFS_MAX_EXTENT_SIZE) { |
| @@ -1603,13 +1599,32 @@ static void btrfs_merge_extent_hook(struct inode *inode, · 4 unmodified lines | ||
| 1603 | 1599 | } |
| 1604 | 1600 | |
| 1605 | 1601 | /* |
| 1606 | − * If we grew by another max_extent, just return, we want to keep that | |
| 1607 | − * reserved amount. | |
| 1602 | + * We have to add up either side to figure out how many extents were | |
| 1603 | + * accounted for before we merged into one big extent. If the number of | |
| 1604 | + * extents we accounted for is <= the amount we need for the new range | |
| 1605 | + * then we can return, otherwise drop. Think of it like this | |
| 1606 | + * | |
| 1607 | + * [ 4k][MAX_SIZE] | |
| 1608 | + * | |
| 1609 | + * So we've grown the extent by a MAX_SIZE extent, this would mean we | |
| 1610 | + * need 2 outstanding extents, on one side we have 1 and the other side | |
| 1611 | + * we have 1 so they are == and we can return. But in this case | |
| 1612 | + * | |
| 1613 | + * [MAX_SIZE+4k][MAX_SIZE+4k] | |
| 1614 | + * | |
| 1615 | + * Each range on their own accounts for 2 extents, but merged together | |
| 1616 | + * they are only 3 extents worth of accounting, so we need to drop in | |
| 1617 | + * this case. | |
| 1608 | 1618 | */ |
| 1619 | + old_size = other->end - other->start + 1; | |
| 1609 | 1620 | num_extents = div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1610 | 1621 | BTRFS_MAX_EXTENT_SIZE); |
| 1622 | + old_size = new->end - new->start + 1; | |
| 1623 | + num_extents += div64_u64(old_size + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 1624 | + BTRFS_MAX_EXTENT_SIZE); | |
| 1625 | + | |
| 1611 | 1626 | if (div64_u64(new_size + BTRFS_MAX_EXTENT_SIZE - 1, |
| 1612 | − BTRFS_MAX_EXTENT_SIZE) > num_extents) | |
| 1627 | + BTRFS_MAX_EXTENT_SIZE) >= num_extents) | |
| 1613 | 1628 | return; |
| 1614 | 1629 | |
| 1615 | 1630 | spin_lock(&BTRFS_I(inode)->lock); |
| @@ -1686,6 +1701,10 @@ static void btrfs_set_bit_hook(struct inode *inode, · 70 unmodified lines | ||
| 1686 | 1701 | spin_unlock(&BTRFS_I(inode)->lock); |
| 1687 | 1702 | } |
| 1688 | 1703 | |
| 1704 | + /* For sanity tests */ | |
| 1705 | + if (btrfs_test_is_dummy_root(root)) | |
| 1706 | + return; | |
| 1707 | + | |
| 1689 | 1708 | __percpu_counter_add(&root->fs_info->delalloc_bytes, len, |
| 1690 | 1709 | root->fs_info->delalloc_batch); |
| 1691 | 1710 | spin_lock(&BTRFS_I(inode)->lock); |
| @@ -1741,6 +1760,10 @@ static void btrfs_clear_bit_hook(struct inode *inode, · 49 unmodified lines | ||
| 1741 | 1760 | root != root->fs_info->tree_root) |
| 1742 | 1761 | btrfs_delalloc_release_metadata(inode, len); |
| 1743 | 1762 | |
| 1763 | + /* For sanity tests. */ | |
| 1764 | + if (btrfs_test_is_dummy_root(root)) | |
| 1765 | + return; | |
| 1766 | + | |
| 1744 | 1767 | if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID |
| 1745 | 1768 | && do_list && !(state->state & EXTENT_NORESERVE)) |
| 1746 | 1769 | btrfs_free_reserved_data_space(inode, len); |
| @@ -7213,7 +7236,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, · 5466 unmodified lines | ||
| 7213 | 7236 | u64 start = iblock << inode->i_blkbits; |
| 7214 | 7237 | u64 lockstart, lockend; |
| 7215 | 7238 | u64 len = bh_result->b_size; |
| 7216 | − u64 orig_len = len; | |
| 7239 | + u64 *outstanding_extents = NULL; | |
| 7217 | 7240 | int unlock_bits = EXTENT_LOCKED; |
| 7218 | 7241 | int ret = 0; |
| 7219 | 7242 | |
| @@ -7225,6 +7248,16 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, · 5 unmodified lines | ||
| 7225 | 7248 | lockstart = start; |
| 7226 | 7249 | lockend = start + len - 1; |
| 7227 | 7250 | |
| 7251 | + if (current->journal_info) { | |
| 7252 | + /* | |
| 7253 | + * Need to pull our outstanding extents and set journal_info to NULL so | |
| 7254 | + * that anything that needs to check if there's a transction doesn't get | |
| 7255 | + * confused. | |
| 7256 | + */ | |
| 7257 | + outstanding_extents = current->journal_info; | |
| 7258 | + current->journal_info = NULL; | |
| 7259 | + } | |
| 7260 | + | |
| 7228 | 7261 | /* |
| 7229 | 7262 | * If this errors out it's because we couldn't invalidate pagecache for |
| 7230 | 7263 | * this range and we need to fallback to buffered. |
| @@ -7348,11 +7381,20 @@ unlock: · 117 unmodified lines | ||
| 7348 | 7381 | if (start + len > i_size_read(inode)) |
| 7349 | 7382 | i_size_write(inode, start + len); |
| 7350 | 7383 | |
| 7351 | − if (len < orig_len) { | |
| 7384 | + /* | |
| 7385 | + * If we have an outstanding_extents count still set then we're | |
| 7386 | + * within our reservation, otherwise we need to adjust our inode | |
| 7387 | + * counter appropriately. | |
| 7388 | + */ | |
| 7389 | + if (*outstanding_extents) { | |
| 7390 | + (*outstanding_extents)--; | |
| 7391 | + } else { | |
| 7352 | 7392 | spin_lock(&BTRFS_I(inode)->lock); |
| 7353 | 7393 | BTRFS_I(inode)->outstanding_extents++; |
| 7354 | 7394 | spin_unlock(&BTRFS_I(inode)->lock); |
| 7355 | 7395 | } |
| 7396 | + | |
| 7397 | + current->journal_info = outstanding_extents; | |
| 7356 | 7398 | btrfs_free_reserved_data_space(inode, len); |
| 7357 | 7399 | } |
| 7358 | 7400 | |
| @@ -7376,6 +7418,8 @@ unlock: · 17 unmodified lines | ||
| 7376 | 7418 | unlock_err: |
| 7377 | 7419 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, |
| 7378 | 7420 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); |
| 7421 | + if (outstanding_extents) | |
| 7422 | + current->journal_info = outstanding_extents; | |
| 7379 | 7423 | return ret; |
| 7380 | 7424 | } |
| 7381 | 7425 | |
| @@ -8075,6 +8119,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, · 693 unmodified lines | ||
| 8075 | 8119 | { |
| 8076 | 8120 | struct file *file = iocb->ki_filp; |
| 8077 | 8121 | struct inode *inode = file->f_mapping->host; |
| 8122 | + u64 outstanding_extents = 0; | |
| 8078 | 8123 | size_t count = 0; |
| 8079 | 8124 | int flags = 0; |
| 8080 | 8125 | bool wakeup = true; |
| @@ -8112,6 +8157,16 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, · 31 unmodified lines | ||
| 8112 | 8157 | ret = btrfs_delalloc_reserve_space(inode, count); |
| 8113 | 8158 | if (ret) |
| 8114 | 8159 | goto out; |
| 8160 | + outstanding_extents = div64_u64(count + | |
| 8161 | + BTRFS_MAX_EXTENT_SIZE - 1, | |
| 8162 | + BTRFS_MAX_EXTENT_SIZE); | |
| 8163 | + | |
| 8164 | + /* | |
| 8165 | + * We need to know how many extents we reserved so that we can | |
| 8166 | + * do the accounting properly if we go over the number we | |
| 8167 | + * originally calculated. Abuse current->journal_info for this. | |
| 8168 | + */ | |
| 8169 | + current->journal_info = &outstanding_extents; | |
| 8115 | 8170 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, |
| 8116 | 8171 | &BTRFS_I(inode)->runtime_flags)) { |
| 8117 | 8172 | inode_dio_done(inode); |
| @@ -8124,6 +8179,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, · 6 unmodified lines | ||
| 8124 | 8179 | iter, offset, btrfs_get_blocks_direct, NULL, |
| 8125 | 8180 | btrfs_submit_direct, flags); |
| 8126 | 8181 | if (rw & WRITE) { |
| 8182 | + current->journal_info = NULL; | |
| 8127 | 8183 | if (ret < 0 && ret != -EIOCBQUEUED) |
| 8128 | 8184 | btrfs_delalloc_release_space(inode, count); |
| 8129 | 8185 | else if (ret >= 0 && (size_t)ret < count) |
| @@ -1259,7 +1259,7 @@ static int comp_oper(struct btrfs_qgroup_operation *oper1, · 1258 unmodified lines | ||
| 1259 | 1259 | if (oper1->seq < oper2->seq) |
| 1260 | 1260 | return -1; |
| 1261 | 1261 | if (oper1->seq > oper2->seq) |
| 1262 | − return -1; | |
| 1262 | + return 1; | |
| 1263 | 1263 | if (oper1->ref_root < oper2->ref_root) |
| 1264 | 1264 | return -1; |
| 1265 | 1265 | if (oper1->ref_root > oper2->ref_root) |
| @@ -911,6 +911,197 @@ out: · 910 unmodified lines | ||
| 911 | 911 | return ret; |
| 912 | 912 | } |
| 913 | 913 | |
| 914 | +static int test_extent_accounting(void) | |
| 915 | +{ | |
| 916 | + struct inode *inode = NULL; | |
| 917 | + struct btrfs_root *root = NULL; | |
| 918 | + int ret = -ENOMEM; | |
| 919 | + | |
| 920 | + inode = btrfs_new_test_inode(); | |
| 921 | + if (!inode) { | |
| 922 | + test_msg("Couldn't allocate inode\n"); | |
| 923 | + return ret; | |
| 924 | + } | |
| 925 | + | |
| 926 | + root = btrfs_alloc_dummy_root(); | |
| 927 | + if (IS_ERR(root)) { | |
| 928 | + test_msg("Couldn't allocate root\n"); | |
| 929 | + goto out; | |
| 930 | + } | |
| 931 | + | |
| 932 | + root->fs_info = btrfs_alloc_dummy_fs_info(); | |
| 933 | + if (!root->fs_info) { | |
| 934 | + test_msg("Couldn't allocate dummy fs info\n"); | |
| 935 | + goto out; | |
| 936 | + } | |
| 937 | + | |
| 938 | + BTRFS_I(inode)->root = root; | |
| 939 | + btrfs_test_inode_set_ops(inode); | |
| 940 | + | |
| 941 | + /* [BTRFS_MAX_EXTENT_SIZE] */ | |
| 942 | + BTRFS_I(inode)->outstanding_extents++; | |
| 943 | + ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, | |
| 944 | + NULL); | |
| 945 | + if (ret) { | |
| 946 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 947 | + goto out; | |
| 948 | + } | |
| 949 | + if (BTRFS_I(inode)->outstanding_extents != 1) { | |
| 950 | + ret = -EINVAL; | |
| 951 | + test_msg("Miscount, wanted 1, got %u\n", | |
| 952 | + BTRFS_I(inode)->outstanding_extents); | |
| 953 | + goto out; | |
| 954 | + } | |
| 955 | + | |
| 956 | + /* [BTRFS_MAX_EXTENT_SIZE][4k] */ | |
| 957 | + BTRFS_I(inode)->outstanding_extents++; | |
| 958 | + ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, | |
| 959 | + BTRFS_MAX_EXTENT_SIZE + 4095, NULL); | |
| 960 | + if (ret) { | |
| 961 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 962 | + goto out; | |
| 963 | + } | |
| 964 | + if (BTRFS_I(inode)->outstanding_extents != 2) { | |
| 965 | + ret = -EINVAL; | |
| 966 | + test_msg("Miscount, wanted 2, got %u\n", | |
| 967 | + BTRFS_I(inode)->outstanding_extents); | |
| 968 | + goto out; | |
| 969 | + } | |
| 970 | + | |
| 971 | + /* [BTRFS_MAX_EXTENT_SIZE/2][4K HOLE][the rest] */ | |
| 972 | + ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | |
| 973 | + BTRFS_MAX_EXTENT_SIZE >> 1, | |
| 974 | + (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095, | |
| 975 | + EXTENT_DELALLOC | EXTENT_DIRTY | | |
| 976 | + EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING, 0, 0, | |
| 977 | + NULL, GFP_NOFS); | |
| 978 | + if (ret) { | |
| 979 | + test_msg("clear_extent_bit returned %d\n", ret); | |
| 980 | + goto out; | |
| 981 | + } | |
| 982 | + if (BTRFS_I(inode)->outstanding_extents != 2) { | |
| 983 | + ret = -EINVAL; | |
| 984 | + test_msg("Miscount, wanted 2, got %u\n", | |
| 985 | + BTRFS_I(inode)->outstanding_extents); | |
| 986 | + goto out; | |
| 987 | + } | |
| 988 | + | |
| 989 | + /* [BTRFS_MAX_EXTENT_SIZE][4K] */ | |
| 990 | + BTRFS_I(inode)->outstanding_extents++; | |
| 991 | + ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, | |
| 992 | + (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095, | |
| 993 | + NULL); | |
| 994 | + if (ret) { | |
| 995 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 996 | + goto out; | |
| 997 | + } | |
| 998 | + if (BTRFS_I(inode)->outstanding_extents != 2) { | |
| 999 | + ret = -EINVAL; | |
| 1000 | + test_msg("Miscount, wanted 2, got %u\n", | |
| 1001 | + BTRFS_I(inode)->outstanding_extents); | |
| 1002 | + goto out; | |
| 1003 | + } | |
| 1004 | + | |
| 1005 | + /* | |
| 1006 | + * [BTRFS_MAX_EXTENT_SIZE+4K][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4K] | |
| 1007 | + * | |
| 1008 | + * I'm artificially adding 2 to outstanding_extents because in the | |
| 1009 | + * buffered IO case we'd add things up as we go, but I don't feel like | |
| 1010 | + * doing that here, this isn't the interesting case we want to test. | |
| 1011 | + */ | |
| 1012 | + BTRFS_I(inode)->outstanding_extents += 2; | |
| 1013 | + ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + 8192, | |
| 1014 | + (BTRFS_MAX_EXTENT_SIZE << 1) + 12287, | |
| 1015 | + NULL); | |
| 1016 | + if (ret) { | |
| 1017 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 1018 | + goto out; | |
| 1019 | + } | |
| 1020 | + if (BTRFS_I(inode)->outstanding_extents != 4) { | |
| 1021 | + ret = -EINVAL; | |
| 1022 | + test_msg("Miscount, wanted 4, got %u\n", | |
| 1023 | + BTRFS_I(inode)->outstanding_extents); | |
| 1024 | + goto out; | |
| 1025 | + } | |
| 1026 | + | |
| 1027 | + /* [BTRFS_MAX_EXTENT_SIZE+4k][4k][BTRFS_MAX_EXTENT_SIZE+4k] */ | |
| 1028 | + BTRFS_I(inode)->outstanding_extents++; | |
| 1029 | + ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096, | |
| 1030 | + BTRFS_MAX_EXTENT_SIZE+8191, NULL); | |
| 1031 | + if (ret) { | |
| 1032 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 1033 | + goto out; | |
| 1034 | + } | |
| 1035 | + if (BTRFS_I(inode)->outstanding_extents != 3) { | |
| 1036 | + ret = -EINVAL; | |
| 1037 | + test_msg("Miscount, wanted 3, got %u\n", | |
| 1038 | + BTRFS_I(inode)->outstanding_extents); | |
| 1039 | + goto out; | |
| 1040 | + } | |
| 1041 | + | |
| 1042 | + /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */ | |
| 1043 | + ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | |
| 1044 | + BTRFS_MAX_EXTENT_SIZE+4096, | |
| 1045 | + BTRFS_MAX_EXTENT_SIZE+8191, | |
| 1046 | + EXTENT_DIRTY | EXTENT_DELALLOC | | |
| 1047 | + EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, | |
| 1048 | + NULL, GFP_NOFS); | |
| 1049 | + if (ret) { | |
| 1050 | + test_msg("clear_extent_bit returned %d\n", ret); | |
| 1051 | + goto out; | |
| 1052 | + } | |
| 1053 | + if (BTRFS_I(inode)->outstanding_extents != 4) { | |
| 1054 | + ret = -EINVAL; | |
| 1055 | + test_msg("Miscount, wanted 4, got %u\n", | |
| 1056 | + BTRFS_I(inode)->outstanding_extents); | |
| 1057 | + goto out; | |
| 1058 | + } | |
| 1059 | + | |
| 1060 | + /* | |
| 1061 | + * Refill the hole again just for good measure, because I thought it | |
| 1062 | + * might fail and I'd rather satisfy my paranoia at this point. | |
| 1063 | + */ | |
| 1064 | + BTRFS_I(inode)->outstanding_extents++; | |
| 1065 | + ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096, | |
| 1066 | + BTRFS_MAX_EXTENT_SIZE+8191, NULL); | |
| 1067 | + if (ret) { | |
| 1068 | + test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | |
| 1069 | + goto out; | |
| 1070 | + } | |
| 1071 | + if (BTRFS_I(inode)->outstanding_extents != 3) { | |
| 1072 | + ret = -EINVAL; | |
| 1073 | + test_msg("Miscount, wanted 3, got %u\n", | |
| 1074 | + BTRFS_I(inode)->outstanding_extents); | |
| 1075 | + goto out; | |
| 1076 | + } | |
| 1077 | + | |
| 1078 | + /* Empty */ | |
| 1079 | + ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, | |
| 1080 | + EXTENT_DIRTY | EXTENT_DELALLOC | | |
| 1081 | + EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, | |
| 1082 | + NULL, GFP_NOFS); | |
| 1083 | + if (ret) { | |
| 1084 | + test_msg("clear_extent_bit returned %d\n", ret); | |
| 1085 | + goto out; | |
| 1086 | + } | |
| 1087 | + if (BTRFS_I(inode)->outstanding_extents) { | |
| 1088 | + ret = -EINVAL; | |
| 1089 | + test_msg("Miscount, wanted 0, got %u\n", | |
| 1090 | + BTRFS_I(inode)->outstanding_extents); | |
| 1091 | + goto out; | |
| 1092 | + } | |
| 1093 | + ret = 0; | |
| 1094 | +out: | |
| 1095 | + if (ret) | |
| 1096 | + clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, | |
| 1097 | + EXTENT_DIRTY | EXTENT_DELALLOC | | |
| 1098 | + EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, | |
| 1099 | + NULL, GFP_NOFS); | |
| 1100 | + iput(inode); | |
| 1101 | + btrfs_free_dummy_root(root); | |
| 1102 | + return ret; | |
| 1103 | +} | |
| 1104 | + | |
| 914 | 1105 | int btrfs_test_inodes(void) |
| 915 | 1106 | { |
| 916 | 1107 | int ret; |
| @@ -924,5 +1115,9 @@ int btrfs_test_inodes(void) · 7 unmodified lines | ||
| 924 | 1115 | if (ret) |
| 925 | 1116 | return ret; |
| 926 | 1117 | test_msg("Running hole first btrfs_get_extent test\n"); |
| 927 | − return test_hole_first(); | |
| 1118 | + ret = test_hole_first(); | |
| 1119 | + if (ret) | |
| 1120 | + return ret; | |
| 1121 | + test_msg("Running outstanding_extents tests\n"); | |
| 1122 | + return test_extent_accounting(); | |
| 928 | 1123 | } |
| @@ -1023,17 +1023,13 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, · 1022 unmodified lines | ||
| 1023 | 1023 | u64 old_root_bytenr; |
| 1024 | 1024 | u64 old_root_used; |
| 1025 | 1025 | struct btrfs_root *tree_root = root->fs_info->tree_root; |
| 1026 | − bool extent_root = (root->objectid == BTRFS_EXTENT_TREE_OBJECTID); | |
| 1027 | 1026 | |
| 1028 | 1027 | old_root_used = btrfs_root_used(&root->root_item); |
| 1029 | − btrfs_write_dirty_block_groups(trans, root); | |
| 1030 | 1028 | |
| 1031 | 1029 | while (1) { |
| 1032 | 1030 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); |
| 1033 | 1031 | if (old_root_bytenr == root->node->start && |
| 1034 | − old_root_used == btrfs_root_used(&root->root_item) && | |
| 1035 | − (!extent_root || | |
| 1036 | − list_empty(&trans->transaction->dirty_bgs))) | |
| 1032 | + old_root_used == btrfs_root_used(&root->root_item)) | |
| 1037 | 1033 | break; |
| 1038 | 1034 | |
| 1039 | 1035 | btrfs_set_root_node(&root->root_item, root->node); |
| @@ -1044,14 +1040,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, · 4 unmodified lines | ||
| 1044 | 1040 | return ret; |
| 1045 | 1041 | |
| 1046 | 1042 | old_root_used = btrfs_root_used(&root->root_item); |
| 1047 | − if (extent_root) { | |
| 1048 | − ret = btrfs_write_dirty_block_groups(trans, root); | |
| 1049 | − if (ret) | |
| 1050 | − return ret; | |
| 1051 | − } | |
| 1052 | − ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | |
| 1053 | − if (ret) | |
| 1054 | − return ret; | |
| 1055 | 1043 | } |
| 1056 | 1044 | |
| 1057 | 1045 | return 0; |
| @@ -1068,6 +1056,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, · 10 unmodified lines | ||
| 1068 | 1056 | struct btrfs_root *root) |
| 1069 | 1057 | { |
| 1070 | 1058 | struct btrfs_fs_info *fs_info = root->fs_info; |
| 1059 | + struct list_head *dirty_bgs = &trans->transaction->dirty_bgs; | |
| 1071 | 1060 | struct list_head *next; |
| 1072 | 1061 | struct extent_buffer *eb; |
| 1073 | 1062 | int ret; |
| @@ -1095,11 +1084,15 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, · 21 unmodified lines | ||
| 1095 | 1084 | if (ret) |
| 1096 | 1085 | return ret; |
| 1097 | 1086 | |
| 1087 | + ret = btrfs_setup_space_cache(trans, root); | |
| 1088 | + if (ret) | |
| 1089 | + return ret; | |
| 1090 | + | |
| 1098 | 1091 | /* run_qgroups might have added some more refs */ |
| 1099 | 1092 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
| 1100 | 1093 | if (ret) |
| 1101 | 1094 | return ret; |
| 1102 | − | |
| 1095 | +again: | |
| 1103 | 1096 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { |
| 1104 | 1097 | next = fs_info->dirty_cowonly_roots.next; |
| 1105 | 1098 | list_del_init(next); |
| @@ -1112,8 +1105,23 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, · 6 unmodified lines | ||
| 1112 | 1105 | ret = update_cowonly_root(trans, root); |
| 1113 | 1106 | if (ret) |
| 1114 | 1107 | return ret; |
| 1108 | + ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | |
| 1109 | + if (ret) | |
| 1110 | + return ret; | |
| 1115 | 1111 | } |
| 1116 | 1112 | |
| 1113 | + while (!list_empty(dirty_bgs)) { | |
| 1114 | + ret = btrfs_write_dirty_block_groups(trans, root); | |
| 1115 | + if (ret) | |
| 1116 | + return ret; | |
| 1117 | + ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | |
| 1118 | + if (ret) | |
| 1119 | + return ret; | |
| 1120 | + } | |
| 1121 | + | |
| 1122 | + if (!list_empty(&fs_info->dirty_cowonly_roots)) | |
| 1123 | + goto again; | |
| 1124 | + | |
| 1117 | 1125 | list_add_tail(&fs_info->extent_root->dirty_list, |
| 1118 | 1126 | &trans->transaction->switch_commits); |
| 1119 | 1127 | btrfs_after_dev_replace_commit(fs_info); |
| @@ -1811,6 +1819,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, · 691 unmodified lines | ||
| 1811 | 1819 | |
| 1812 | 1820 | wait_for_commit(root, cur_trans); |
| 1813 | 1821 | |
| 1822 | + if (unlikely(cur_trans->aborted)) | |
| 1823 | + ret = cur_trans->aborted; | |
| 1824 | + | |
| 1814 | 1825 | btrfs_put_transaction(cur_trans); |
| 1815 | 1826 | |
| 1816 | 1827 | return ret; |
| @@ -890,8 +890,8 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) · 889 unmodified lines | ||
| 890 | 890 | |
| 891 | 891 | newpage = buf->page; |
| 892 | 892 | |
| 893 | − if (WARN_ON(!PageUptodate(newpage))) | |
| 894 | − return -EIO; | |
| 893 | + if (!PageUptodate(newpage)) | |
| 894 | + SetPageUptodate(newpage); | |
| 895 | 895 | |
| 896 | 896 | ClearPageMappedToDisk(newpage); |
| 897 | 897 | |
| @@ -1353,6 +1353,17 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, · 455 unmodified lines | ||
| 1353 | 1353 | return err; |
| 1354 | 1354 | } |
| 1355 | 1355 | |
| 1356 | +static int fuse_dev_open(struct inode *inode, struct file *file) | |
| 1357 | +{ | |
| 1358 | + /* | |
| 1359 | + * The fuse device's file's private_data is used to hold | |
| 1360 | + * the fuse_conn(ection) when it is mounted, and is used to | |
| 1361 | + * keep track of whether the file has been mounted already. | |
| 1362 | + */ | |
| 1363 | + file->private_data = NULL; | |
| 1364 | + return 0; | |
| 1365 | +} | |
| 1366 | + | |
| 1356 | 1367 | static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, |
| 1357 | 1368 | unsigned long nr_segs, loff_t pos) |
| 1358 | 1369 | { |
| @@ -1797,6 +1808,9 @@ copy_finish: · 438 unmodified lines | ||
| 1797 | 1808 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, |
| 1798 | 1809 | unsigned int size, struct fuse_copy_state *cs) |
| 1799 | 1810 | { |
| 1811 | + /* Don't try to move pages (yet) */ | |
| 1812 | + cs->move_pages = 0; | |
| 1813 | + | |
| 1800 | 1814 | switch (code) { |
| 1801 | 1815 | case FUSE_NOTIFY_POLL: |
| 1802 | 1816 | return fuse_notify_poll(fc, size, cs); |
| @@ -2217,6 +2231,7 @@ static int fuse_dev_fasync(int fd, struct file *file, int on) · 414 unmodified lines | ||
| 2217 | 2231 | |
| 2218 | 2232 | const struct file_operations fuse_dev_operations = { |
| 2219 | 2233 | .owner = THIS_MODULE, |
| 2234 | + .open = fuse_dev_open, | |
| 2220 | 2235 | .llseek = no_llseek, |
| 2221 | 2236 | .read = do_sync_read, |
| 2222 | 2237 | .aio_read = fuse_dev_read, |
| @@ -207,6 +207,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, · 206 unmodified lines | ||
| 207 | 207 | goto out_free; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | + of->event = atomic_read(&of->kn->attr.open->event); | |
| 210 | 211 | ops = kernfs_ops(of->kn); |
| 211 | 212 | if (ops->read) |
| 212 | 213 | len = ops->read(of, buf, len, *ppos); |
| @@ -1728,7 +1728,7 @@ static int generic_delete_lease(struct file *filp, void *owner) · 1727 unmodified lines | ||
| 1728 | 1728 | break; |
| 1729 | 1729 | } |
| 1730 | 1730 | } |
| 1731 | − trace_generic_delete_lease(inode, fl); | |
| 1731 | + trace_generic_delete_lease(inode, victim); | |
| 1732 | 1732 | if (victim) |
| 1733 | 1733 | error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose); |
| 1734 | 1734 | spin_unlock(&ctx->flc_lock); |
| @@ -587,8 +587,6 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls) · 586 unmodified lines | ||
| 587 | 587 | |
| 588 | 588 | rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str)); |
| 589 | 589 | |
| 590 | − nfsd4_cb_layout_fail(ls); | |
| 591 | − | |
| 592 | 590 | printk(KERN_WARNING |
| 593 | 591 | "nfsd: client %s failed to respond to layout recall. " |
| 594 | 592 | " Fencing..\n", addr_str); |
| @@ -1907,6 +1907,7 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, · 1906 unmodified lines | ||
| 1907 | 1907 | struct the_nilfs *nilfs) |
| 1908 | 1908 | { |
| 1909 | 1909 | struct nilfs_inode_info *ii, *n; |
| 1910 | + int during_mount = !(sci->sc_super->s_flags & MS_ACTIVE); | |
| 1910 | 1911 | int defer_iput = false; |
| 1911 | 1912 | |
| 1912 | 1913 | spin_lock(&nilfs->ns_inode_lock); |
| @@ -1919,10 +1920,10 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, · 6 unmodified lines | ||
| 1919 | 1920 | brelse(ii->i_bh); |
| 1920 | 1921 | ii->i_bh = NULL; |
| 1921 | 1922 | list_del_init(&ii->i_dirty); |
| 1922 | − if (!ii->vfs_inode.i_nlink) { | |
| 1923 | + if (!ii->vfs_inode.i_nlink || during_mount) { | |
| 1923 | 1924 | /* |
| 1924 | − * Defer calling iput() to avoid a deadlock | |
| 1925 | − * over I_SYNC flag for inodes with i_nlink == 0 | |
| 1925 | + * Defer calling iput() to avoid deadlocks if | |
| 1926 | + * i_nlink == 0 or mount is not yet finished. | |
| 1926 | 1927 | */ |
| 1927 | 1928 | list_add_tail(&ii->i_dirty, &sci->sc_iput_queue); |
| 1928 | 1929 | defer_iput = true; |
| @@ -143,7 +143,8 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark, · 142 unmodified lines | ||
| 143 | 143 | !(marks_mask & FS_ISDIR & ~marks_ignored_mask)) |
| 144 | 144 | return false; |
| 145 | 145 | |
| 146 | − if (event_mask & marks_mask & ~marks_ignored_mask) | |
| 146 | + if (event_mask & FAN_ALL_OUTGOING_EVENTS & marks_mask & | |
| 147 | + ~marks_ignored_mask) | |
| 147 | 148 | return true; |
| 148 | 149 | |
| 149 | 150 | return false; |
| @@ -502,7 +502,7 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb) · 501 unmodified lines | ||
| 502 | 502 | |
| 503 | 503 | static inline int ocfs2_supports_append_dio(struct ocfs2_super *osb) |
| 504 | 504 | { |
| 505 | − if (osb->s_feature_ro_compat & OCFS2_FEATURE_RO_COMPAT_APPEND_DIO) | |
| 505 | + if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_APPEND_DIO) | |
| 506 | 506 | return 1; |
| 507 | 507 | return 0; |
| 508 | 508 | } |
| @@ -102,11 +102,11 @@ · 101 unmodified lines | ||
| 102 | 102 | | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \ |
| 103 | 103 | | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \ |
| 104 | 104 | | OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG \ |
| 105 | − | OCFS2_FEATURE_INCOMPAT_CLUSTERINFO) | |
| 105 | + | OCFS2_FEATURE_INCOMPAT_CLUSTERINFO \ | |
| 106 | + | OCFS2_FEATURE_INCOMPAT_APPEND_DIO) | |
| 106 | 107 | #define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \ |
| 107 | 108 | | OCFS2_FEATURE_RO_COMPAT_USRQUOTA \ |
| 108 | − | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA \ | |
| 109 | − | OCFS2_FEATURE_RO_COMPAT_APPEND_DIO) | |
| 109 | + | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA) | |
| 110 | 110 | |
| 111 | 111 | /* |
| 112 | 112 | * Heartbeat-only devices are missing journals and other files. The |
| @@ -178,6 +178,11 @@ · 65 unmodified lines | ||
| 178 | 178 | */ |
| 179 | 179 | #define OCFS2_FEATURE_INCOMPAT_CLUSTERINFO 0x4000 |
| 180 | 180 | |
| 181 | +/* | |
| 182 | + * Append Direct IO support | |
| 183 | + */ | |
| 184 | +#define OCFS2_FEATURE_INCOMPAT_APPEND_DIO 0x8000 | |
| 185 | + | |
| 181 | 186 | /* |
| 182 | 187 | * backup superblock flag is used to indicate that this volume |
| 183 | 188 | * has backup superblocks. |
| @@ -200,10 +205,6 @@ · 16 unmodified lines | ||
| 200 | 205 | #define OCFS2_FEATURE_RO_COMPAT_USRQUOTA 0x0002 |
| 201 | 206 | #define OCFS2_FEATURE_RO_COMPAT_GRPQUOTA 0x0004 |
| 202 | 207 | |
| 203 | −/* | |
| 204 | − * Append Direct IO support | |
| 205 | − */ | |
| 206 | −#define OCFS2_FEATURE_RO_COMPAT_APPEND_DIO 0x0008 | |
| 207 | 208 | |
| 208 | 209 | /* The byte offset of the first backup block will be 1G. |
| 209 | 210 | * The following will be 4G, 16G, 64G, 256G and 1T. |
| @@ -529,8 +529,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data) · 528 unmodified lines | ||
| 529 | 529 | { |
| 530 | 530 | struct ovl_fs *ufs = sb->s_fs_info; |
| 531 | 531 | |
| 532 | − if (!(*flags & MS_RDONLY) && | |
| 533 | − (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY))) | |
| 532 | + if (!(*flags & MS_RDONLY) && !ufs->upper_mnt) | |
| 534 | 533 | return -EROFS; |
| 535 | 534 | |
| 536 | 535 | return 0; |
| @@ -615,9 +614,19 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config) · 78 unmodified lines | ||
| 615 | 614 | break; |
| 616 | 615 | |
| 617 | 616 | default: |
| 617 | + pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); | |
| 618 | 618 | return -EINVAL; |
| 619 | 619 | } |
| 620 | 620 | } |
| 621 | + | |
| 622 | + /* Workdir is useless in non-upper mount */ | |
| 623 | + if (!config->upperdir && config->workdir) { | |
| 624 | + pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n", | |
| 625 | + config->workdir); | |
| 626 | + kfree(config->workdir); | |
| 627 | + config->workdir = NULL; | |
| 628 | + } | |
| 629 | + | |
| 621 | 630 | return 0; |
| 622 | 631 | } |
| 623 | 632 | |
| @@ -837,7 +846,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 213 unmodified lines | ||
| 837 | 846 | |
| 838 | 847 | sb->s_stack_depth = 0; |
| 839 | 848 | if (ufs->config.upperdir) { |
| 840 | − /* FIXME: workdir is not needed for a R/O mount */ | |
| 841 | 849 | if (!ufs->config.workdir) { |
| 842 | 850 | pr_err("overlayfs: missing 'workdir'\n"); |
| 843 | 851 | goto out_free_config; |
| @@ -847,6 +855,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 3 unmodified lines | ||
| 847 | 855 | if (err) |
| 848 | 856 | goto out_free_config; |
| 849 | 857 | |
| 858 | + /* Upper fs should not be r/o */ | |
| 859 | + if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) { | |
| 860 | + pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); | |
| 861 | + err = -EINVAL; | |
| 862 | + goto out_put_upperpath; | |
| 863 | + } | |
| 864 | + | |
| 850 | 865 | err = ovl_mount_dir(ufs->config.workdir, &workpath); |
| 851 | 866 | if (err) |
| 852 | 867 | goto out_put_upperpath; |
| @@ -869,8 +884,14 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 16 unmodified lines | ||
| 869 | 884 | |
| 870 | 885 | err = -EINVAL; |
| 871 | 886 | stacklen = ovl_split_lowerdirs(lowertmp); |
| 872 | − if (stacklen > OVL_MAX_STACK) | |
| 887 | + if (stacklen > OVL_MAX_STACK) { | |
| 888 | + pr_err("overlayfs: too many lower directries, limit is %d\n", | |
| 889 | + OVL_MAX_STACK); | |
| 873 | 890 | goto out_free_lowertmp; |
| 891 | + } else if (!ufs->config.upperdir && stacklen == 1) { | |
| 892 | + pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n"); | |
| 893 | + goto out_free_lowertmp; | |
| 894 | + } | |
| 874 | 895 | |
| 875 | 896 | stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); |
| 876 | 897 | if (!stack) |
| @@ -932,8 +953,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) · 55 unmodified lines | ||
| 932 | 953 | ufs->numlower++; |
| 933 | 954 | } |
| 934 | 955 | |
| 935 | − /* If the upper fs is r/o or nonexistent, we mark overlayfs r/o too */ | |
| 936 | − if (!ufs->upper_mnt || (ufs->upper_mnt->mnt_sb->s_flags & MS_RDONLY)) | |
| 956 | + /* If the upper fs is nonexistent, we mark overlayfs r/o too */ | |
| 957 | + if (!ufs->upper_mnt) | |
| 937 | 958 | sb->s_flags |= MS_RDONLY; |
| 938 | 959 | |
| 939 | 960 | sb->s_d_op = &ovl_dentry_operations; |
| @@ -1325,6 +1325,9 @@ out: · 1324 unmodified lines | ||
| 1325 | 1325 | |
| 1326 | 1326 | static int pagemap_open(struct inode *inode, struct file *file) |
| 1327 | 1327 | { |
| 1328 | + /* do not disclose physical addresses: attack vector */ | |
| 1329 | + if (!capable(CAP_SYS_ADMIN)) | |
| 1330 | + return -EPERM; | |
| 1328 | 1331 | pr_warn_once("Bits 55-60 of /proc/PID/pagemap entries are about " |
| 1329 | 1332 | "to stop being page-shift some time soon. See the " |
| 1330 | 1333 | "linux/Documentation/vm/pagemap.txt for details.\n"); |
| @@ -13,7 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #define PULL_DISABLE (1 << 3) |
| 15 | 15 | #define INPUT_EN (1 << 5) |
| 16 | −#define SLEWCTRL_FAST (1 << 6) | |
| 16 | +#define SLEWCTRL_SLOW (1 << 6) | |
| 17 | +#define SLEWCTRL_FAST 0 | |
| 17 | 18 | |
| 18 | 19 | /* update macro depending on INPUT_EN and PULL_ENA */ |
| 19 | 20 | #undef PIN_OUTPUT |
| @@ -18,7 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | #define PULL_DISABLE (1 << 16) |
| 19 | 19 | #define PULL_UP (1 << 17) |
| 20 | 20 | #define INPUT_EN (1 << 18) |
| 21 | −#define SLEWCTRL_FAST (1 << 19) | |
| 21 | +#define SLEWCTRL_SLOW (1 << 19) | |
| 22 | +#define SLEWCTRL_FAST 0 | |
| 22 | 23 | #define DS0_PULL_UP_DOWN_EN (1 << 27) |
| 23 | 24 | |
| 24 | 25 | #define PIN_OUTPUT (PULL_DISABLE) |
| @@ -114,6 +114,7 @@ struct vgic_ops { · 113 unmodified lines | ||
| 114 | 114 | void (*sync_lr_elrsr)(struct kvm_vcpu *, int, struct vgic_lr); |
| 115 | 115 | u64 (*get_elrsr)(const struct kvm_vcpu *vcpu); |
| 116 | 116 | u64 (*get_eisr)(const struct kvm_vcpu *vcpu); |
| 117 | + void (*clear_eisr)(struct kvm_vcpu *vcpu); | |
| 117 | 118 | u32 (*get_interrupt_status)(const struct kvm_vcpu *vcpu); |
| 118 | 119 | void (*enable_underflow)(struct kvm_vcpu *vcpu); |
| 119 | 120 | void (*disable_underflow)(struct kvm_vcpu *vcpu); |
| @@ -125,6 +125,19 @@ int clk_set_phase(struct clk *clk, int degrees); · 124 unmodified lines | ||
| 125 | 125 | */ |
| 126 | 126 | int clk_get_phase(struct clk *clk); |
| 127 | 127 | |
| 128 | +/** | |
| 129 | + * clk_is_match - check if two clk's point to the same hardware clock | |
| 130 | + * @p: clk compared against q | |
| 131 | + * @q: clk compared against p | |
| 132 | + * | |
| 133 | + * Returns true if the two struct clk pointers both point to the same hardware | |
| 134 | + * clock node. Put differently, returns true if struct clk *p and struct clk *q | |
| 135 | + * share the same struct clk_core object. | |
| 136 | + * | |
| 137 | + * Returns false otherwise. Note that two NULL clks are treated as matching. | |
| 138 | + */ | |
| 139 | +bool clk_is_match(const struct clk *p, const struct clk *q); | |
| 140 | + | |
| 128 | 141 | #else |
| 129 | 142 | |
| 130 | 143 | static inline long clk_get_accuracy(struct clk *clk) |
| @@ -142,6 +155,11 @@ static inline long clk_get_phase(struct clk *clk) · 11 unmodified lines | ||
| 142 | 155 | return -ENOTSUPP; |
| 143 | 156 | } |
| 144 | 157 | |
| 158 | +static inline bool clk_is_match(const struct clk *p, const struct clk *q) | |
| 159 | +{ | |
| 160 | + return p == q; | |
| 161 | +} | |
| 162 | + | |
| 145 | 163 | #endif |
| 146 | 164 | |
| 147 | 165 | /** |
| @@ -375,6 +375,7 @@ int dm_create(int minor, struct mapped_device **md); · 374 unmodified lines | ||
| 375 | 375 | */ |
| 376 | 376 | struct mapped_device *dm_get_md(dev_t dev); |
| 377 | 377 | void dm_get(struct mapped_device *md); |
| 378 | +int dm_hold(struct mapped_device *md); | |
| 378 | 379 | void dm_put(struct mapped_device *md); |
| 379 | 380 | |
| 380 | 381 | /* |
| @@ -166,6 +166,11 @@ · 165 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | #define GITS_TRANSLATER 0x10040 |
| 168 | 168 | |
| 169 | +#define GITS_CTLR_ENABLE (1U << 0) | |
| 170 | +#define GITS_CTLR_QUIESCENT (1U << 31) | |
| 171 | + | |
| 172 | +#define GITS_TYPER_DEVBITS_SHIFT 13 | |
| 173 | +#define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) | |
| 169 | 174 | #define GITS_TYPER_PTA (1UL << 19) |
| 170 | 175 | |
| 171 | 176 | #define GITS_CBASER_VALID (1UL << 63) |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | struct kmem_cache; |
| 7 | 7 | struct page; |
| 8 | +struct vm_struct; | |
| 8 | 9 | |
| 9 | 10 | #ifdef CONFIG_KASAN |
| 10 | 11 | |
| @@ -49,15 +50,11 @@ void kasan_krealloc(const void *object, size_t new_size); · 38 unmodified lines | ||
| 49 | 50 | void kasan_slab_alloc(struct kmem_cache *s, void *object); |
| 50 | 51 | void kasan_slab_free(struct kmem_cache *s, void *object); |
| 51 | 52 | |
| 52 | −#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) | |
| 53 | − | |
| 54 | 53 | int kasan_module_alloc(void *addr, size_t size); |
| 55 | −void kasan_module_free(void *addr); | |
| 54 | +void kasan_free_shadow(const struct vm_struct *vm); | |
| 56 | 55 | |
| 57 | 56 | #else /* CONFIG_KASAN */ |
| 58 | 57 | |
| 59 | −#define MODULE_ALIGN 1 | |
| 60 | − | |
| 61 | 58 | static inline void kasan_unpoison_shadow(const void *address, size_t size) {} |
| 62 | 59 | |
| 63 | 60 | static inline void kasan_enable_current(void) {} |
| @@ -82,7 +79,7 @@ static inline void kasan_slab_alloc(struct kmem_cache *s, void *object) {} · 18 unmodified lines | ||
| 82 | 79 | static inline void kasan_slab_free(struct kmem_cache *s, void *object) {} |
| 83 | 80 | |
| 84 | 81 | static inline int kasan_module_alloc(void *addr, size_t size) { return 0; } |
| 85 | −static inline void kasan_module_free(void *addr) {} | |
| 82 | +static inline void kasan_free_shadow(const struct vm_struct *vm) {} | |
| 86 | 83 | |
| 87 | 84 | #endif /* CONFIG_KASAN */ |
| 88 | 85 | |
| @@ -344,6 +344,10 @@ struct module { · 343 unmodified lines | ||
| 344 | 344 | unsigned long *ftrace_callsites; |
| 345 | 345 | #endif |
| 346 | 346 | |
| 347 | +#ifdef CONFIG_LIVEPATCH | |
| 348 | + bool klp_alive; | |
| 349 | +#endif | |
| 350 | + | |
| 347 | 351 | #ifdef CONFIG_MODULE_UNLOAD |
| 348 | 352 | /* What modules depend on me? */ |
| 349 | 353 | struct list_head source_list; |
| @@ -84,4 +84,12 @@ void module_arch_cleanup(struct module *mod); · 83 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | /* Any cleanup before freeing mod->module_init */ |
| 86 | 86 | void module_arch_freeing_init(struct module *mod); |
| 87 | + | |
| 88 | +#ifdef CONFIG_KASAN | |
| 89 | +#include <linux/kasan.h> | |
| 90 | +#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) | |
| 91 | +#else | |
| 92 | +#define MODULE_ALIGN PAGE_SIZE | |
| 93 | +#endif | |
| 94 | + | |
| 87 | 95 | #endif |
| @@ -965,9 +965,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, · 964 unmodified lines | ||
| 965 | 965 | * Used to add FDB entries to dump requests. Implementers should add |
| 966 | 966 | * entries to skb and update idx with the number of entries. |
| 967 | 967 | * |
| 968 | − * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) | |
| 968 | + * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh, | |
| 969 | + * u16 flags) | |
| 969 | 970 | * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, |
| 970 | 971 | * struct net_device *dev, u32 filter_mask) |
| 972 | + * int (*ndo_bridge_dellink)(struct net_device *dev, struct nlmsghdr *nlh, | |
| 973 | + * u16 flags); | |
| 971 | 974 | * |
| 972 | 975 | * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); |
| 973 | 976 | * Called to change device carrier. Soft-devices (like dummy, team, etc) |
| @@ -84,7 +84,7 @@ static inline int of_platform_populate(struct device_node *root, · 83 unmodified lines | ||
| 84 | 84 | static inline void of_platform_depopulate(struct device *parent) { } |
| 85 | 85 | #endif |
| 86 | 86 | |
| 87 | −#ifdef CONFIG_OF_DYNAMIC | |
| 87 | +#if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS) | |
| 88 | 88 | extern void of_platform_register_reconfig_notifier(void); |
| 89 | 89 | #else |
| 90 | 90 | static inline void of_platform_register_reconfig_notifier(void) { } |
| @@ -82,7 +82,7 @@ static inline int pinctrl_gpio_direction_output(unsigned gpio) · 81 unmodified lines | ||
| 82 | 82 | |
| 83 | 83 | static inline struct pinctrl * __must_check pinctrl_get(struct device *dev) |
| 84 | 84 | { |
| 85 | − return ERR_PTR(-ENOSYS); | |
| 85 | + return NULL; | |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | static inline void pinctrl_put(struct pinctrl *p) |
| @@ -93,7 +93,7 @@ static inline struct pinctrl_state * __must_check pinctrl_lookup_state( · 4 unmodified lines | ||
| 93 | 93 | struct pinctrl *p, |
| 94 | 94 | const char *name) |
| 95 | 95 | { |
| 96 | − return ERR_PTR(-ENOSYS); | |
| 96 | + return NULL; | |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | static inline int pinctrl_select_state(struct pinctrl *p, |
| @@ -104,7 +104,7 @@ static inline int pinctrl_select_state(struct pinctrl *p, · 4 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | static inline struct pinctrl * __must_check devm_pinctrl_get(struct device *dev) |
| 106 | 106 | { |
| 107 | − return ERR_PTR(-ENOSYS); | |
| 107 | + return NULL; | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | static inline void devm_pinctrl_put(struct pinctrl *p) |
| @@ -948,6 +948,13 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) · 947 unmodified lines | ||
| 948 | 948 | to->l4_hash = from->l4_hash; |
| 949 | 949 | }; |
| 950 | 950 | |
| 951 | +static inline void skb_sender_cpu_clear(struct sk_buff *skb) | |
| 952 | +{ | |
| 953 | +#ifdef CONFIG_XPS | |
| 954 | + skb->sender_cpu = 0; | |
| 955 | +#endif | |
| 956 | +} | |
| 957 | + | |
| 951 | 958 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
| 952 | 959 | static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) |
| 953 | 960 | { |
| @@ -649,7 +649,7 @@ struct spi_transfer { · 648 unmodified lines | ||
| 649 | 649 | * sequence completes. On some systems, many such sequences can execute as |
| 650 | 650 | * as single programmed DMA transfer. On all systems, these messages are |
| 651 | 651 | * queued, and might complete after transactions to other devices. Messages |
| 652 | − * sent to a given spi_device are alway executed in FIFO order. | |
| 652 | + * sent to a given spi_device are always executed in FIFO order. | |
| 653 | 653 | * |
| 654 | 654 | * The code that submits an spi_message (and its spi_transfers) |
| 655 | 655 | * to the lower layers is responsible for managing its memory. |
| @@ -98,6 +98,8 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, · 97 unmodified lines | ||
| 98 | 98 | size_t maxsize, size_t *start); |
| 99 | 99 | int iov_iter_npages(const struct iov_iter *i, int maxpages); |
| 100 | 100 | |
| 101 | +const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags); | |
| 102 | + | |
| 101 | 103 | static inline size_t iov_iter_count(struct iov_iter *i) |
| 102 | 104 | { |
| 103 | 105 | return i->count; |
| @@ -17,6 +17,7 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ · 16 unmodified lines | ||
| 17 | 17 | #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ |
| 18 | 18 | #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ |
| 19 | 19 | #define VM_NO_GUARD 0x00000040 /* don't add guard page */ |
| 20 | +#define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ | |
| 20 | 21 | /* bits [20..32] reserved for arch specific ioremap internals */ |
| 21 | 22 | |
| 22 | 23 | /* |
| @@ -70,7 +70,8 @@ enum { · 69 unmodified lines | ||
| 70 | 70 | /* data contains off-queue information when !WORK_STRUCT_PWQ */ |
| 71 | 71 | WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, |
| 72 | 72 | |
| 73 | − WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE), | |
| 73 | + __WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, | |
| 74 | + WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING), | |
| 74 | 75 | |
| 75 | 76 | /* |
| 76 | 77 | * When a work item is off queue, its high bits point to the last |
| @@ -481,6 +481,7 @@ void dst_init(void); · 480 unmodified lines | ||
| 481 | 481 | enum { |
| 482 | 482 | XFRM_LOOKUP_ICMP = 1 << 0, |
| 483 | 483 | XFRM_LOOKUP_QUEUE = 1 << 1, |
| 484 | + XFRM_LOOKUP_KEEP_DST_REF = 1 << 2, | |
| 484 | 485 | }; |
| 485 | 486 | |
| 486 | 487 | struct flowi; |
| @@ -119,6 +119,22 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg, · 118 unmodified lines | ||
| 119 | 119 | const struct nft_data *data, |
| 120 | 120 | enum nft_data_types type); |
| 121 | 121 | |
| 122 | + | |
| 123 | +/** | |
| 124 | + * struct nft_userdata - user defined data associated with an object | |
| 125 | + * | |
| 126 | + * @len: length of the data | |
| 127 | + * @data: content | |
| 128 | + * | |
| 129 | + * The presence of user data is indicated in an object specific fashion, | |
| 130 | + * so a length of zero can't occur and the value "len" indicates data | |
| 131 | + * of length len + 1. | |
| 132 | + */ | |
| 133 | +struct nft_userdata { | |
| 134 | + u8 len; | |
| 135 | + unsigned char data[0]; | |
| 136 | +}; | |
| 137 | + | |
| 122 | 138 | /** |
| 123 | 139 | * struct nft_set_elem - generic representation of set elements |
| 124 | 140 | * |
| @@ -380,7 +396,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) · 255 unmodified lines | ||
| 380 | 396 | * @handle: rule handle |
| 381 | 397 | * @genmask: generation mask |
| 382 | 398 | * @dlen: length of expression data |
| 383 | − * @ulen: length of user data (used for comments) | |
| 399 | + * @udata: user data is appended to the rule | |
| 384 | 400 | * @data: expression data |
| 385 | 401 | */ |
| 386 | 402 | struct nft_rule { |
| @@ -388,7 +404,7 @@ struct nft_rule { · 1 unmodified line | ||
| 388 | 404 | u64 handle:42, |
| 389 | 405 | genmask:2, |
| 390 | 406 | dlen:12, |
| 391 | − ulen:8; | |
| 407 | + udata:1; | |
| 392 | 408 | unsigned char data[] |
| 393 | 409 | __attribute__((aligned(__alignof__(struct nft_expr)))); |
| 394 | 410 | }; |
| @@ -476,7 +492,7 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule) · 81 unmodified lines | ||
| 476 | 492 | return (struct nft_expr *)&rule->data[rule->dlen]; |
| 477 | 493 | } |
| 478 | 494 | |
| 479 | −static inline void *nft_userdata(const struct nft_rule *rule) | |
| 495 | +static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule) | |
| 480 | 496 | { |
| 481 | 497 | return (void *)&rule->data[rule->dlen]; |
| 482 | 498 | } |
| @@ -91,6 +91,7 @@ struct vxlanhdr { · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | #define VXLAN_N_VID (1u << 24) |
| 93 | 93 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) |
| 94 | +#define VXLAN_VNI_MASK (VXLAN_VID_MASK << 8) | |
| 94 | 95 | #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr)) |
| 95 | 96 | |
| 96 | 97 | struct vxlan_metadata { |
| @@ -92,7 +92,7 @@ · 91 unmodified lines | ||
| 92 | 92 | #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ |
| 93 | 93 | |
| 94 | 94 | #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ |
| 95 | −#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ | |
| 95 | +#define AT91_DDRSDRC_MD (7 << 0) /* Memory Device Type */ | |
| 96 | 96 | #define AT91_DDRSDRC_MD_SDR 0 |
| 97 | 97 | #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 |
| 98 | 98 | #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 |
| @@ -111,6 +111,7 @@ void array_free(void *array, int n); · 110 unmodified lines | ||
| 111 | 111 | void target_core_setup_sub_cits(struct se_subsystem_api *); |
| 112 | 112 | |
| 113 | 113 | /* attribute helpers from target_core_device.c for backend drivers */ |
| 114 | +bool se_dev_check_wce(struct se_device *); | |
| 114 | 115 | int se_dev_set_max_unmap_lba_count(struct se_device *, u32); |
| 115 | 116 | int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32); |
| 116 | 117 | int se_dev_set_unmap_granularity(struct se_device *, u32); |
| @@ -60,7 +60,7 @@ struct virtio_blk_config { · 59 unmodified lines | ||
| 60 | 60 | __u32 size_max; |
| 61 | 61 | /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ |
| 62 | 62 | __u32 seg_max; |
| 63 | − /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ | |
| 63 | + /* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */ | |
| 64 | 64 | struct virtio_blk_geometry { |
| 65 | 65 | __u16 cylinders; |
| 66 | 66 | __u8 heads; |
| @@ -119,7 +119,11 @@ struct virtio_blk_config { · 52 unmodified lines | ||
| 119 | 119 | #define VIRTIO_BLK_T_BARRIER 0x80000000 |
| 120 | 120 | #endif /* !VIRTIO_BLK_NO_LEGACY */ |
| 121 | 121 | |
| 122 | −/* This is the first element of the read scatter-gather list. */ | |
| 122 | +/* | |
| 123 | + * This comes first in the read scatter-gather list. | |
| 124 | + * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, | |
| 125 | + * this is the first element of the read scatter-gather list. | |
| 126 | + */ | |
| 123 | 127 | struct virtio_blk_outhdr { |
| 124 | 128 | /* VIRTIO_BLK_T* */ |
| 125 | 129 | __virtio32 type; |
| @@ -29,8 +29,16 @@ · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | #include <linux/virtio_types.h> |
| 31 | 31 | |
| 32 | −#define VIRTIO_SCSI_CDB_SIZE 32 | |
| 33 | −#define VIRTIO_SCSI_SENSE_SIZE 96 | |
| 32 | +/* Default values of the CDB and sense data size configuration fields */ | |
| 33 | +#define VIRTIO_SCSI_CDB_DEFAULT_SIZE 32 | |
| 34 | +#define VIRTIO_SCSI_SENSE_DEFAULT_SIZE 96 | |
| 35 | + | |
| 36 | +#ifndef VIRTIO_SCSI_CDB_SIZE | |
| 37 | +#define VIRTIO_SCSI_CDB_SIZE VIRTIO_SCSI_CDB_DEFAULT_SIZE | |
| 38 | +#endif | |
| 39 | +#ifndef VIRTIO_SCSI_SENSE_SIZE | |
| 40 | +#define VIRTIO_SCSI_SENSE_SIZE VIRTIO_SCSI_SENSE_DEFAULT_SIZE | |
| 41 | +#endif | |
| 34 | 42 | |
| 35 | 43 | /* SCSI command request, followed by data-out */ |
| 36 | 44 | struct virtio_scsi_cmd_req { |
| @@ -689,6 +689,7 @@ struct omapdss_dsi_ops { · 688 unmodified lines | ||
| 689 | 689 | }; |
| 690 | 690 | |
| 691 | 691 | struct omap_dss_device { |
| 692 | + struct kobject kobj; | |
| 692 | 693 | struct device *dev; |
| 693 | 694 | |
| 694 | 695 | struct module *owner; |
| @@ -114,9 +114,9 @@ int __must_check __xenbus_register_backend(struct xenbus_driver *drv, · 113 unmodified lines | ||
| 114 | 114 | const char *mod_name); |
| 115 | 115 | |
| 116 | 116 | #define xenbus_register_frontend(drv) \ |
| 117 | − __xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME); | |
| 117 | + __xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME) | |
| 118 | 118 | #define xenbus_register_backend(drv) \ |
| 119 | − __xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME); | |
| 119 | + __xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME) | |
| 120 | 120 | |
| 121 | 121 | void xenbus_unregister_driver(struct xenbus_driver *drv); |
| 122 | 122 | |
| @@ -548,9 +548,6 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr, · 547 unmodified lines | ||
| 548 | 548 | |
| 549 | 549 | rcu_read_lock(); |
| 550 | 550 | cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { |
| 551 | − if (cp == root_cs) | |
| 552 | − continue; | |
| 553 | − | |
| 554 | 551 | /* skip the whole subtree if @cp doesn't have any CPU */ |
| 555 | 552 | if (cpumask_empty(cp->cpus_allowed)) { |
| 556 | 553 | pos_css = css_rightmost_descendant(pos_css); |
| @@ -873,7 +870,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) · 316 unmodified lines | ||
| 873 | 870 | * If it becomes empty, inherit the effective mask of the |
| 874 | 871 | * parent, which is guaranteed to have some CPUs. |
| 875 | 872 | */ |
| 876 | − if (cpumask_empty(new_cpus)) | |
| 873 | + if (cgroup_on_dfl(cp->css.cgroup) && cpumask_empty(new_cpus)) | |
| 877 | 874 | cpumask_copy(new_cpus, parent->effective_cpus); |
| 878 | 875 | |
| 879 | 876 | /* Skip the whole subtree if the cpumask remains the same. */ |
| @@ -1129,7 +1126,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) · 249 unmodified lines | ||
| 1129 | 1126 | * If it becomes empty, inherit the effective mask of the |
| 1130 | 1127 | * parent, which is guaranteed to have some MEMs. |
| 1131 | 1128 | */ |
| 1132 | − if (nodes_empty(*new_mems)) | |
| 1129 | + if (cgroup_on_dfl(cp->css.cgroup) && nodes_empty(*new_mems)) | |
| 1133 | 1130 | *new_mems = parent->effective_mems; |
| 1134 | 1131 | |
| 1135 | 1132 | /* Skip the whole subtree if the nodemask remains the same. */ |
| @@ -1979,7 +1976,9 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) · 843 unmodified lines | ||
| 1979 | 1976 | |
| 1980 | 1977 | spin_lock_irq(&callback_lock); |
| 1981 | 1978 | cs->mems_allowed = parent->mems_allowed; |
| 1979 | + cs->effective_mems = parent->mems_allowed; | |
| 1982 | 1980 | cpumask_copy(cs->cpus_allowed, parent->cpus_allowed); |
| 1981 | + cpumask_copy(cs->effective_cpus, parent->cpus_allowed); | |
| 1983 | 1982 | spin_unlock_irq(&callback_lock); |
| 1984 | 1983 | out_unlock: |
| 1985 | 1984 | mutex_unlock(&cpuset_mutex); |
| @@ -3591,7 +3591,7 @@ static void put_event(struct perf_event *event) · 3590 unmodified lines | ||
| 3591 | 3591 | ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING); |
| 3592 | 3592 | WARN_ON_ONCE(ctx->parent_ctx); |
| 3593 | 3593 | perf_remove_from_context(event, true); |
| 3594 | − mutex_unlock(&ctx->mutex); | |
| 3594 | + perf_event_ctx_unlock(event, ctx); | |
| 3595 | 3595 | |
| 3596 | 3596 | _free_event(event); |
| 3597 | 3597 | } |
| @@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj) · 88 unmodified lines | ||
| 89 | 89 | /* sets obj->mod if object is not vmlinux and module is found */ |
| 90 | 90 | static void klp_find_object_module(struct klp_object *obj) |
| 91 | 91 | { |
| 92 | + struct module *mod; | |
| 93 | + | |
| 92 | 94 | if (!klp_is_module(obj)) |
| 93 | 95 | return; |
| 94 | 96 | |
| 95 | 97 | mutex_lock(&module_mutex); |
| 96 | 98 | /* |
| 97 | − * We don't need to take a reference on the module here because we have | |
| 98 | − * the klp_mutex, which is also taken by the module notifier. This | |
| 99 | − * prevents any module from unloading until we release the klp_mutex. | |
| 99 | + * We do not want to block removal of patched modules and therefore | |
| 100 | + * we do not take a reference here. The patches are removed by | |
| 101 | + * a going module handler instead. | |
| 102 | + */ | |
| 103 | + mod = find_module(obj->name); | |
| 104 | + /* | |
| 105 | + * Do not mess work of the module coming and going notifiers. | |
| 106 | + * Note that the patch might still be needed before the going handler | |
| 107 | + * is called. Module functions can be called even in the GOING state | |
| 108 | + * until mod->exit() finishes. This is especially important for | |
| 109 | + * patches that modify semantic of the functions. | |
| 100 | 110 | */ |
| 101 | − obj->mod = find_module(obj->name); | |
| 111 | + if (mod && mod->klp_alive) | |
| 112 | + obj->mod = mod; | |
| 113 | + | |
| 102 | 114 | mutex_unlock(&module_mutex); |
| 103 | 115 | } |
| 104 | 116 | |
| @@ -767,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) · 662 unmodified lines | ||
| 767 | 779 | return -EINVAL; |
| 768 | 780 | |
| 769 | 781 | obj->state = KLP_DISABLED; |
| 782 | + obj->mod = NULL; | |
| 770 | 783 | |
| 771 | 784 | klp_find_object_module(obj); |
| 772 | 785 | |
| @@ -961,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action, · 188 unmodified lines | ||
| 961 | 974 | |
| 962 | 975 | mutex_lock(&klp_mutex); |
| 963 | 976 | |
| 977 | + /* | |
| 978 | + * Each module has to know that the notifier has been called. | |
| 979 | + * We never know what module will get patched by a new patch. | |
| 980 | + */ | |
| 981 | + if (action == MODULE_STATE_COMING) | |
| 982 | + mod->klp_alive = true; | |
| 983 | + else /* MODULE_STATE_GOING */ | |
| 984 | + mod->klp_alive = false; | |
| 985 | + | |
| 964 | 986 | list_for_each_entry(patch, &klp_patches, list) { |
| 965 | 987 | for (obj = patch->objs; obj->funcs; obj++) { |
| 966 | 988 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) |
| @@ -56,7 +56,6 @@ · 55 unmodified lines | ||
| 56 | 56 | #include <linux/async.h> |
| 57 | 57 | #include <linux/percpu.h> |
| 58 | 58 | #include <linux/kmemleak.h> |
| 59 | −#include <linux/kasan.h> | |
| 60 | 59 | #include <linux/jump_label.h> |
| 61 | 60 | #include <linux/pfn.h> |
| 62 | 61 | #include <linux/bsearch.h> |
| @@ -1814,7 +1813,6 @@ static void unset_module_init_ro_nx(struct module *mod) { } · 1751 unmodified lines | ||
| 1814 | 1813 | void __weak module_memfree(void *module_region) |
| 1815 | 1814 | { |
| 1816 | 1815 | vfree(module_region); |
| 1817 | − kasan_module_free(module_region); | |
| 1818 | 1816 | } |
| 1819 | 1817 | |
| 1820 | 1818 | void __weak module_arch_cleanup(struct module *mod) |
| @@ -1059,6 +1059,12 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) · 1058 unmodified lines | ||
| 1059 | 1059 | |
| 1060 | 1060 | static struct pid * const ftrace_swapper_pid = &init_struct_pid; |
| 1061 | 1061 | |
| 1062 | +#ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
| 1063 | +static int ftrace_graph_active; | |
| 1064 | +#else | |
| 1065 | +# define ftrace_graph_active 0 | |
| 1066 | +#endif | |
| 1067 | + | |
| 1062 | 1068 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 1063 | 1069 | |
| 1064 | 1070 | static struct ftrace_ops *removed_ops; |
| @@ -2041,8 +2047,12 @@ static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) · 976 unmodified lines | ||
| 2041 | 2047 | if (!ftrace_rec_count(rec)) |
| 2042 | 2048 | rec->flags = 0; |
| 2043 | 2049 | else |
| 2044 | − /* Just disable the record (keep REGS state) */ | |
| 2045 | − rec->flags &= ~FTRACE_FL_ENABLED; | |
| 2050 | + /* | |
| 2051 | + * Just disable the record, but keep the ops TRAMP | |
| 2052 | + * and REGS states. The _EN flags must be disabled though. | |
| 2053 | + */ | |
| 2054 | + rec->flags &= ~(FTRACE_FL_ENABLED | FTRACE_FL_TRAMP_EN | | |
| 2055 | + FTRACE_FL_REGS_EN); | |
| 2046 | 2056 | } |
| 2047 | 2057 | |
| 2048 | 2058 | return FTRACE_UPDATE_MAKE_NOP; |
| @@ -2688,24 +2698,36 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) · 639 unmodified lines | ||
| 2688 | 2698 | |
| 2689 | 2699 | static void ftrace_startup_sysctl(void) |
| 2690 | 2700 | { |
| 2701 | + int command; | |
| 2702 | + | |
| 2691 | 2703 | if (unlikely(ftrace_disabled)) |
| 2692 | 2704 | return; |
| 2693 | 2705 | |
| 2694 | 2706 | /* Force update next time */ |
| 2695 | 2707 | saved_ftrace_func = NULL; |
| 2696 | 2708 | /* ftrace_start_up is true if we want ftrace running */ |
| 2697 | − if (ftrace_start_up) | |
| 2698 | − ftrace_run_update_code(FTRACE_UPDATE_CALLS); | |
| 2709 | + if (ftrace_start_up) { | |
| 2710 | + command = FTRACE_UPDATE_CALLS; | |
| 2711 | + if (ftrace_graph_active) | |
| 2712 | + command |= FTRACE_START_FUNC_RET; | |
| 2713 | + ftrace_startup_enable(command); | |
| 2714 | + } | |
| 2699 | 2715 | } |
| 2700 | 2716 | |
| 2701 | 2717 | static void ftrace_shutdown_sysctl(void) |
| 2702 | 2718 | { |
| 2719 | + int command; | |
| 2720 | + | |
| 2703 | 2721 | if (unlikely(ftrace_disabled)) |
| 2704 | 2722 | return; |
| 2705 | 2723 | |
| 2706 | 2724 | /* ftrace_start_up is true if ftrace is running */ |
| 2707 | − if (ftrace_start_up) | |
| 2708 | − ftrace_run_update_code(FTRACE_DISABLE_CALLS); | |
| 2725 | + if (ftrace_start_up) { | |
| 2726 | + command = FTRACE_DISABLE_CALLS; | |
| 2727 | + if (ftrace_graph_active) | |
| 2728 | + command |= FTRACE_STOP_FUNC_RET; | |
| 2729 | + ftrace_run_update_code(command); | |
| 2730 | + } | |
| 2709 | 2731 | } |
| 2710 | 2732 | |
| 2711 | 2733 | static cycle_t ftrace_update_time; |
| @@ -5558,12 +5580,12 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, · 2846 unmodified lines | ||
| 5558 | 5580 | |
| 5559 | 5581 | if (ftrace_enabled) { |
| 5560 | 5582 | |
| 5561 | − ftrace_startup_sysctl(); | |
| 5562 | − | |
| 5563 | 5583 | /* we are starting ftrace again */ |
| 5564 | 5584 | if (ftrace_ops_list != &ftrace_list_end) |
| 5565 | 5585 | update_ftrace_function(); |
| 5566 | 5586 | |
| 5587 | + ftrace_startup_sysctl(); | |
| 5588 | + | |
| 5567 | 5589 | } else { |
| 5568 | 5590 | /* stopping ftrace calls (just send to ftrace_stub) */ |
| 5569 | 5591 | ftrace_trace_function = ftrace_stub; |
| @@ -5590,8 +5612,6 @@ static struct ftrace_ops graph_ops = { · 20 unmodified lines | ||
| 5590 | 5612 | ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash) |
| 5591 | 5613 | }; |
| 5592 | 5614 | |
| 5593 | −static int ftrace_graph_active; | |
| 5594 | − | |
| 5595 | 5615 | int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) |
| 5596 | 5616 | { |
| 5597 | 5617 | return 0; |
| @@ -2728,19 +2728,57 @@ bool flush_work(struct work_struct *work) · 2727 unmodified lines | ||
| 2728 | 2728 | } |
| 2729 | 2729 | EXPORT_SYMBOL_GPL(flush_work); |
| 2730 | 2730 | |
| 2731 | +struct cwt_wait { | |
| 2732 | + wait_queue_t wait; | |
| 2733 | + struct work_struct *work; | |
| 2734 | +}; | |
| 2735 | + | |
| 2736 | +static int cwt_wakefn(wait_queue_t *wait, unsigned mode, int sync, void *key) | |
| 2737 | +{ | |
| 2738 | + struct cwt_wait *cwait = container_of(wait, struct cwt_wait, wait); | |
| 2739 | + | |
| 2740 | + if (cwait->work != key) | |
| 2741 | + return 0; | |
| 2742 | + return autoremove_wake_function(wait, mode, sync, key); | |
| 2743 | +} | |
| 2744 | + | |
| 2731 | 2745 | static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) |
| 2732 | 2746 | { |
| 2747 | + static DECLARE_WAIT_QUEUE_HEAD(cancel_waitq); | |
| 2733 | 2748 | unsigned long flags; |
| 2734 | 2749 | int ret; |
| 2735 | 2750 | |
| 2736 | 2751 | do { |
| 2737 | 2752 | ret = try_to_grab_pending(work, is_dwork, &flags); |
| 2738 | 2753 | /* |
| 2739 | − * If someone else is canceling, wait for the same event it | |
| 2740 | − * would be waiting for before retrying. | |
| 2754 | + * If someone else is already canceling, wait for it to | |
| 2755 | + * finish. flush_work() doesn't work for PREEMPT_NONE | |
| 2756 | + * because we may get scheduled between @work's completion | |
| 2757 | + * and the other canceling task resuming and clearing | |
| 2758 | + * CANCELING - flush_work() will return false immediately | |
| 2759 | + * as @work is no longer busy, try_to_grab_pending() will | |
| 2760 | + * return -ENOENT as @work is still being canceled and the | |
| 2761 | + * other canceling task won't be able to clear CANCELING as | |
| 2762 | + * we're hogging the CPU. | |
| 2763 | + * | |
| 2764 | + * Let's wait for completion using a waitqueue. As this | |
| 2765 | + * may lead to the thundering herd problem, use a custom | |
| 2766 | + * wake function which matches @work along with exclusive | |
| 2767 | + * wait and wakeup. | |
| 2741 | 2768 | */ |
| 2742 | − if (unlikely(ret == -ENOENT)) | |
| 2743 | − flush_work(work); | |
| 2769 | + if (unlikely(ret == -ENOENT)) { | |
| 2770 | + struct cwt_wait cwait; | |
| 2771 | + | |
| 2772 | + init_wait(&cwait.wait); | |
| 2773 | + cwait.wait.func = cwt_wakefn; | |
| 2774 | + cwait.work = work; | |
| 2775 | + | |
| 2776 | + prepare_to_wait_exclusive(&cancel_waitq, &cwait.wait, | |
| 2777 | + TASK_UNINTERRUPTIBLE); | |
| 2778 | + if (work_is_canceling(work)) | |
| 2779 | + schedule(); | |
| 2780 | + finish_wait(&cancel_waitq, &cwait.wait); | |
| 2781 | + } | |
| 2744 | 2782 | } while (unlikely(ret < 0)); |
| 2745 | 2783 | |
| 2746 | 2784 | /* tell other tasks trying to grab @work to back off */ |
| @@ -2749,6 +2787,16 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) · 2 unmodified lines | ||
| 2749 | 2787 | |
| 2750 | 2788 | flush_work(work); |
| 2751 | 2789 | clear_work_data(work); |
| 2790 | + | |
| 2791 | + /* | |
| 2792 | + * Paired with prepare_to_wait() above so that either | |
| 2793 | + * waitqueue_active() is visible here or !work_is_canceling() is | |
| 2794 | + * visible there. | |
| 2795 | + */ | |
| 2796 | + smp_mb(); | |
| 2797 | + if (waitqueue_active(&cancel_waitq)) | |
| 2798 | + __wake_up(&cancel_waitq, TASK_NORMAL, 1, work); | |
| 2799 | + | |
| 2752 | 2800 | return ret; |
| 2753 | 2801 | } |
| 2754 | 2802 | |
| @@ -24,7 +24,7 @@ obj-y += lockref.o · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
| 26 | 26 | bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ |
| 27 | − gcd.o lcm.o list_sort.o uuid.o flex_array.o clz_ctz.o \ | |
| 27 | + gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ | |
| 28 | 28 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ |
| 29 | 29 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o |
| 30 | 30 | obj-y += string_helpers.o |
| @@ -751,3 +751,18 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) · 750 unmodified lines | ||
| 751 | 751 | return npages; |
| 752 | 752 | } |
| 753 | 753 | EXPORT_SYMBOL(iov_iter_npages); |
| 754 | + | |
| 755 | +const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags) | |
| 756 | +{ | |
| 757 | + *new = *old; | |
| 758 | + if (new->type & ITER_BVEC) | |
| 759 | + return new->bvec = kmemdup(new->bvec, | |
| 760 | + new->nr_segs * sizeof(struct bio_vec), | |
| 761 | + flags); | |
| 762 | + else | |
| 763 | + /* iovec and kvec have identical layout */ | |
| 764 | + return new->iov = kmemdup(new->iov, | |
| 765 | + new->nr_segs * sizeof(struct iovec), | |
| 766 | + flags); | |
| 767 | +} | |
| 768 | +EXPORT_SYMBOL(dup_iter); | |
| @@ -139,6 +139,9 @@ static int lz4_uncompress(const char *source, char *dest, int osize) · 138 unmodified lines | ||
| 139 | 139 | /* Error: request to write beyond destination buffer */ |
| 140 | 140 | if (cpy > oend) |
| 141 | 141 | goto _output_error; |
| 142 | + if ((ref + COPYLENGTH) > oend || | |
| 143 | + (op + COPYLENGTH) > oend) | |
| 144 | + goto _output_error; | |
| 142 | 145 | LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); |
| 143 | 146 | while (op < cpy) |
| 144 | 147 | *op++ = *ref++; |
| @@ -61,7 +61,7 @@ int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | if (s->len < s->size) { |
| 63 | 63 | len = vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); |
| 64 | − if (seq_buf_can_fit(s, len)) { | |
| 64 | + if (s->len + len < s->size) { | |
| 65 | 65 | s->len += len; |
| 66 | 66 | return 0; |
| 67 | 67 | } |
| @@ -118,7 +118,7 @@ int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) · 50 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | if (s->len < s->size) { |
| 120 | 120 | ret = bstr_printf(s->buffer + s->len, len, fmt, binary); |
| 121 | − if (seq_buf_can_fit(s, ret)) { | |
| 121 | + if (s->len + ret < s->size) { | |
| 122 | 122 | s->len += ret; |
| 123 | 123 | return 0; |
| 124 | 124 | } |
| @@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ · 20 unmodified lines | ||
| 21 | 21 | mm_init.o mmu_context.o percpu.o slab_common.o \ |
| 22 | 22 | compaction.o vmacache.o \ |
| 23 | 23 | interval_tree.o list_lru.o workingset.o \ |
| 24 | − iov_iter.o debug.o $(mmu-y) | |
| 24 | + debug.o $(mmu-y) | |
| 25 | 25 | |
| 26 | 26 | obj-y += init-mm.o |
| 27 | 27 | |
| @@ -64,15 +64,17 @@ static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order) · 63 unmodified lines | ||
| 64 | 64 | return (1UL << (align_order - cma->order_per_bit)) - 1; |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | +/* | |
| 68 | + * Find a PFN aligned to the specified order and return an offset represented in | |
| 69 | + * order_per_bits. | |
| 70 | + */ | |
| 67 | 71 | static unsigned long cma_bitmap_aligned_offset(struct cma *cma, int align_order) |
| 68 | 72 | { |
| 69 | − unsigned int alignment; | |
| 70 | − | |
| 71 | 73 | if (align_order <= cma->order_per_bit) |
| 72 | 74 | return 0; |
| 73 | − alignment = 1UL << (align_order - cma->order_per_bit); | |
| 74 | − return ALIGN(cma->base_pfn, alignment) - | |
| 75 | − (cma->base_pfn >> cma->order_per_bit); | |
| 75 | + | |
| 76 | + return (ALIGN(cma->base_pfn, (1UL << align_order)) | |
| 77 | + - cma->base_pfn) >> cma->order_per_bit; | |
| 76 | 78 | } |
| 77 | 79 | |
| 78 | 80 | static unsigned long cma_bitmap_maxno(struct cma *cma) |
| @@ -1295,8 +1295,13 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, · 1294 unmodified lines | ||
| 1295 | 1295 | * Avoid grouping on DSO/COW pages in specific and RO pages |
| 1296 | 1296 | * in general, RO pages shouldn't hurt as much anyway since |
| 1297 | 1297 | * they can be in shared cache state. |
| 1298 | + * | |
| 1299 | + * FIXME! This checks "pmd_dirty()" as an approximation of | |
| 1300 | + * "is this a read-only page", since checking "pmd_write()" | |
| 1301 | + * is even more broken. We haven't actually turned this into | |
| 1302 | + * a writable page, so pmd_write() will always be false. | |
| 1298 | 1303 | */ |
| 1299 | − if (!pmd_write(pmd)) | |
| 1304 | + if (!pmd_dirty(pmd)) | |
| 1300 | 1305 | flags |= TNF_NO_GROUP; |
| 1301 | 1306 | |
| 1302 | 1307 | /* |
| @@ -1482,6 +1487,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, · 179 unmodified lines | ||
| 1482 | 1487 | |
| 1483 | 1488 | if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) { |
| 1484 | 1489 | pmd_t entry; |
| 1490 | + ret = 1; | |
| 1485 | 1491 | |
| 1486 | 1492 | /* |
| 1487 | 1493 | * Avoid trapping faults against the zero page. The read-only |
| @@ -1490,11 +1496,10 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, · 2 unmodified lines | ||
| 1490 | 1496 | */ |
| 1491 | 1497 | if (prot_numa && is_huge_zero_pmd(*pmd)) { |
| 1492 | 1498 | spin_unlock(ptl); |
| 1493 | − return 0; | |
| 1499 | + return ret; | |
| 1494 | 1500 | } |
| 1495 | 1501 | |
| 1496 | 1502 | if (!prot_numa || !pmd_protnone(*pmd)) { |
| 1497 | − ret = 1; | |
| 1498 | 1503 | entry = pmdp_get_and_clear_notify(mm, addr, pmd); |
| 1499 | 1504 | entry = pmd_modify(entry, newprot); |
| 1500 | 1505 | ret = HPAGE_PMD_NR; |
| @@ -917,7 +917,6 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) · 916 unmodified lines | ||
| 917 | 917 | __SetPageHead(page); |
| 918 | 918 | __ClearPageReserved(page); |
| 919 | 919 | for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { |
| 920 | − __SetPageTail(p); | |
| 921 | 920 | /* |
| 922 | 921 | * For gigantic hugepages allocated through bootmem at |
| 923 | 922 | * boot, it's safer to be consistent with the not-gigantic |
| @@ -933,6 +932,9 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) · 9 unmodified lines | ||
| 933 | 932 | __ClearPageReserved(p); |
| 934 | 933 | set_page_count(p, 0); |
| 935 | 934 | p->first_page = page; |
| 935 | + /* Make sure p->first_page is always valid for PageTail() */ | |
| 936 | + smp_wmb(); | |
| 937 | + __SetPageTail(p); | |
| 936 | 938 | } |
| 937 | 939 | } |
| 938 | 940 | |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/stacktrace.h> |
| 30 | 30 | #include <linux/string.h> |
| 31 | 31 | #include <linux/types.h> |
| 32 | +#include <linux/vmalloc.h> | |
| 32 | 33 | #include <linux/kasan.h> |
| 33 | 34 | |
| 34 | 35 | #include "kasan.h" |
| @@ -414,12 +415,19 @@ int kasan_module_alloc(void *addr, size_t size) · 379 unmodified lines | ||
| 414 | 415 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, |
| 415 | 416 | PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE, |
| 416 | 417 | __builtin_return_address(0)); |
| 417 | − return ret ? 0 : -ENOMEM; | |
| 418 | + | |
| 419 | + if (ret) { | |
| 420 | + find_vm_area(addr)->flags |= VM_KASAN; | |
| 421 | + return 0; | |
| 422 | + } | |
| 423 | + | |
| 424 | + return -ENOMEM; | |
| 418 | 425 | } |
| 419 | 426 | |
| 420 | −void kasan_module_free(void *addr) | |
| 427 | +void kasan_free_shadow(const struct vm_struct *vm) | |
| 421 | 428 | { |
| 422 | − vfree(kasan_mem_to_shadow(addr)); | |
| 429 | + if (vm->flags & VM_KASAN) | |
| 430 | + vfree(kasan_mem_to_shadow(vm->addr)); | |
| 423 | 431 | } |
| 424 | 432 | |
| 425 | 433 | static void register_global(struct kasan_global *global) |
| @@ -5232,7 +5232,9 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css) · 5231 unmodified lines | ||
| 5232 | 5232 | * on for the root memcg is enough. |
| 5233 | 5233 | */ |
| 5234 | 5234 | if (cgroup_on_dfl(root_css->cgroup)) |
| 5235 | − mem_cgroup_from_css(root_css)->use_hierarchy = true; | |
| 5235 | + root_mem_cgroup->use_hierarchy = true; | |
| 5236 | + else | |
| 5237 | + root_mem_cgroup->use_hierarchy = false; | |
| 5236 | 5238 | } |
| 5237 | 5239 | |
| 5238 | 5240 | static u64 memory_current_read(struct cgroup_subsys_state *css, |
| @@ -3072,8 +3072,13 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, · 3071 unmodified lines | ||
| 3072 | 3072 | * Avoid grouping on DSO/COW pages in specific and RO pages |
| 3073 | 3073 | * in general, RO pages shouldn't hurt as much anyway since |
| 3074 | 3074 | * they can be in shared cache state. |
| 3075 | + * | |
| 3076 | + * FIXME! This checks "pmd_dirty()" as an approximation of | |
| 3077 | + * "is this a read-only page", since checking "pmd_write()" | |
| 3078 | + * is even more broken. We haven't actually turned this into | |
| 3079 | + * a writable page, so pmd_write() will always be false. | |
| 3075 | 3080 | */ |
| 3076 | − if (!pte_write(pte)) | |
| 3081 | + if (!pte_dirty(pte)) | |
| 3077 | 3082 | flags |= TNF_NO_GROUP; |
| 3078 | 3083 | |
| 3079 | 3084 | /* |
| @@ -26,10 +26,10 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | int can_do_mlock(void) |
| 28 | 28 | { |
| 29 | − if (capable(CAP_IPC_LOCK)) | |
| 30 | − return 1; | |
| 31 | 29 | if (rlimit(RLIMIT_MEMLOCK) != 0) |
| 32 | 30 | return 1; |
| 31 | + if (capable(CAP_IPC_LOCK)) | |
| 32 | + return 1; | |
| 33 | 33 | return 0; |
| 34 | 34 | } |
| 35 | 35 | EXPORT_SYMBOL(can_do_mlock); |
| @@ -62,6 +62,7 @@ void *high_memory; · 61 unmodified lines | ||
| 62 | 62 | EXPORT_SYMBOL(high_memory); |
| 63 | 63 | struct page *mem_map; |
| 64 | 64 | unsigned long max_mapnr; |
| 65 | +EXPORT_SYMBOL(max_mapnr); | |
| 65 | 66 | unsigned long highest_memmap_pfn; |
| 66 | 67 | struct percpu_counter vm_committed_as; |
| 67 | 68 | int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ |
| @@ -2373,7 +2373,8 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, · 2372 unmodified lines | ||
| 2373 | 2373 | goto out; |
| 2374 | 2374 | } |
| 2375 | 2375 | /* Exhausted what can be done so it's blamo time */ |
| 2376 | − if (out_of_memory(ac->zonelist, gfp_mask, order, ac->nodemask, false)) | |
| 2376 | + if (out_of_memory(ac->zonelist, gfp_mask, order, ac->nodemask, false) | |
| 2377 | + || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) | |
| 2377 | 2378 | *did_some_progress = 1; |
| 2378 | 2379 | out: |
| 2379 | 2380 | oom_zonelist_unlock(ac->zonelist, gfp_mask); |
| @@ -1418,6 +1418,7 @@ struct vm_struct *remove_vm_area(const void *addr) · 1417 unmodified lines | ||
| 1418 | 1418 | spin_unlock(&vmap_area_lock); |
| 1419 | 1419 | |
| 1420 | 1420 | vmap_debug_free_range(va->va_start, va->va_end); |
| 1421 | + kasan_free_shadow(vm); | |
| 1421 | 1422 | free_unmap_vmap_area(va); |
| 1422 | 1423 | vm->size -= PAGE_SIZE; |
| 1423 | 1424 | |
| @@ -658,14 +658,30 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) · 657 unmodified lines | ||
| 658 | 658 | static void p9_virtio_remove(struct virtio_device *vdev) |
| 659 | 659 | { |
| 660 | 660 | struct virtio_chan *chan = vdev->priv; |
| 661 | − | |
| 662 | − if (chan->inuse) | |
| 663 | − p9_virtio_close(chan->client); | |
| 664 | − vdev->config->del_vqs(vdev); | |
| 661 | + unsigned long warning_time; | |
| 665 | 662 | |
| 666 | 663 | mutex_lock(&virtio_9p_lock); |
| 664 | + | |
| 665 | + /* Remove self from list so we don't get new users. */ | |
| 667 | 666 | list_del(&chan->chan_list); |
| 667 | + warning_time = jiffies; | |
| 668 | + | |
| 669 | + /* Wait for existing users to close. */ | |
| 670 | + while (chan->inuse) { | |
| 671 | + mutex_unlock(&virtio_9p_lock); | |
| 672 | + msleep(250); | |
| 673 | + if (time_after(jiffies, warning_time + 10 * HZ)) { | |
| 674 | + dev_emerg(&vdev->dev, | |
| 675 | + "p9_virtio_remove: waiting for device in use.\n"); | |
| 676 | + warning_time = jiffies; | |
| 677 | + } | |
| 678 | + mutex_lock(&virtio_9p_lock); | |
| 679 | + } | |
| 680 | + | |
| 668 | 681 | mutex_unlock(&virtio_9p_lock); |
| 682 | + | |
| 683 | + vdev->config->del_vqs(vdev); | |
| 684 | + | |
| 669 | 685 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); |
| 670 | 686 | kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE); |
| 671 | 687 | kfree(chan->tag); |
| @@ -563,6 +563,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) · 562 unmodified lines | ||
| 563 | 563 | */ |
| 564 | 564 | del_nbp(p); |
| 565 | 565 | |
| 566 | + dev_set_mtu(br->dev, br_min_mtu(br)); | |
| 567 | + | |
| 566 | 568 | spin_lock_bh(&br->lock); |
| 567 | 569 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 568 | 570 | spin_unlock_bh(&br->lock); |
| @@ -281,7 +281,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, · 280 unmodified lines | ||
| 281 | 281 | int copylen; |
| 282 | 282 | |
| 283 | 283 | ret = -EOPNOTSUPP; |
| 284 | − if (m->msg_flags&MSG_OOB) | |
| 284 | + if (flags & MSG_OOB) | |
| 285 | 285 | goto read_error; |
| 286 | 286 | |
| 287 | 287 | skb = skb_recv_datagram(sk, flags, 0 , &ret); |
| @@ -259,6 +259,9 @@ int can_send(struct sk_buff *skb, int loop) · 258 unmodified lines | ||
| 259 | 259 | goto inval_skb; |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | + skb->ip_summed = CHECKSUM_UNNECESSARY; | |
| 263 | + | |
| 264 | + skb_reset_mac_header(skb); | |
| 262 | 265 | skb_reset_network_header(skb); |
| 263 | 266 | skb_reset_transport_header(skb); |
| 264 | 267 | |
| @@ -2166,28 +2166,28 @@ replay: · 2165 unmodified lines | ||
| 2166 | 2166 | } |
| 2167 | 2167 | } |
| 2168 | 2168 | err = rtnl_configure_link(dev, ifm); |
| 2169 | − if (err < 0) { | |
| 2170 | − if (ops->newlink) { | |
| 2171 | − LIST_HEAD(list_kill); | |
| 2172 | − | |
| 2173 | − ops->dellink(dev, &list_kill); | |
| 2174 | − unregister_netdevice_many(&list_kill); | |
| 2175 | − } else { | |
| 2176 | − unregister_netdevice(dev); | |
| 2177 | − } | |
| 2178 | − goto out; | |
| 2179 | − } | |
| 2180 | − | |
| 2169 | + if (err < 0) | |
| 2170 | + goto out_unregister; | |
| 2181 | 2171 | if (link_net) { |
| 2182 | 2172 | err = dev_change_net_namespace(dev, dest_net, ifname); |
| 2183 | 2173 | if (err < 0) |
| 2184 | − unregister_netdevice(dev); | |
| 2174 | + goto out_unregister; | |
| 2185 | 2175 | } |
| 2186 | 2176 | out: |
| 2187 | 2177 | if (link_net) |
| 2188 | 2178 | put_net(link_net); |
| 2189 | 2179 | put_net(dest_net); |
| 2190 | 2180 | return err; |
| 2181 | +out_unregister: | |
| 2182 | + if (ops->newlink) { | |
| 2183 | + LIST_HEAD(list_kill); | |
| 2184 | + | |
| 2185 | + ops->dellink(dev, &list_kill); | |
| 2186 | + unregister_netdevice_many(&list_kill); | |
| 2187 | + } else { | |
| 2188 | + unregister_netdevice(dev); | |
| 2189 | + } | |
| 2190 | + goto out; | |
| 2191 | 2191 | } |
| 2192 | 2192 | } |
| 2193 | 2193 | |
| @@ -3733,9 +3733,13 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, · 3732 unmodified lines | ||
| 3733 | 3733 | struct sock *sk, int tstype) |
| 3734 | 3734 | { |
| 3735 | 3735 | struct sk_buff *skb; |
| 3736 | − bool tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | |
| 3736 | + bool tsonly; | |
| 3737 | 3737 | |
| 3738 | − if (!sk || !skb_may_tx_timestamp(sk, tsonly)) | |
| 3738 | + if (!sk) | |
| 3739 | + return; | |
| 3740 | + | |
| 3741 | + tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | |
| 3742 | + if (!skb_may_tx_timestamp(sk, tsonly)) | |
| 3739 | 3743 | return; |
| 3740 | 3744 | |
| 3741 | 3745 | if (tsonly) |
| @@ -4173,7 +4177,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) · 431 unmodified lines | ||
| 4173 | 4177 | skb->ignore_df = 0; |
| 4174 | 4178 | skb_dst_drop(skb); |
| 4175 | 4179 | skb->mark = 0; |
| 4176 | − skb->sender_cpu = 0; | |
| 4180 | + skb_sender_cpu_clear(skb); | |
| 4177 | 4181 | skb_init_secmark(skb); |
| 4178 | 4182 | secpath_reset(skb); |
| 4179 | 4183 | nf_reset(skb); |
| @@ -1655,6 +1655,10 @@ void sock_rfree(struct sk_buff *skb) · 1654 unmodified lines | ||
| 1655 | 1655 | } |
| 1656 | 1656 | EXPORT_SYMBOL(sock_rfree); |
| 1657 | 1657 | |
| 1658 | +/* | |
| 1659 | + * Buffer destructor for skbs that are not used directly in read or write | |
| 1660 | + * path, e.g. for error handler skbs. Automatically called from kfree_skb. | |
| 1661 | + */ | |
| 1658 | 1662 | void sock_efree(struct sk_buff *skb) |
| 1659 | 1663 | { |
| 1660 | 1664 | sock_put(skb->sk); |
| @@ -25,6 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | static int zero = 0; |
| 26 | 26 | static int one = 1; |
| 27 | 27 | static int ushort_max = USHRT_MAX; |
| 28 | +static int min_sndbuf = SOCK_MIN_SNDBUF; | |
| 29 | +static int min_rcvbuf = SOCK_MIN_RCVBUF; | |
| 28 | 30 | |
| 29 | 31 | static int net_msg_warn; /* Unused, but still a sysctl */ |
| 30 | 32 | |
| @@ -237,7 +239,7 @@ static struct ctl_table net_core_table[] = { · 206 unmodified lines | ||
| 237 | 239 | .maxlen = sizeof(int), |
| 238 | 240 | .mode = 0644, |
| 239 | 241 | .proc_handler = proc_dointvec_minmax, |
| 240 | − .extra1 = &one, | |
| 242 | + .extra1 = &min_sndbuf, | |
| 241 | 243 | }, |
| 242 | 244 | { |
| 243 | 245 | .procname = "rmem_max", |
| @@ -245,7 +247,7 @@ static struct ctl_table net_core_table[] = { · 1 unmodified line | ||
| 245 | 247 | .maxlen = sizeof(int), |
| 246 | 248 | .mode = 0644, |
| 247 | 249 | .proc_handler = proc_dointvec_minmax, |
| 248 | − .extra1 = &one, | |
| 250 | + .extra1 = &min_rcvbuf, | |
| 249 | 251 | }, |
| 250 | 252 | { |
| 251 | 253 | .procname = "wmem_default", |
| @@ -253,7 +255,7 @@ static struct ctl_table net_core_table[] = { · 1 unmodified line | ||
| 253 | 255 | .maxlen = sizeof(int), |
| 254 | 256 | .mode = 0644, |
| 255 | 257 | .proc_handler = proc_dointvec_minmax, |
| 256 | − .extra1 = &one, | |
| 258 | + .extra1 = &min_sndbuf, | |
| 257 | 259 | }, |
| 258 | 260 | { |
| 259 | 261 | .procname = "rmem_default", |
| @@ -261,7 +263,7 @@ static struct ctl_table net_core_table[] = { · 1 unmodified line | ||
| 261 | 263 | .maxlen = sizeof(int), |
| 262 | 264 | .mode = 0644, |
| 263 | 265 | .proc_handler = proc_dointvec_minmax, |
| 264 | − .extra1 = &one, | |
| 266 | + .extra1 = &min_rcvbuf, | |
| 265 | 267 | }, |
| 266 | 268 | { |
| 267 | 269 | .procname = "dev_weight", |
| @@ -268,6 +268,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) · 267 unmodified lines | ||
| 268 | 268 | release_sock(sk); |
| 269 | 269 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) |
| 270 | 270 | timeo = schedule_timeout(timeo); |
| 271 | + sched_annotate_sleep(); | |
| 271 | 272 | lock_sock(sk); |
| 272 | 273 | err = 0; |
| 273 | 274 | if (!reqsk_queue_empty(&icsk->icsk_accept_queue)) |
| @@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler( · 70 unmodified lines | ||
| 71 | 71 | mutex_unlock(&inet_diag_table_mutex); |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | +static size_t inet_sk_attr_size(void) | |
| 75 | +{ | |
| 76 | + return nla_total_size(sizeof(struct tcp_info)) | |
| 77 | + + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ | |
| 78 | + + nla_total_size(1) /* INET_DIAG_TOS */ | |
| 79 | + + nla_total_size(1) /* INET_DIAG_TCLASS */ | |
| 80 | + + nla_total_size(sizeof(struct inet_diag_meminfo)) | |
| 81 | + + nla_total_size(sizeof(struct inet_diag_msg)) | |
| 82 | + + nla_total_size(SK_MEMINFO_VARS * sizeof(u32)) | |
| 83 | + + nla_total_size(TCP_CA_NAME_MAX) | |
| 84 | + + nla_total_size(sizeof(struct tcpvegas_info)) | |
| 85 | + + 64; | |
| 86 | +} | |
| 87 | + | |
| 74 | 88 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, |
| 75 | 89 | struct sk_buff *skb, struct inet_diag_req_v2 *req, |
| 76 | 90 | struct user_namespace *user_ns, |
| @@ -326,9 +340,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s · 249 unmodified lines | ||
| 326 | 340 | if (err) |
| 327 | 341 | goto out; |
| 328 | 342 | |
| 329 | − rep = nlmsg_new(sizeof(struct inet_diag_msg) + | |
| 330 | − sizeof(struct inet_diag_meminfo) + | |
| 331 | − sizeof(struct tcp_info) + 64, GFP_KERNEL); | |
| 343 | + rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL); | |
| 332 | 344 | if (!rep) { |
| 333 | 345 | err = -ENOMEM; |
| 334 | 346 | goto out; |
| @@ -67,6 +67,7 @@ static int ip_forward_finish(struct sk_buff *skb) · 66 unmodified lines | ||
| 67 | 67 | if (unlikely(opt->optlen)) |
| 68 | 68 | ip_forward_options(skb); |
| 69 | 69 | |
| 70 | + skb_sender_cpu_clear(skb); | |
| 70 | 71 | return dst_output(skb); |
| 71 | 72 | } |
| 72 | 73 | |
| @@ -659,27 +659,30 @@ EXPORT_SYMBOL(ip_defrag); · 658 unmodified lines | ||
| 659 | 659 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) |
| 660 | 660 | { |
| 661 | 661 | struct iphdr iph; |
| 662 | + int netoff; | |
| 662 | 663 | u32 len; |
| 663 | 664 | |
| 664 | 665 | if (skb->protocol != htons(ETH_P_IP)) |
| 665 | 666 | return skb; |
| 666 | 667 | |
| 667 | − if (skb_copy_bits(skb, 0, &iph, sizeof(iph)) < 0) | |
| 668 | + netoff = skb_network_offset(skb); | |
| 669 | + | |
| 670 | + if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0) | |
| 668 | 671 | return skb; |
| 669 | 672 | |
| 670 | 673 | if (iph.ihl < 5 || iph.version != 4) |
| 671 | 674 | return skb; |
| 672 | 675 | |
| 673 | 676 | len = ntohs(iph.tot_len); |
| 674 | − if (skb->len < len || len < (iph.ihl * 4)) | |
| 677 | + if (skb->len < netoff + len || len < (iph.ihl * 4)) | |
| 675 | 678 | return skb; |
| 676 | 679 | |
| 677 | 680 | if (ip_is_fragment(&iph)) { |
| 678 | 681 | skb = skb_share_check(skb, GFP_ATOMIC); |
| 679 | 682 | if (skb) { |
| 680 | − if (!pskb_may_pull(skb, iph.ihl*4)) | |
| 683 | + if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) | |
| 681 | 684 | return skb; |
| 682 | − if (pskb_trim_rcsum(skb, len)) | |
| 685 | + if (pskb_trim_rcsum(skb, netoff + len)) | |
| 683 | 686 | return skb; |
| 684 | 687 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
| 685 | 688 | if (ip_defrag(skb, user)) |
| @@ -432,17 +432,32 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf · 431 unmodified lines | ||
| 432 | 432 | kfree_skb(skb); |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | −static bool ipv4_pktinfo_prepare_errqueue(const struct sock *sk, | |
| 436 | − const struct sk_buff *skb, | |
| 437 | − int ee_origin) | |
| 435 | +/* IPv4 supports cmsg on all imcp errors and some timestamps | |
| 436 | + * | |
| 437 | + * Timestamp code paths do not initialize the fields expected by cmsg: | |
| 438 | + * the PKTINFO fields in skb->cb[]. Fill those in here. | |
| 439 | + */ | |
| 440 | +static bool ipv4_datagram_support_cmsg(const struct sock *sk, | |
| 441 | + struct sk_buff *skb, | |
| 442 | + int ee_origin) | |
| 438 | 443 | { |
| 439 | − struct in_pktinfo *info = PKTINFO_SKB_CB(skb); | |
| 444 | + struct in_pktinfo *info; | |
| 445 | + | |
| 446 | + if (ee_origin == SO_EE_ORIGIN_ICMP) | |
| 447 | + return true; | |
| 440 | 448 | |
| 441 | − if ((ee_origin != SO_EE_ORIGIN_TIMESTAMPING) || | |
| 442 | − (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || | |
| 449 | + if (ee_origin == SO_EE_ORIGIN_LOCAL) | |
| 450 | + return false; | |
| 451 | + | |
| 452 | + /* Support IP_PKTINFO on tstamp packets if requested, to correlate | |
| 453 | + * timestamp with egress dev. Not possible for packets without dev | |
| 454 | + * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). | |
| 455 | + */ | |
| 456 | + if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || | |
| 443 | 457 | (!skb->dev)) |
| 444 | 458 | return false; |
| 445 | 459 | |
| 460 | + info = PKTINFO_SKB_CB(skb); | |
| 446 | 461 | info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; |
| 447 | 462 | info->ipi_ifindex = skb->dev->ifindex; |
| 448 | 463 | return true; |
| @@ -483,7 +498,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) · 34 unmodified lines | ||
| 483 | 498 | |
| 484 | 499 | serr = SKB_EXT_ERR(skb); |
| 485 | 500 | |
| 486 | − if (sin && skb->len) { | |
| 501 | + if (sin && serr->port) { | |
| 487 | 502 | sin->sin_family = AF_INET; |
| 488 | 503 | sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + |
| 489 | 504 | serr->addr_offset); |
| @@ -496,9 +511,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) · 6 unmodified lines | ||
| 496 | 511 | sin = &errhdr.offender; |
| 497 | 512 | memset(sin, 0, sizeof(*sin)); |
| 498 | 513 | |
| 499 | − if (skb->len && | |
| 500 | − (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || | |
| 501 | − ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin))) { | |
| 514 | + if (ipv4_datagram_support_cmsg(sk, skb, serr->ee.ee_origin)) { | |
| 502 | 515 | sin->sin_family = AF_INET; |
| 503 | 516 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
| 504 | 517 | if (inet_sk(sk)->cmsg_flags) |
| @@ -259,6 +259,9 @@ int ping_init_sock(struct sock *sk) · 258 unmodified lines | ||
| 259 | 259 | kgid_t low, high; |
| 260 | 260 | int ret = 0; |
| 261 | 261 | |
| 262 | + if (sk->sk_family == AF_INET6) | |
| 263 | + sk->sk_ipv6only = 1; | |
| 264 | + | |
| 262 | 265 | inet_get_ping_group_range_net(net, &low, &high); |
| 263 | 266 | if (gid_lte(low, group) && gid_lte(group, high)) |
| 264 | 267 | return 0; |
| @@ -305,6 +308,11 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, · 40 unmodified lines | ||
| 305 | 308 | if (addr_len < sizeof(*addr)) |
| 306 | 309 | return -EINVAL; |
| 307 | 310 | |
| 311 | + if (addr->sin_family != AF_INET && | |
| 312 | + !(addr->sin_family == AF_UNSPEC && | |
| 313 | + addr->sin_addr.s_addr == htonl(INADDR_ANY))) | |
| 314 | + return -EAFNOSUPPORT; | |
| 315 | + | |
| 308 | 316 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n", |
| 309 | 317 | sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port)); |
| 310 | 318 | |
| @@ -330,7 +338,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, · 19 unmodified lines | ||
| 330 | 338 | return -EINVAL; |
| 331 | 339 | |
| 332 | 340 | if (addr->sin6_family != AF_INET6) |
| 333 | − return -EINVAL; | |
| 341 | + return -EAFNOSUPPORT; | |
| 334 | 342 | |
| 335 | 343 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n", |
| 336 | 344 | sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); |
| @@ -716,7 +724,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m · 379 unmodified lines | ||
| 716 | 724 | if (msg->msg_namelen < sizeof(*usin)) |
| 717 | 725 | return -EINVAL; |
| 718 | 726 | if (usin->sin_family != AF_INET) |
| 719 | − return -EINVAL; | |
| 727 | + return -EAFNOSUPPORT; | |
| 720 | 728 | daddr = usin->sin_addr.s_addr; |
| 721 | 729 | /* no remote port */ |
| 722 | 730 | } else { |
| @@ -835,17 +835,13 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, · 834 unmodified lines | ||
| 835 | 835 | int large_allowed) |
| 836 | 836 | { |
| 837 | 837 | struct tcp_sock *tp = tcp_sk(sk); |
| 838 | − u32 new_size_goal, size_goal, hlen; | |
| 838 | + u32 new_size_goal, size_goal; | |
| 839 | 839 | |
| 840 | 840 | if (!large_allowed || !sk_can_gso(sk)) |
| 841 | 841 | return mss_now; |
| 842 | 842 | |
| 843 | − /* Maybe we should/could use sk->sk_prot->max_header here ? */ | |
| 844 | − hlen = inet_csk(sk)->icsk_af_ops->net_header_len + | |
| 845 | − inet_csk(sk)->icsk_ext_hdr_len + | |
| 846 | − tp->tcp_header_len; | |
| 847 | − | |
| 848 | − new_size_goal = sk->sk_gso_max_size - 1 - hlen; | |
| 843 | + /* Note : tcp_tso_autosize() will eventually split this later */ | |
| 844 | + new_size_goal = sk->sk_gso_max_size - 1 - MAX_TCP_HEADER; | |
| 849 | 845 | new_size_goal = tcp_bound_to_half_wnd(tp, new_size_goal); |
| 850 | 846 | |
| 851 | 847 | /* We try hard to avoid divides here */ |
| @@ -378,6 +378,12 @@ EXPORT_SYMBOL_GPL(tcp_slow_start); · 377 unmodified lines | ||
| 378 | 378 | */ |
| 379 | 379 | void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked) |
| 380 | 380 | { |
| 381 | + /* If credits accumulated at a higher w, apply them gently now. */ | |
| 382 | + if (tp->snd_cwnd_cnt >= w) { | |
| 383 | + tp->snd_cwnd_cnt = 0; | |
| 384 | + tp->snd_cwnd++; | |
| 385 | + } | |
| 386 | + | |
| 381 | 387 | tp->snd_cwnd_cnt += acked; |
| 382 | 388 | if (tp->snd_cwnd_cnt >= w) { |
| 383 | 389 | u32 delta = tp->snd_cwnd_cnt / w; |
| @@ -306,8 +306,10 @@ tcp_friendliness: · 305 unmodified lines | ||
| 306 | 306 | } |
| 307 | 307 | } |
| 308 | 308 | |
| 309 | − if (ca->cnt == 0) /* cannot be zero */ | |
| 310 | − ca->cnt = 1; | |
| 309 | + /* The maximum rate of cwnd increase CUBIC allows is 1 packet per | |
| 310 | + * 2 packets ACKed, meaning cwnd grows at 1.5x per RTT. | |
| 311 | + */ | |
| 312 | + ca->cnt = max(ca->cnt, 2U); | |
| 311 | 313 | } |
| 312 | 314 | |
| 313 | 315 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked) |
| @@ -63,6 +63,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) · 62 unmodified lines | ||
| 63 | 63 | return err; |
| 64 | 64 | |
| 65 | 65 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; |
| 66 | + skb->protocol = htons(ETH_P_IP); | |
| 66 | 67 | |
| 67 | 68 | return x->outer_mode->output2(x, skb); |
| 68 | 69 | } |
| @@ -71,7 +72,6 @@ EXPORT_SYMBOL(xfrm4_prepare_output); · 2 unmodified lines | ||
| 71 | 72 | int xfrm4_output_finish(struct sk_buff *skb) |
| 72 | 73 | { |
| 73 | 74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
| 74 | − skb->protocol = htons(ETH_P_IP); | |
| 75 | 75 | |
| 76 | 76 | #ifdef CONFIG_NETFILTER |
| 77 | 77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; |
| @@ -325,14 +325,34 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) · 324 unmodified lines | ||
| 325 | 325 | kfree_skb(skb); |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | −static void ip6_datagram_prepare_pktinfo_errqueue(struct sk_buff *skb) | |
| 328 | +/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL. | |
| 329 | + * | |
| 330 | + * At one point, excluding local errors was a quick test to identify icmp/icmp6 | |
| 331 | + * errors. This is no longer true, but the test remained, so the v6 stack, | |
| 332 | + * unlike v4, also honors cmsg requests on all wifi and timestamp errors. | |
| 333 | + * | |
| 334 | + * Timestamp code paths do not initialize the fields expected by cmsg: | |
| 335 | + * the PKTINFO fields in skb->cb[]. Fill those in here. | |
| 336 | + */ | |
| 337 | +static bool ip6_datagram_support_cmsg(struct sk_buff *skb, | |
| 338 | + struct sock_exterr_skb *serr) | |
| 329 | 339 | { |
| 330 | − int ifindex = skb->dev ? skb->dev->ifindex : -1; | |
| 340 | + if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || | |
| 341 | + serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) | |
| 342 | + return true; | |
| 343 | + | |
| 344 | + if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) | |
| 345 | + return false; | |
| 346 | + | |
| 347 | + if (!skb->dev) | |
| 348 | + return false; | |
| 331 | 349 | |
| 332 | 350 | if (skb->protocol == htons(ETH_P_IPV6)) |
| 333 | − IP6CB(skb)->iif = ifindex; | |
| 351 | + IP6CB(skb)->iif = skb->dev->ifindex; | |
| 334 | 352 | else |
| 335 | − PKTINFO_SKB_CB(skb)->ipi_ifindex = ifindex; | |
| 353 | + PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; | |
| 354 | + | |
| 355 | + return true; | |
| 336 | 356 | } |
| 337 | 357 | |
| 338 | 358 | /* |
| @@ -369,7 +389,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) · 30 unmodified lines | ||
| 369 | 389 | |
| 370 | 390 | serr = SKB_EXT_ERR(skb); |
| 371 | 391 | |
| 372 | − if (sin && skb->len) { | |
| 392 | + if (sin && serr->port) { | |
| 373 | 393 | const unsigned char *nh = skb_network_header(skb); |
| 374 | 394 | sin->sin6_family = AF_INET6; |
| 375 | 395 | sin->sin6_flowinfo = 0; |
| @@ -394,14 +414,11 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) · 18 unmodified lines | ||
| 394 | 414 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
| 395 | 415 | sin = &errhdr.offender; |
| 396 | 416 | memset(sin, 0, sizeof(*sin)); |
| 397 | − if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL && skb->len) { | |
| 417 | + | |
| 418 | + if (ip6_datagram_support_cmsg(skb, serr)) { | |
| 398 | 419 | sin->sin6_family = AF_INET6; |
| 399 | − if (np->rxopt.all) { | |
| 400 | − if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && | |
| 401 | − serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) | |
| 402 | − ip6_datagram_prepare_pktinfo_errqueue(skb); | |
| 420 | + if (np->rxopt.all) | |
| 403 | 421 | ip6_datagram_recv_common_ctl(sk, msg, skb); |
| 404 | − } | |
| 405 | 422 | if (skb->protocol == htons(ETH_P_IPV6)) { |
| 406 | 423 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
| 407 | 424 | if (np->rxopt.all) |
| @@ -318,6 +318,7 @@ static int ip6_forward_proxy_check(struct sk_buff *skb) · 317 unmodified lines | ||
| 318 | 318 | |
| 319 | 319 | static inline int ip6_forward_finish(struct sk_buff *skb) |
| 320 | 320 | { |
| 321 | + skb_sender_cpu_clear(skb); | |
| 321 | 322 | return dst_output(skb); |
| 322 | 323 | } |
| 323 | 324 | |
| @@ -314,7 +314,7 @@ out: · 313 unmodified lines | ||
| 314 | 314 | * Create tunnel matching given parameters. |
| 315 | 315 | * |
| 316 | 316 | * Return: |
| 317 | − * created tunnel or NULL | |
| 317 | + * created tunnel or error pointer | |
| 318 | 318 | **/ |
| 319 | 319 | |
| 320 | 320 | static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) |
| @@ -322,7 +322,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) · 1 unmodified line | ||
| 322 | 322 | struct net_device *dev; |
| 323 | 323 | struct ip6_tnl *t; |
| 324 | 324 | char name[IFNAMSIZ]; |
| 325 | − int err; | |
| 325 | + int err = -ENOMEM; | |
| 326 | 326 | |
| 327 | 327 | if (p->name[0]) |
| 328 | 328 | strlcpy(name, p->name, IFNAMSIZ); |
| @@ -348,7 +348,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) · 19 unmodified lines | ||
| 348 | 348 | failed_free: |
| 349 | 349 | ip6_dev_free(dev); |
| 350 | 350 | failed: |
| 351 | − return NULL; | |
| 351 | + return ERR_PTR(err); | |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | 354 | /** |
| @@ -362,7 +362,7 @@ failed: · 7 unmodified lines | ||
| 362 | 362 | * tunnel device is created and registered for use. |
| 363 | 363 | * |
| 364 | 364 | * Return: |
| 365 | − * matching tunnel or NULL | |
| 365 | + * matching tunnel or error pointer | |
| 366 | 366 | **/ |
| 367 | 367 | |
| 368 | 368 | static struct ip6_tnl *ip6_tnl_locate(struct net *net, |
| @@ -380,13 +380,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net, · 11 unmodified lines | ||
| 380 | 380 | if (ipv6_addr_equal(local, &t->parms.laddr) && |
| 381 | 381 | ipv6_addr_equal(remote, &t->parms.raddr)) { |
| 382 | 382 | if (create) |
| 383 | − return NULL; | |
| 383 | + return ERR_PTR(-EEXIST); | |
| 384 | 384 | |
| 385 | 385 | return t; |
| 386 | 386 | } |
| 387 | 387 | } |
| 388 | 388 | if (!create) |
| 389 | − return NULL; | |
| 389 | + return ERR_PTR(-ENODEV); | |
| 390 | 390 | return ip6_tnl_create(net, p); |
| 391 | 391 | } |
| 392 | 392 | |
| @@ -1420,7 +1420,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) · 1027 unmodified lines | ||
| 1420 | 1420 | } |
| 1421 | 1421 | ip6_tnl_parm_from_user(&p1, &p); |
| 1422 | 1422 | t = ip6_tnl_locate(net, &p1, 0); |
| 1423 | − if (t == NULL) | |
| 1423 | + if (IS_ERR(t)) | |
| 1424 | 1424 | t = netdev_priv(dev); |
| 1425 | 1425 | } else { |
| 1426 | 1426 | memset(&p, 0, sizeof(p)); |
| @@ -1445,7 +1445,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) · 18 unmodified lines | ||
| 1445 | 1445 | ip6_tnl_parm_from_user(&p1, &p); |
| 1446 | 1446 | t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL); |
| 1447 | 1447 | if (cmd == SIOCCHGTUNNEL) { |
| 1448 | − if (t != NULL) { | |
| 1448 | + if (!IS_ERR(t)) { | |
| 1449 | 1449 | if (t->dev != dev) { |
| 1450 | 1450 | err = -EEXIST; |
| 1451 | 1451 | break; |
| @@ -1457,14 +1457,15 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) · 5 unmodified lines | ||
| 1457 | 1457 | else |
| 1458 | 1458 | err = ip6_tnl_update(t, &p1); |
| 1459 | 1459 | } |
| 1460 | − if (t) { | |
| 1460 | + if (!IS_ERR(t)) { | |
| 1461 | 1461 | err = 0; |
| 1462 | 1462 | ip6_tnl_parm_to_user(&p, &t->parms); |
| 1463 | 1463 | if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) |
| 1464 | 1464 | err = -EFAULT; |
| 1465 | 1465 | |
| 1466 | − } else | |
| 1467 | − err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); | |
| 1466 | + } else { | |
| 1467 | + err = PTR_ERR(t); | |
| 1468 | + } | |
| 1468 | 1469 | break; |
| 1469 | 1470 | case SIOCDELTUNNEL: |
| 1470 | 1471 | err = -EPERM; |
| @@ -1478,7 +1479,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) · 7 unmodified lines | ||
| 1478 | 1479 | err = -ENOENT; |
| 1479 | 1480 | ip6_tnl_parm_from_user(&p1, &p); |
| 1480 | 1481 | t = ip6_tnl_locate(net, &p1, 0); |
| 1481 | − if (t == NULL) | |
| 1482 | + if (IS_ERR(t)) | |
| 1482 | 1483 | break; |
| 1483 | 1484 | err = -EPERM; |
| 1484 | 1485 | if (t->dev == ip6n->fb_tnl_dev) |
| @@ -1672,12 +1673,13 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, · 187 unmodified lines | ||
| 1672 | 1673 | struct nlattr *tb[], struct nlattr *data[]) |
| 1673 | 1674 | { |
| 1674 | 1675 | struct net *net = dev_net(dev); |
| 1675 | − struct ip6_tnl *nt; | |
| 1676 | + struct ip6_tnl *nt, *t; | |
| 1676 | 1677 | |
| 1677 | 1678 | nt = netdev_priv(dev); |
| 1678 | 1679 | ip6_tnl_netlink_parms(data, &nt->parms); |
| 1679 | 1680 | |
| 1680 | − if (ip6_tnl_locate(net, &nt->parms, 0)) | |
| 1681 | + t = ip6_tnl_locate(net, &nt->parms, 0); | |
| 1682 | + if (!IS_ERR(t)) | |
| 1681 | 1683 | return -EEXIST; |
| 1682 | 1684 | |
| 1683 | 1685 | return ip6_tnl_create2(dev); |
| @@ -1697,8 +1699,7 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[], · 13 unmodified lines | ||
| 1697 | 1699 | ip6_tnl_netlink_parms(data, &p); |
| 1698 | 1700 | |
| 1699 | 1701 | t = ip6_tnl_locate(net, &p, 0); |
| 1700 | − | |
| 1701 | − if (t) { | |
| 1702 | + if (!IS_ERR(t)) { | |
| 1702 | 1703 | if (t->dev != dev) |
| 1703 | 1704 | return -EEXIST; |
| 1704 | 1705 | } else |
| @@ -102,9 +102,10 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, · 101 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | if (msg->msg_name) { |
| 104 | 104 | DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name); |
| 105 | − if (msg->msg_namelen < sizeof(struct sockaddr_in6) || | |
| 106 | − u->sin6_family != AF_INET6) { | |
| 105 | + if (msg->msg_namelen < sizeof(*u)) | |
| 107 | 106 | return -EINVAL; |
| 107 | + if (u->sin6_family != AF_INET6) { | |
| 108 | + return -EAFNOSUPPORT; | |
| 108 | 109 | } |
| 109 | 110 | if (sk->sk_bound_dev_if && |
| 110 | 111 | sk->sk_bound_dev_if != u->sin6_scope_id) { |
| @@ -114,6 +114,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) · 113 unmodified lines | ||
| 114 | 114 | return err; |
| 115 | 115 | |
| 116 | 116 | skb->ignore_df = 1; |
| 117 | + skb->protocol = htons(ETH_P_IPV6); | |
| 117 | 118 | |
| 118 | 119 | return x->outer_mode->output2(x, skb); |
| 119 | 120 | } |
| @@ -122,7 +123,6 @@ EXPORT_SYMBOL(xfrm6_prepare_output); · 2 unmodified lines | ||
| 122 | 123 | int xfrm6_output_finish(struct sk_buff *skb) |
| 123 | 124 | { |
| 124 | 125 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); |
| 125 | − skb->protocol = htons(ETH_P_IPV6); | |
| 126 | 126 | |
| 127 | 127 | #ifdef CONFIG_NETFILTER |
| 128 | 128 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; |
| @@ -200,6 +200,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) · 199 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
| 202 | 202 | case IPPROTO_MH: |
| 203 | + offset += ipv6_optlen(exthdr); | |
| 203 | 204 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
| 204 | 205 | struct ip6_mh *mh; |
| 205 | 206 | |
| @@ -58,13 +58,24 @@ struct ieee80211_local; · 57 unmodified lines | ||
| 58 | 58 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN |
| 59 | 59 | |
| 60 | 60 | /* |
| 61 | − * Some APs experience problems when working with U-APSD. Decrease the | |
| 62 | − * probability of that happening by using legacy mode for all ACs but VO. | |
| 63 | − * The AP that caused us trouble was a Cisco 4410N. It ignores our | |
| 64 | − * setting, and always treats non-VO ACs as legacy. | |
| 61 | + * Some APs experience problems when working with U-APSD. Decreasing the | |
| 62 | + * probability of that happening by using legacy mode for all ACs but VO isn't | |
| 63 | + * enough. | |
| 64 | + * | |
| 65 | + * Cisco 4410N originally forced us to enable VO by default only because it | |
| 66 | + * treated non-VO ACs as legacy. | |
| 67 | + * | |
| 68 | + * However some APs (notably Netgear R7000) silently reclassify packets to | |
| 69 | + * different ACs. Since u-APSD ACs require trigger frames for frame retrieval | |
| 70 | + * clients would never see some frames (e.g. ARP responses) or would fetch them | |
| 71 | + * accidentally after a long time. | |
| 72 | + * | |
| 73 | + * It makes little sense to enable u-APSD queues by default because it needs | |
| 74 | + * userspace applications to be aware of it to actually take advantage of the | |
| 75 | + * possible additional powersavings. Implicitly depending on driver autotrigger | |
| 76 | + * frame support doesn't make much sense. | |
| 65 | 77 | */ |
| 66 | −#define IEEE80211_DEFAULT_UAPSD_QUEUES \ | |
| 67 | − IEEE80211_WMM_IE_STA_QOSINFO_AC_VO | |
| 78 | +#define IEEE80211_DEFAULT_UAPSD_QUEUES 0 | |
| 68 | 79 | |
| 69 | 80 | #define IEEE80211_DEFAULT_MAX_SP_LEN \ |
| 70 | 81 | IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL |
| @@ -453,6 +464,7 @@ struct ieee80211_if_managed { · 382 unmodified lines | ||
| 453 | 464 | unsigned int flags; |
| 454 | 465 | |
| 455 | 466 | bool csa_waiting_bcn; |
| 467 | + bool csa_ignored_same_chan; | |
| 456 | 468 | |
| 457 | 469 | bool beacon_crc_valid; |
| 458 | 470 | u32 beacon_crc; |
| @@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, · 1149 unmodified lines | ||
| 1150 | 1150 | return; |
| 1151 | 1151 | } |
| 1152 | 1152 | |
| 1153 | + if (cfg80211_chandef_identical(&csa_ie.chandef, | |
| 1154 | + &sdata->vif.bss_conf.chandef)) { | |
| 1155 | + if (ifmgd->csa_ignored_same_chan) | |
| 1156 | + return; | |
| 1157 | + sdata_info(sdata, | |
| 1158 | + "AP %pM tries to chanswitch to same channel, ignore\n", | |
| 1159 | + ifmgd->associated->bssid); | |
| 1160 | + ifmgd->csa_ignored_same_chan = true; | |
| 1161 | + return; | |
| 1162 | + } | |
| 1163 | + | |
| 1153 | 1164 | mutex_lock(&local->mtx); |
| 1154 | 1165 | mutex_lock(&local->chanctx_mtx); |
| 1155 | 1166 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
| @@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, · 54 unmodified lines | ||
| 1210 | 1221 | sdata->vif.csa_active = true; |
| 1211 | 1222 | sdata->csa_chandef = csa_ie.chandef; |
| 1212 | 1223 | sdata->csa_block_tx = csa_ie.mode; |
| 1224 | + ifmgd->csa_ignored_same_chan = false; | |
| 1213 | 1225 | |
| 1214 | 1226 | if (sdata->csa_block_tx) |
| 1215 | 1227 | ieee80211_stop_vif_queues(local, sdata, |
| @@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, · 874 unmodified lines | ||
| 2090 | 2102 | |
| 2091 | 2103 | sdata->vif.csa_active = false; |
| 2092 | 2104 | ifmgd->csa_waiting_bcn = false; |
| 2105 | + ifmgd->csa_ignored_same_chan = false; | |
| 2093 | 2106 | if (sdata->csa_block_tx) { |
| 2094 | 2107 | ieee80211_wake_vif_queues(local, sdata, |
| 2095 | 2108 | IEEE80211_QUEUE_STOP_REASON_CSA); |
| @@ -3204,7 +3217,8 @@ static const u64 care_about_ies = · 1108 unmodified lines | ||
| 3204 | 3217 | (1ULL << WLAN_EID_CHANNEL_SWITCH) | |
| 3205 | 3218 | (1ULL << WLAN_EID_PWR_CONSTRAINT) | |
| 3206 | 3219 | (1ULL << WLAN_EID_HT_CAPABILITY) | |
| 3207 | − (1ULL << WLAN_EID_HT_OPERATION); | |
| 3220 | + (1ULL << WLAN_EID_HT_OPERATION) | | |
| 3221 | + (1ULL << WLAN_EID_EXT_CHANSWITCH_ANN); | |
| 3208 | 3222 | |
| 3209 | 3223 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, |
| 3210 | 3224 | struct ieee80211_mgmt *mgmt, size_t len, |
| @@ -2214,6 +2214,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) · 2213 unmodified lines | ||
| 2214 | 2214 | hdr = (struct ieee80211_hdr *) skb->data; |
| 2215 | 2215 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
| 2216 | 2216 | |
| 2217 | + if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) | |
| 2218 | + return RX_DROP_MONITOR; | |
| 2219 | + | |
| 2217 | 2220 | /* frame is in RMC, don't forward */ |
| 2218 | 2221 | if (ieee80211_is_data(hdr->frame_control) && |
| 2219 | 2222 | is_multicast_ether_addr(hdr->addr1) && |
| @@ -3178,7 +3178,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, · 3177 unmodified lines | ||
| 3178 | 3178 | wdev_iter = &sdata_iter->wdev; |
| 3179 | 3179 | |
| 3180 | 3180 | if (sdata_iter == sdata || |
| 3181 | − rcu_access_pointer(sdata_iter->vif.chanctx_conf) == NULL || | |
| 3181 | + !ieee80211_sdata_running(sdata_iter) || | |
| 3182 | 3182 | local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) |
| 3183 | 3183 | continue; |
| 3184 | 3184 | |
| @@ -896,6 +896,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param, · 895 unmodified lines | ||
| 896 | 896 | IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); |
| 897 | 897 | return; |
| 898 | 898 | } |
| 899 | + if (!(flags & IP_VS_CONN_F_TEMPLATE)) | |
| 900 | + kfree(param->pe_data); | |
| 899 | 901 | } |
| 900 | 902 | |
| 901 | 903 | if (opt) |
| @@ -1169,6 +1171,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end) · 267 unmodified lines | ||
| 1169 | 1171 | (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL) |
| 1170 | 1172 | ); |
| 1171 | 1173 | #endif |
| 1174 | + ip_vs_pe_put(param.pe); | |
| 1172 | 1175 | return 0; |
| 1173 | 1176 | /* Error exit */ |
| 1174 | 1177 | out: |
| @@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule) · 226 unmodified lines | ||
| 227 | 227 | |
| 228 | 228 | static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) |
| 229 | 229 | { |
| 230 | − rule->genmask = 0; | |
| 230 | + rule->genmask &= ~(1 << gencursor_next(net)); | |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | 233 | static int |
| @@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 1477 unmodified lines | ||
| 1711 | 1711 | } |
| 1712 | 1712 | nla_nest_end(skb, list); |
| 1713 | 1713 | |
| 1714 | − if (rule->ulen && | |
| 1715 | − nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule))) | |
| 1716 | − goto nla_put_failure; | |
| 1714 | + if (rule->udata) { | |
| 1715 | + struct nft_userdata *udata = nft_userdata(rule); | |
| 1716 | + if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1, | |
| 1717 | + udata->data) < 0) | |
| 1718 | + goto nla_put_failure; | |
| 1719 | + } | |
| 1717 | 1720 | |
| 1718 | 1721 | nlmsg_end(skb, nlh); |
| 1719 | 1722 | return 0; |
| @@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, · 176 unmodified lines | ||
| 1896 | 1899 | struct nft_table *table; |
| 1897 | 1900 | struct nft_chain *chain; |
| 1898 | 1901 | struct nft_rule *rule, *old_rule = NULL; |
| 1902 | + struct nft_userdata *udata; | |
| 1899 | 1903 | struct nft_trans *trans = NULL; |
| 1900 | 1904 | struct nft_expr *expr; |
| 1901 | 1905 | struct nft_ctx ctx; |
| 1902 | 1906 | struct nlattr *tmp; |
| 1903 | − unsigned int size, i, n, ulen = 0; | |
| 1907 | + unsigned int size, i, n, ulen = 0, usize = 0; | |
| 1904 | 1908 | int err, rem; |
| 1905 | 1909 | bool create; |
| 1906 | 1910 | u64 handle, pos_handle; |
| @@ -1968,12 +1972,19 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, · 61 unmodified lines | ||
| 1968 | 1972 | n++; |
| 1969 | 1973 | } |
| 1970 | 1974 | } |
| 1975 | + /* Check for overflow of dlen field */ | |
| 1976 | + err = -EFBIG; | |
| 1977 | + if (size >= 1 << 12) | |
| 1978 | + goto err1; | |
| 1971 | 1979 | |
| 1972 | − if (nla[NFTA_RULE_USERDATA]) | |
| 1980 | + if (nla[NFTA_RULE_USERDATA]) { | |
| 1973 | 1981 | ulen = nla_len(nla[NFTA_RULE_USERDATA]); |
| 1982 | + if (ulen > 0) | |
| 1983 | + usize = sizeof(struct nft_userdata) + ulen; | |
| 1984 | + } | |
| 1974 | 1985 | |
| 1975 | 1986 | err = -ENOMEM; |
| 1976 | − rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL); | |
| 1987 | + rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL); | |
| 1977 | 1988 | if (rule == NULL) |
| 1978 | 1989 | goto err1; |
| 1979 | 1990 | |
| @@ -1981,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, · 1 unmodified line | ||
| 1981 | 1992 | |
| 1982 | 1993 | rule->handle = handle; |
| 1983 | 1994 | rule->dlen = size; |
| 1984 | − rule->ulen = ulen; | |
| 1995 | + rule->udata = ulen ? 1 : 0; | |
| 1985 | 1996 | |
| 1986 | − if (ulen) | |
| 1987 | − nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen); | |
| 1997 | + if (ulen) { | |
| 1998 | + udata = nft_userdata(rule); | |
| 1999 | + udata->len = ulen - 1; | |
| 2000 | + nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen); | |
| 2001 | + } | |
| 1988 | 2002 | |
| 1989 | 2003 | expr = nft_expr_first(rule); |
| 1990 | 2004 | for (i = 0; i < n; i++) { |
| @@ -2031,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, · 40 unmodified lines | ||
| 2031 | 2045 | |
| 2032 | 2046 | err3: |
| 2033 | 2047 | list_del_rcu(&rule->list); |
| 2034 | − if (trans) { | |
| 2035 | − list_del_rcu(&nft_trans_rule(trans)->list); | |
| 2036 | − nft_rule_clear(net, nft_trans_rule(trans)); | |
| 2037 | − nft_trans_destroy(trans); | |
| 2038 | − chain->use++; | |
| 2039 | − } | |
| 2040 | 2048 | err2: |
| 2041 | 2049 | nf_tables_rule_destroy(&ctx, rule); |
| 2042 | 2050 | err1: |
| @@ -3612,12 +3620,11 @@ static int nf_tables_commit(struct sk_buff *skb) · 1569 unmodified lines | ||
| 3612 | 3620 | &te->elem, |
| 3613 | 3621 | NFT_MSG_DELSETELEM, 0); |
| 3614 | 3622 | te->set->ops->get(te->set, &te->elem); |
| 3615 | − te->set->ops->remove(te->set, &te->elem); | |
| 3616 | 3623 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); |
| 3617 | − if (te->elem.flags & NFT_SET_MAP) { | |
| 3618 | − nft_data_uninit(&te->elem.data, | |
| 3619 | − te->set->dtype); | |
| 3620 | − } | |
| 3624 | + if (te->set->flags & NFT_SET_MAP && | |
| 3625 | + !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) | |
| 3626 | + nft_data_uninit(&te->elem.data, te->set->dtype); | |
| 3627 | + te->set->ops->remove(te->set, &te->elem); | |
| 3621 | 3628 | nft_trans_destroy(trans); |
| 3622 | 3629 | break; |
| 3623 | 3630 | } |
| @@ -3658,7 +3665,7 @@ static int nf_tables_abort(struct sk_buff *skb) · 34 unmodified lines | ||
| 3658 | 3665 | { |
| 3659 | 3666 | struct net *net = sock_net(skb->sk); |
| 3660 | 3667 | struct nft_trans *trans, *next; |
| 3661 | − struct nft_set *set; | |
| 3668 | + struct nft_trans_elem *te; | |
| 3662 | 3669 | |
| 3663 | 3670 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { |
| 3664 | 3671 | switch (trans->msg_type) { |
| @@ -3719,9 +3726,13 @@ static int nf_tables_abort(struct sk_buff *skb) · 54 unmodified lines | ||
| 3719 | 3726 | break; |
| 3720 | 3727 | case NFT_MSG_NEWSETELEM: |
| 3721 | 3728 | nft_trans_elem_set(trans)->nelems--; |
| 3722 | − set = nft_trans_elem_set(trans); | |
| 3723 | − set->ops->get(set, &nft_trans_elem(trans)); | |
| 3724 | − set->ops->remove(set, &nft_trans_elem(trans)); | |
| 3729 | + te = (struct nft_trans_elem *)trans->data; | |
| 3730 | + te->set->ops->get(te->set, &te->elem); | |
| 3731 | + nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); | |
| 3732 | + if (te->set->flags & NFT_SET_MAP && | |
| 3733 | + !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) | |
| 3734 | + nft_data_uninit(&te->elem.data, te->set->dtype); | |
| 3735 | + te->set->ops->remove(te->set, &te->elem); | |
| 3725 | 3736 | nft_trans_destroy(trans); |
| 3726 | 3737 | break; |
| 3727 | 3738 | case NFT_MSG_DELSETELEM: |
| @@ -123,7 +123,7 @@ static void · 122 unmodified lines | ||
| 123 | 123 | nft_target_set_tgchk_param(struct xt_tgchk_param *par, |
| 124 | 124 | const struct nft_ctx *ctx, |
| 125 | 125 | struct xt_target *target, void *info, |
| 126 | − union nft_entry *entry, u8 proto, bool inv) | |
| 126 | + union nft_entry *entry, u16 proto, bool inv) | |
| 127 | 127 | { |
| 128 | 128 | par->net = ctx->net; |
| 129 | 129 | par->table = ctx->table->name; |
| @@ -137,7 +137,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, · 7 unmodified lines | ||
| 137 | 137 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
| 138 | 138 | break; |
| 139 | 139 | case NFPROTO_BRIDGE: |
| 140 | − entry->ebt.ethproto = proto; | |
| 140 | + entry->ebt.ethproto = (__force __be16)proto; | |
| 141 | 141 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
| 142 | 142 | break; |
| 143 | 143 | } |
| @@ -171,7 +171,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] · 27 unmodified lines | ||
| 171 | 171 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, |
| 172 | 172 | }; |
| 173 | 173 | |
| 174 | −static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv) | |
| 174 | +static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) | |
| 175 | 175 | { |
| 176 | 176 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; |
| 177 | 177 | u32 flags; |
| @@ -203,7 +203,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 25 unmodified lines | ||
| 203 | 203 | struct xt_target *target = expr->ops->data; |
| 204 | 204 | struct xt_tgchk_param par; |
| 205 | 205 | size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); |
| 206 | − u8 proto = 0; | |
| 206 | + u16 proto = 0; | |
| 207 | 207 | bool inv = false; |
| 208 | 208 | union nft_entry e = {}; |
| 209 | 209 | int ret; |
| @@ -334,7 +334,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { · 124 unmodified lines | ||
| 334 | 334 | static void |
| 335 | 335 | nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, |
| 336 | 336 | struct xt_match *match, void *info, |
| 337 | − union nft_entry *entry, u8 proto, bool inv) | |
| 337 | + union nft_entry *entry, u16 proto, bool inv) | |
| 338 | 338 | { |
| 339 | 339 | par->net = ctx->net; |
| 340 | 340 | par->table = ctx->table->name; |
| @@ -348,7 +348,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, · 7 unmodified lines | ||
| 348 | 348 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
| 349 | 349 | break; |
| 350 | 350 | case NFPROTO_BRIDGE: |
| 351 | − entry->ebt.ethproto = proto; | |
| 351 | + entry->ebt.ethproto = (__force __be16)proto; | |
| 352 | 352 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
| 353 | 353 | break; |
| 354 | 354 | } |
| @@ -385,7 +385,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, · 30 unmodified lines | ||
| 385 | 385 | struct xt_match *match = expr->ops->data; |
| 386 | 386 | struct xt_mtchk_param par; |
| 387 | 387 | size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); |
| 388 | − u8 proto = 0; | |
| 388 | + u16 proto = 0; | |
| 389 | 389 | bool inv = false; |
| 390 | 390 | union nft_entry e = {}; |
| 391 | 391 | int ret; |
| @@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, · 3122 unmodified lines | ||
| 3123 | 3123 | return 0; |
| 3124 | 3124 | } |
| 3125 | 3125 | |
| 3126 | −static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) | |
| 3126 | +static void packet_dev_mclist_delete(struct net_device *dev, | |
| 3127 | + struct packet_mclist **mlp) | |
| 3127 | 3128 | { |
| 3128 | − for ( ; i; i = i->next) { | |
| 3129 | − if (i->ifindex == dev->ifindex) | |
| 3130 | − packet_dev_mc(dev, i, what); | |
| 3129 | + struct packet_mclist *ml; | |
| 3130 | + | |
| 3131 | + while ((ml = *mlp) != NULL) { | |
| 3132 | + if (ml->ifindex == dev->ifindex) { | |
| 3133 | + packet_dev_mc(dev, ml, -1); | |
| 3134 | + *mlp = ml->next; | |
| 3135 | + kfree(ml); | |
| 3136 | + } else | |
| 3137 | + mlp = &ml->next; | |
| 3131 | 3138 | } |
| 3132 | 3139 | } |
| 3133 | 3140 | |
| @@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) · 70 unmodified lines | ||
| 3204 | 3211 | packet_dev_mc(dev, ml, -1); |
| 3205 | 3212 | kfree(ml); |
| 3206 | 3213 | } |
| 3207 | − rtnl_unlock(); | |
| 3208 | − return 0; | |
| 3214 | + break; | |
| 3209 | 3215 | } |
| 3210 | 3216 | } |
| 3211 | 3217 | rtnl_unlock(); |
| 3212 | − return -EADDRNOTAVAIL; | |
| 3218 | + return 0; | |
| 3213 | 3219 | } |
| 3214 | 3220 | |
| 3215 | 3221 | static void packet_flush_mclist(struct sock *sk) |
| @@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this, · 343 unmodified lines | ||
| 3559 | 3565 | switch (msg) { |
| 3560 | 3566 | case NETDEV_UNREGISTER: |
| 3561 | 3567 | if (po->mclist) |
| 3562 | − packet_dev_mclist(dev, po->mclist, -1); | |
| 3568 | + packet_dev_mclist_delete(dev, &po->mclist); | |
| 3563 | 3569 | /* fallthrough */ |
| 3564 | 3570 | |
| 3565 | 3571 | case NETDEV_DOWN: |
| @@ -88,7 +88,9 @@ static unsigned int rds_iw_unmap_fastreg_list(struct rds_iw_mr_pool *pool, · 87 unmodified lines | ||
| 88 | 88 | int *unpinned); |
| 89 | 89 | static void rds_iw_destroy_fastreg(struct rds_iw_mr_pool *pool, struct rds_iw_mr *ibmr); |
| 90 | 90 | |
| 91 | −static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwdev, struct rdma_cm_id **cm_id) | |
| 91 | +static int rds_iw_get_device(struct sockaddr_in *src, struct sockaddr_in *dst, | |
| 92 | + struct rds_iw_device **rds_iwdev, | |
| 93 | + struct rdma_cm_id **cm_id) | |
| 92 | 94 | { |
| 93 | 95 | struct rds_iw_device *iwdev; |
| 94 | 96 | struct rds_iw_cm_id *i_cm_id; |
| @@ -112,15 +114,15 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd · 17 unmodified lines | ||
| 112 | 114 | src_addr->sin_port, |
| 113 | 115 | dst_addr->sin_addr.s_addr, |
| 114 | 116 | dst_addr->sin_port, |
| 115 | − rs->rs_bound_addr, | |
| 116 | − rs->rs_bound_port, | |
| 117 | − rs->rs_conn_addr, | |
| 118 | − rs->rs_conn_port); | |
| 117 | + src->sin_addr.s_addr, | |
| 118 | + src->sin_port, | |
| 119 | + dst->sin_addr.s_addr, | |
| 120 | + dst->sin_port); | |
| 119 | 121 | #ifdef WORKING_TUPLE_DETECTION |
| 120 | − if (src_addr->sin_addr.s_addr == rs->rs_bound_addr && | |
| 121 | − src_addr->sin_port == rs->rs_bound_port && | |
| 122 | − dst_addr->sin_addr.s_addr == rs->rs_conn_addr && | |
| 123 | − dst_addr->sin_port == rs->rs_conn_port) { | |
| 122 | + if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr && | |
| 123 | + src_addr->sin_port == src->sin_port && | |
| 124 | + dst_addr->sin_addr.s_addr == dst->sin_addr.s_addr && | |
| 125 | + dst_addr->sin_port == dst->sin_port) { | |
| 124 | 126 | #else |
| 125 | 127 | /* FIXME - needs to compare the local and remote |
| 126 | 128 | * ipaddr/port tuple, but the ipaddr is the only |
| @@ -128,7 +130,7 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd · 1 unmodified line | ||
| 128 | 130 | * zero'ed. It doesn't appear to be properly populated |
| 129 | 131 | * during connection setup... |
| 130 | 132 | */ |
| 131 | − if (src_addr->sin_addr.s_addr == rs->rs_bound_addr) { | |
| 133 | + if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr) { | |
| 132 | 134 | #endif |
| 133 | 135 | spin_unlock_irq(&iwdev->spinlock); |
| 134 | 136 | *rds_iwdev = iwdev; |
| @@ -180,19 +182,13 @@ int rds_iw_update_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_i · 45 unmodified lines | ||
| 180 | 182 | { |
| 181 | 183 | struct sockaddr_in *src_addr, *dst_addr; |
| 182 | 184 | struct rds_iw_device *rds_iwdev_old; |
| 183 | − struct rds_sock rs; | |
| 184 | 185 | struct rdma_cm_id *pcm_id; |
| 185 | 186 | int rc; |
| 186 | 187 | |
| 187 | 188 | src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr; |
| 188 | 189 | dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr; |
| 189 | 190 | |
| 190 | − rs.rs_bound_addr = src_addr->sin_addr.s_addr; | |
| 191 | − rs.rs_bound_port = src_addr->sin_port; | |
| 192 | − rs.rs_conn_addr = dst_addr->sin_addr.s_addr; | |
| 193 | − rs.rs_conn_port = dst_addr->sin_port; | |
| 194 | − | |
| 195 | − rc = rds_iw_get_device(&rs, &rds_iwdev_old, &pcm_id); | |
| 191 | + rc = rds_iw_get_device(src_addr, dst_addr, &rds_iwdev_old, &pcm_id); | |
| 196 | 192 | if (rc) |
| 197 | 193 | rds_iw_remove_cm_id(rds_iwdev, cm_id); |
| 198 | 194 | |
| @@ -598,9 +594,17 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents, · 399 unmodified lines | ||
| 598 | 594 | struct rds_iw_device *rds_iwdev; |
| 599 | 595 | struct rds_iw_mr *ibmr = NULL; |
| 600 | 596 | struct rdma_cm_id *cm_id; |
| 597 | + struct sockaddr_in src = { | |
| 598 | + .sin_addr.s_addr = rs->rs_bound_addr, | |
| 599 | + .sin_port = rs->rs_bound_port, | |
| 600 | + }; | |
| 601 | + struct sockaddr_in dst = { | |
| 602 | + .sin_addr.s_addr = rs->rs_conn_addr, | |
| 603 | + .sin_port = rs->rs_conn_port, | |
| 604 | + }; | |
| 601 | 605 | int ret; |
| 602 | 606 | |
| 603 | − ret = rds_iw_get_device(rs, &rds_iwdev, &cm_id); | |
| 607 | + ret = rds_iw_get_device(&src, &dst, &rds_iwdev, &cm_id); | |
| 604 | 608 | if (ret || !cm_id) { |
| 605 | 609 | ret = -ENODEV; |
| 606 | 610 | goto out; |
| @@ -42,7 +42,8 @@ void rxrpc_UDP_error_report(struct sock *sk) · 41 unmodified lines | ||
| 42 | 42 | _leave("UDP socket errqueue empty"); |
| 43 | 43 | return; |
| 44 | 44 | } |
| 45 | − if (!skb->len) { | |
| 45 | + serr = SKB_EXT_ERR(skb); | |
| 46 | + if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) { | |
| 46 | 47 | _leave("UDP empty message"); |
| 47 | 48 | kfree_skb(skb); |
| 48 | 49 | return; |
| @@ -50,7 +51,6 @@ void rxrpc_UDP_error_report(struct sock *sk) · 1 unmodified line | ||
| 50 | 51 | |
| 51 | 52 | rxrpc_new_skb(skb); |
| 52 | 53 | |
| 53 | − serr = SKB_EXT_ERR(skb); | |
| 54 | 54 | addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset); |
| 55 | 55 | port = serr->port; |
| 56 | 56 | |
| @@ -87,7 +87,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, · 86 unmodified lines | ||
| 87 | 87 | if (!skb) { |
| 88 | 88 | /* nothing remains on the queue */ |
| 89 | 89 | if (copied && |
| 90 | − (msg->msg_flags & MSG_PEEK || timeo == 0)) | |
| 90 | + (flags & MSG_PEEK || timeo == 0)) | |
| 91 | 91 | goto out; |
| 92 | 92 | |
| 93 | 93 | /* wait for a message to turn up */ |
| @@ -25,21 +25,41 @@ static int tcf_bpf(struct sk_buff *skb, const struct tc_action *a, · 24 unmodified lines | ||
| 25 | 25 | struct tcf_result *res) |
| 26 | 26 | { |
| 27 | 27 | struct tcf_bpf *b = a->priv; |
| 28 | − int action; | |
| 29 | − int filter_res; | |
| 28 | + int action, filter_res; | |
| 30 | 29 | |
| 31 | 30 | spin_lock(&b->tcf_lock); |
| 31 | + | |
| 32 | 32 | b->tcf_tm.lastuse = jiffies; |
| 33 | 33 | bstats_update(&b->tcf_bstats, skb); |
| 34 | − action = b->tcf_action; | |
| 35 | 34 | |
| 36 | 35 | filter_res = BPF_PROG_RUN(b->filter, skb); |
| 37 | − if (filter_res == 0) { | |
| 38 | − /* Return code 0 from the BPF program | |
| 39 | − * is being interpreted as a drop here. | |
| 40 | − */ | |
| 41 | − action = TC_ACT_SHOT; | |
| 36 | + | |
| 37 | + /* A BPF program may overwrite the default action opcode. | |
| 38 | + * Similarly as in cls_bpf, if filter_res == -1 we use the | |
| 39 | + * default action specified from tc. | |
| 40 | + * | |
| 41 | + * In case a different well-known TC_ACT opcode has been | |
| 42 | + * returned, it will overwrite the default one. | |
| 43 | + * | |
| 44 | + * For everything else that is unkown, TC_ACT_UNSPEC is | |
| 45 | + * returned. | |
| 46 | + */ | |
| 47 | + switch (filter_res) { | |
| 48 | + case TC_ACT_PIPE: | |
| 49 | + case TC_ACT_RECLASSIFY: | |
| 50 | + case TC_ACT_OK: | |
| 51 | + action = filter_res; | |
| 52 | + break; | |
| 53 | + case TC_ACT_SHOT: | |
| 54 | + action = filter_res; | |
| 42 | 55 | b->tcf_qstats.drops++; |
| 56 | + break; | |
| 57 | + case TC_ACT_UNSPEC: | |
| 58 | + action = b->tcf_action; | |
| 59 | + break; | |
| 60 | + default: | |
| 61 | + action = TC_ACT_UNSPEC; | |
| 62 | + break; | |
| 43 | 63 | } |
| 44 | 64 | |
| 45 | 65 | spin_unlock(&b->tcf_lock); |
| @@ -78,8 +78,11 @@ struct tc_u_hnode { · 77 unmodified lines | ||
| 78 | 78 | struct tc_u_common *tp_c; |
| 79 | 79 | int refcnt; |
| 80 | 80 | unsigned int divisor; |
| 81 | − struct tc_u_knode __rcu *ht[1]; | |
| 82 | 81 | struct rcu_head rcu; |
| 82 | + /* The 'ht' field MUST be the last field in structure to allow for | |
| 83 | + * more entries allocated at end of structure. | |
| 84 | + */ | |
| 85 | + struct tc_u_knode __rcu *ht[1]; | |
| 83 | 86 | }; |
| 84 | 87 | |
| 85 | 88 | struct tc_u_common { |
| @@ -464,10 +464,11 @@ void tipc_link_reset(struct tipc_link *l_ptr) · 463 unmodified lines | ||
| 464 | 464 | /* Clean up all queues, except inputq: */ |
| 465 | 465 | __skb_queue_purge(&l_ptr->outqueue); |
| 466 | 466 | __skb_queue_purge(&l_ptr->deferred_queue); |
| 467 | − skb_queue_splice_init(&l_ptr->wakeupq, &l_ptr->inputq); | |
| 468 | − if (!skb_queue_empty(&l_ptr->inputq)) | |
| 467 | + if (!owner->inputq) | |
| 468 | + owner->inputq = &l_ptr->inputq; | |
| 469 | + skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq); | |
| 470 | + if (!skb_queue_empty(owner->inputq)) | |
| 469 | 471 | owner->action_flags |= TIPC_MSG_EVT; |
| 470 | − owner->inputq = &l_ptr->inputq; | |
| 471 | 472 | l_ptr->next_out = NULL; |
| 472 | 473 | l_ptr->unacked_window = 0; |
| 473 | 474 | l_ptr->checkpoint = 1; |
| @@ -4400,6 +4400,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) · 4399 unmodified lines | ||
| 4400 | 4400 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
| 4401 | 4401 | return -EINVAL; |
| 4402 | 4402 | |
| 4403 | + /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT | |
| 4404 | + * as userspace might just pass through the capabilities from the IEs | |
| 4405 | + * directly, rather than enforcing this restriction and returning an | |
| 4406 | + * error in this case. | |
| 4407 | + */ | |
| 4408 | + if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) { | |
| 4409 | + params.ht_capa = NULL; | |
| 4410 | + params.vht_capa = NULL; | |
| 4411 | + } | |
| 4412 | + | |
| 4403 | 4413 | /* When you run into this, adjust the code below for the new flag */ |
| 4404 | 4414 | BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); |
| 4405 | 4415 | |
| @@ -2269,11 +2269,9 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, · 2268 unmodified lines | ||
| 2269 | 2269 | * have the xfrm_state's. We need to wait for KM to |
| 2270 | 2270 | * negotiate new SA's or bail out with error.*/ |
| 2271 | 2271 | if (net->xfrm.sysctl_larval_drop) { |
| 2272 | − dst_release(dst); | |
| 2273 | − xfrm_pols_put(pols, drop_pols); | |
| 2274 | 2272 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); |
| 2275 | − | |
| 2276 | − return ERR_PTR(-EREMOTE); | |
| 2273 | + err = -EREMOTE; | |
| 2274 | + goto error; | |
| 2277 | 2275 | } |
| 2278 | 2276 | |
| 2279 | 2277 | err = -EAGAIN; |
| @@ -2324,7 +2322,8 @@ nopol: · 44 unmodified lines | ||
| 2324 | 2322 | error: |
| 2325 | 2323 | dst_release(dst); |
| 2326 | 2324 | dropdst: |
| 2327 | − dst_release(dst_orig); | |
| 2325 | + if (!(flags & XFRM_LOOKUP_KEEP_DST_REF)) | |
| 2326 | + dst_release(dst_orig); | |
| 2328 | 2327 | xfrm_pols_put(pols, drop_pols); |
| 2329 | 2328 | return ERR_PTR(err); |
| 2330 | 2329 | } |
| @@ -2338,7 +2337,8 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, · 7 unmodified lines | ||
| 2338 | 2337 | struct sock *sk, int flags) |
| 2339 | 2338 | { |
| 2340 | 2339 | struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk, |
| 2341 | − flags | XFRM_LOOKUP_QUEUE); | |
| 2340 | + flags | XFRM_LOOKUP_QUEUE | | |
| 2341 | + XFRM_LOOKUP_KEEP_DST_REF); | |
| 2342 | 2342 | |
| 2343 | 2343 | if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) |
| 2344 | 2344 | return make_blackhole(net, dst_orig->ops->family, dst_orig); |
| @@ -1170,6 +1170,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, · 1169 unmodified lines | ||
| 1170 | 1170 | |
| 1171 | 1171 | if (info->count < 1) |
| 1172 | 1172 | return -EINVAL; |
| 1173 | + if (!*info->id.name) | |
| 1174 | + return -EINVAL; | |
| 1175 | + if (strnlen(info->id.name, sizeof(info->id.name)) >= sizeof(info->id.name)) | |
| 1176 | + return -EINVAL; | |
| 1173 | 1177 | access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : |
| 1174 | 1178 | (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| |
| 1175 | 1179 | SNDRV_CTL_ELEM_ACCESS_INACTIVE| |
| @@ -298,24 +298,24 @@ · 297 unmodified lines | ||
| 298 | 298 | */ |
| 299 | 299 | #define RX_ISOCHRONOUS 0x008 |
| 300 | 300 | |
| 301 | +/* | |
| 302 | + * Index of first quadlet to be interpreted; read/write. If > 0, that many | |
| 303 | + * quadlets at the beginning of each data block will be ignored, and all the | |
| 304 | + * audio and MIDI quadlets will follow. | |
| 305 | + */ | |
| 306 | +#define RX_SEQ_START 0x00c | |
| 307 | + | |
| 301 | 308 | /* |
| 302 | 309 | * The number of audio channels; read-only. There will be one quadlet per |
| 303 | 310 | * channel. |
| 304 | 311 | */ |
| 305 | −#define RX_NUMBER_AUDIO 0x00c | |
| 312 | +#define RX_NUMBER_AUDIO 0x010 | |
| 306 | 313 | |
| 307 | 314 | /* |
| 308 | 315 | * The number of MIDI ports, 0-8; read-only. If > 0, there will be one |
| 309 | 316 | * additional quadlet in each data block, following the audio quadlets. |
| 310 | 317 | */ |
| 311 | −#define RX_NUMBER_MIDI 0x010 | |
| 312 | − | |
| 313 | −/* | |
| 314 | − * Index of first quadlet to be interpreted; read/write. If > 0, that many | |
| 315 | − * quadlets at the beginning of each data block will be ignored, and all the | |
| 316 | − * audio and MIDI quadlets will follow. | |
| 317 | − */ | |
| 318 | −#define RX_SEQ_START 0x014 | |
| 318 | +#define RX_NUMBER_MIDI 0x014 | |
| 319 | 319 | |
| 320 | 320 | /* |
| 321 | 321 | * Names of all audio channels; read-only. Quadlets are byte-swapped. Names |
| @@ -99,9 +99,9 @@ static void dice_proc_read(struct snd_info_entry *entry, · 98 unmodified lines | ||
| 99 | 99 | } tx; |
| 100 | 100 | struct { |
| 101 | 101 | u32 iso; |
| 102 | + u32 seq_start; | |
| 102 | 103 | u32 number_audio; |
| 103 | 104 | u32 number_midi; |
| 104 | − u32 seq_start; | |
| 105 | 105 | char names[RX_NAMES_SIZE]; |
| 106 | 106 | u32 ac3_caps; |
| 107 | 107 | u32 ac3_enable; |
| @@ -204,10 +204,10 @@ static void dice_proc_read(struct snd_info_entry *entry, · 96 unmodified lines | ||
| 204 | 204 | break; |
| 205 | 205 | snd_iprintf(buffer, "rx %u:\n", stream); |
| 206 | 206 | snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso); |
| 207 | + snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); | |
| 207 | 208 | snd_iprintf(buffer, " audio channels: %u\n", |
| 208 | 209 | buf.rx.number_audio); |
| 209 | 210 | snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi); |
| 210 | − snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start); | |
| 211 | 211 | if (quadlets >= 68) { |
| 212 | 212 | dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE); |
| 213 | 213 | snd_iprintf(buffer, " names: %s\n", buf.rx.names); |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) |
| 27 | 27 | { |
| 28 | 28 | r->channels_mask = ~0uLL; |
| 29 | − r->unit = fw_unit_get(unit); | |
| 29 | + r->unit = unit; | |
| 30 | 30 | mutex_init(&r->mutex); |
| 31 | 31 | r->allocated = false; |
| 32 | 32 | |
| @@ -42,7 +42,6 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r) · 9 unmodified lines | ||
| 42 | 42 | { |
| 43 | 43 | WARN_ON(r->allocated); |
| 44 | 44 | mutex_destroy(&r->mutex); |
| 45 | − fw_unit_put(r->unit); | |
| 46 | 45 | } |
| 47 | 46 | EXPORT_SYMBOL(fw_iso_resources_destroy); |
| 48 | 47 | |
| @@ -1164,7 +1164,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, · 1163 unmodified lines | ||
| 1164 | 1164 | } |
| 1165 | 1165 | } |
| 1166 | 1166 | |
| 1167 | − if (!bus->no_response_fallback) | |
| 1167 | + if (bus->no_response_fallback) | |
| 1168 | 1168 | return -1; |
| 1169 | 1169 | |
| 1170 | 1170 | if (!chip->polling_mode && chip->poll_count < 2) { |
| @@ -687,12 +687,45 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid, · 686 unmodified lines | ||
| 687 | 687 | return val; |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | +/* is this a stereo widget or a stereo-to-mono mix? */ | |
| 691 | +static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, int dir) | |
| 692 | +{ | |
| 693 | + unsigned int wcaps = get_wcaps(codec, nid); | |
| 694 | + hda_nid_t conn; | |
| 695 | + | |
| 696 | + if (wcaps & AC_WCAP_STEREO) | |
| 697 | + return true; | |
| 698 | + if (dir != HDA_INPUT || get_wcaps_type(wcaps) != AC_WID_AUD_MIX) | |
| 699 | + return false; | |
| 700 | + if (snd_hda_get_num_conns(codec, nid) != 1) | |
| 701 | + return false; | |
| 702 | + if (snd_hda_get_connections(codec, nid, &conn, 1) < 0) | |
| 703 | + return false; | |
| 704 | + return !!(get_wcaps(codec, conn) & AC_WCAP_STEREO); | |
| 705 | +} | |
| 706 | + | |
| 690 | 707 | /* initialize the amp value (only at the first time) */ |
| 691 | 708 | static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx) |
| 692 | 709 | { |
| 693 | 710 | unsigned int caps = query_amp_caps(codec, nid, dir); |
| 694 | 711 | int val = get_amp_val_to_activate(codec, nid, dir, caps, false); |
| 695 | − snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val); | |
| 712 | + | |
| 713 | + if (is_stereo_amps(codec, nid, dir)) | |
| 714 | + snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val); | |
| 715 | + else | |
| 716 | + snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val); | |
| 717 | +} | |
| 718 | + | |
| 719 | +/* update the amp, doing in stereo or mono depending on NID */ | |
| 720 | +static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx, | |
| 721 | + unsigned int mask, unsigned int val) | |
| 722 | +{ | |
| 723 | + if (is_stereo_amps(codec, nid, dir)) | |
| 724 | + return snd_hda_codec_amp_stereo(codec, nid, dir, idx, | |
| 725 | + mask, val); | |
| 726 | + else | |
| 727 | + return snd_hda_codec_amp_update(codec, nid, 0, dir, idx, | |
| 728 | + mask, val); | |
| 696 | 729 | } |
| 697 | 730 | |
| 698 | 731 | /* calculate amp value mask we can modify; |
| @@ -732,7 +765,7 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir, · 33 unmodified lines | ||
| 732 | 765 | return; |
| 733 | 766 | |
| 734 | 767 | val &= mask; |
| 735 | − snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val); | |
| 768 | + update_amp(codec, nid, dir, idx, mask, val); | |
| 736 | 769 | } |
| 737 | 770 | |
| 738 | 771 | static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, |
| @@ -4424,13 +4457,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) · 3685 unmodified lines | ||
| 4424 | 4457 | has_amp = nid_has_mute(codec, mix, HDA_INPUT); |
| 4425 | 4458 | for (i = 0; i < nums; i++) { |
| 4426 | 4459 | if (has_amp) |
| 4427 | − snd_hda_codec_amp_stereo(codec, mix, | |
| 4428 | − HDA_INPUT, i, | |
| 4429 | − 0xff, HDA_AMP_MUTE); | |
| 4460 | + update_amp(codec, mix, HDA_INPUT, i, | |
| 4461 | + 0xff, HDA_AMP_MUTE); | |
| 4430 | 4462 | else if (nid_has_volume(codec, conn[i], HDA_OUTPUT)) |
| 4431 | − snd_hda_codec_amp_stereo(codec, conn[i], | |
| 4432 | − HDA_OUTPUT, 0, | |
| 4433 | − 0xff, HDA_AMP_MUTE); | |
| 4463 | + update_amp(codec, conn[i], HDA_OUTPUT, 0, | |
| 4464 | + 0xff, HDA_AMP_MUTE); | |
| 4434 | 4465 | } |
| 4435 | 4466 | } |
| 4436 | 4467 | |
| @@ -134,13 +134,38 @@ static void print_amp_caps(struct snd_info_buffer *buffer, · 133 unmodified lines | ||
| 134 | 134 | (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT); |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | +/* is this a stereo widget or a stereo-to-mono mix? */ | |
| 138 | +static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, | |
| 139 | + int dir, unsigned int wcaps, int indices) | |
| 140 | +{ | |
| 141 | + hda_nid_t conn; | |
| 142 | + | |
| 143 | + if (wcaps & AC_WCAP_STEREO) | |
| 144 | + return true; | |
| 145 | + /* check for a stereo-to-mono mix; it must be: | |
| 146 | + * only a single connection, only for input, and only a mixer widget | |
| 147 | + */ | |
| 148 | + if (indices != 1 || dir != HDA_INPUT || | |
| 149 | + get_wcaps_type(wcaps) != AC_WID_AUD_MIX) | |
| 150 | + return false; | |
| 151 | + | |
| 152 | + if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0) | |
| 153 | + return false; | |
| 154 | + /* the connection source is a stereo? */ | |
| 155 | + wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP); | |
| 156 | + return !!(wcaps & AC_WCAP_STEREO); | |
| 157 | +} | |
| 158 | + | |
| 137 | 159 | static void print_amp_vals(struct snd_info_buffer *buffer, |
| 138 | 160 | struct hda_codec *codec, hda_nid_t nid, |
| 139 | − int dir, int stereo, int indices) | |
| 161 | + int dir, unsigned int wcaps, int indices) | |
| 140 | 162 | { |
| 141 | 163 | unsigned int val; |
| 164 | + bool stereo; | |
| 142 | 165 | int i; |
| 143 | 166 | |
| 167 | + stereo = is_stereo_amps(codec, nid, dir, wcaps, indices); | |
| 168 | + | |
| 144 | 169 | dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; |
| 145 | 170 | for (i = 0; i < indices; i++) { |
| 146 | 171 | snd_iprintf(buffer, " ["); |
| @@ -757,12 +782,10 @@ static void print_codec_info(struct snd_info_entry *entry, · 610 unmodified lines | ||
| 757 | 782 | (codec->single_adc_amp && |
| 758 | 783 | wid_type == AC_WID_AUD_IN)) |
| 759 | 784 | print_amp_vals(buffer, codec, nid, HDA_INPUT, |
| 760 | − wid_caps & AC_WCAP_STEREO, | |
| 761 | − 1); | |
| 785 | + wid_caps, 1); | |
| 762 | 786 | else |
| 763 | 787 | print_amp_vals(buffer, codec, nid, HDA_INPUT, |
| 764 | − wid_caps & AC_WCAP_STEREO, | |
| 765 | − conn_len); | |
| 788 | + wid_caps, conn_len); | |
| 766 | 789 | } |
| 767 | 790 | if (wid_caps & AC_WCAP_OUT_AMP) { |
| 768 | 791 | snd_iprintf(buffer, " Amp-Out caps: "); |
| @@ -771,11 +794,10 @@ static void print_codec_info(struct snd_info_entry *entry, · 2 unmodified lines | ||
| 771 | 794 | if (wid_type == AC_WID_PIN && |
| 772 | 795 | codec->pin_amp_workaround) |
| 773 | 796 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, |
| 774 | − wid_caps & AC_WCAP_STEREO, | |
| 775 | − conn_len); | |
| 797 | + wid_caps, conn_len); | |
| 776 | 798 | else |
| 777 | 799 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, |
| 778 | − wid_caps & AC_WCAP_STEREO, 1); | |
| 800 | + wid_caps, 1); | |
| 779 | 801 | } |
| 780 | 802 | |
| 781 | 803 | switch (wid_type) { |
| @@ -393,6 +393,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { · 392 unmodified lines | ||
| 393 | 393 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), |
| 394 | 394 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
| 395 | 395 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
| 396 | + SND_PCI_QUIRK(0x106b, 0x5600, "MacBookAir 5,2", CS420X_MBP81), | |
| 396 | 397 | SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), |
| 397 | 398 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), |
| 398 | 399 | {} /* terminator */ |
| @@ -584,6 +585,7 @@ static int patch_cs420x(struct hda_codec *codec) · 185 unmodified lines | ||
| 584 | 585 | return -ENOMEM; |
| 585 | 586 | |
| 586 | 587 | spec->gen.automute_hook = cs_automute; |
| 588 | + codec->single_adc_amp = 1; | |
| 587 | 589 | |
| 588 | 590 | snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl, |
| 589 | 591 | cs420x_fixups); |
| @@ -223,6 +223,7 @@ enum { · 222 unmodified lines | ||
| 223 | 223 | CXT_PINCFG_LENOVO_TP410, |
| 224 | 224 | CXT_PINCFG_LEMOTE_A1004, |
| 225 | 225 | CXT_PINCFG_LEMOTE_A1205, |
| 226 | + CXT_PINCFG_COMPAQ_CQ60, | |
| 226 | 227 | CXT_FIXUP_STEREO_DMIC, |
| 227 | 228 | CXT_FIXUP_INC_MIC_BOOST, |
| 228 | 229 | CXT_FIXUP_HEADPHONE_MIC_PIN, |
| @@ -660,6 +661,15 @@ static const struct hda_fixup cxt_fixups[] = { · 431 unmodified lines | ||
| 660 | 661 | .type = HDA_FIXUP_PINS, |
| 661 | 662 | .v.pins = cxt_pincfg_lemote, |
| 662 | 663 | }, |
| 664 | + [CXT_PINCFG_COMPAQ_CQ60] = { | |
| 665 | + .type = HDA_FIXUP_PINS, | |
| 666 | + .v.pins = (const struct hda_pintbl[]) { | |
| 667 | + /* 0x17 was falsely set up as a mic, it should 0x1d */ | |
| 668 | + { 0x17, 0x400001f0 }, | |
| 669 | + { 0x1d, 0x97a70120 }, | |
| 670 | + { } | |
| 671 | + } | |
| 672 | + }, | |
| 663 | 673 | [CXT_FIXUP_STEREO_DMIC] = { |
| 664 | 674 | .type = HDA_FIXUP_FUNC, |
| 665 | 675 | .v.func = cxt_fixup_stereo_dmic, |
| @@ -769,6 +779,7 @@ static const struct hda_model_fixup cxt5047_fixup_models[] = { · 103 unmodified lines | ||
| 769 | 779 | }; |
| 770 | 780 | |
| 771 | 781 | static const struct snd_pci_quirk cxt5051_fixups[] = { |
| 782 | + SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60), | |
| 772 | 783 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), |
| 773 | 784 | {} |
| 774 | 785 | }; |
| @@ -317,7 +317,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, · 316 unmodified lines | ||
| 317 | 317 | { |
| 318 | 318 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 319 | 319 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
| 320 | − unsigned int deemph = ucontrol->value.enumerated.item[0]; | |
| 320 | + unsigned int deemph = ucontrol->value.integer.value[0]; | |
| 321 | 321 | |
| 322 | 322 | if (deemph > 1) |
| 323 | 323 | return -EINVAL; |
| @@ -333,7 +333,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, · 9 unmodified lines | ||
| 333 | 333 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 334 | 334 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
| 335 | 335 | |
| 336 | − ucontrol->value.enumerated.item[0] = adav80x->deemph; | |
| 336 | + ucontrol->value.integer.value[0] = adav80x->deemph; | |
| 337 | 337 | return 0; |
| 338 | 338 | }; |
| 339 | 339 | |
| @@ -76,7 +76,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, · 75 unmodified lines | ||
| 76 | 76 | { |
| 77 | 77 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 78 | 78 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); |
| 79 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 79 | + int deemph = ucontrol->value.integer.value[0]; | |
| 80 | 80 | |
| 81 | 81 | if (deemph > 1) |
| 82 | 82 | return -EINVAL; |
| @@ -92,7 +92,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, · 9 unmodified lines | ||
| 92 | 92 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 93 | 93 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); |
| 94 | 94 | |
| 95 | − ucontrol->value.enumerated.item[0] = ak4641->deemph; | |
| 95 | + ucontrol->value.integer.value[0] = ak4641->deemph; | |
| 96 | 96 | return 0; |
| 97 | 97 | }; |
| 98 | 98 | |
| @@ -343,25 +343,25 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = { · 342 unmodified lines | ||
| 343 | 343 | }; |
| 344 | 344 | |
| 345 | 345 | static const struct snd_soc_dapm_route ak4671_intercon[] = { |
| 346 | − {"DAC Left", "NULL", "PMPLL"}, | |
| 347 | − {"DAC Right", "NULL", "PMPLL"}, | |
| 348 | − {"ADC Left", "NULL", "PMPLL"}, | |
| 349 | − {"ADC Right", "NULL", "PMPLL"}, | |
| 346 | + {"DAC Left", NULL, "PMPLL"}, | |
| 347 | + {"DAC Right", NULL, "PMPLL"}, | |
| 348 | + {"ADC Left", NULL, "PMPLL"}, | |
| 349 | + {"ADC Right", NULL, "PMPLL"}, | |
| 350 | 350 | |
| 351 | 351 | /* Outputs */ |
| 352 | − {"LOUT1", "NULL", "LOUT1 Mixer"}, | |
| 353 | − {"ROUT1", "NULL", "ROUT1 Mixer"}, | |
| 354 | − {"LOUT2", "NULL", "LOUT2 Mix Amp"}, | |
| 355 | − {"ROUT2", "NULL", "ROUT2 Mix Amp"}, | |
| 356 | − {"LOUT3", "NULL", "LOUT3 Mixer"}, | |
| 357 | − {"ROUT3", "NULL", "ROUT3 Mixer"}, | |
| 352 | + {"LOUT1", NULL, "LOUT1 Mixer"}, | |
| 353 | + {"ROUT1", NULL, "ROUT1 Mixer"}, | |
| 354 | + {"LOUT2", NULL, "LOUT2 Mix Amp"}, | |
| 355 | + {"ROUT2", NULL, "ROUT2 Mix Amp"}, | |
| 356 | + {"LOUT3", NULL, "LOUT3 Mixer"}, | |
| 357 | + {"ROUT3", NULL, "ROUT3 Mixer"}, | |
| 358 | 358 | |
| 359 | 359 | {"LOUT1 Mixer", "DACL", "DAC Left"}, |
| 360 | 360 | {"ROUT1 Mixer", "DACR", "DAC Right"}, |
| 361 | 361 | {"LOUT2 Mixer", "DACHL", "DAC Left"}, |
| 362 | 362 | {"ROUT2 Mixer", "DACHR", "DAC Right"}, |
| 363 | − {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"}, | |
| 364 | − {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"}, | |
| 363 | + {"LOUT2 Mix Amp", NULL, "LOUT2 Mixer"}, | |
| 364 | + {"ROUT2 Mix Amp", NULL, "ROUT2 Mixer"}, | |
| 365 | 365 | {"LOUT3 Mixer", "DACSL", "DAC Left"}, |
| 366 | 366 | {"ROUT3 Mixer", "DACSR", "DAC Right"}, |
| 367 | 367 | |
| @@ -381,18 +381,18 @@ static const struct snd_soc_dapm_route ak4671_intercon[] = { · 13 unmodified lines | ||
| 381 | 381 | {"LIN2", NULL, "Mic Bias"}, |
| 382 | 382 | {"RIN2", NULL, "Mic Bias"}, |
| 383 | 383 | |
| 384 | − {"ADC Left", "NULL", "LIN MUX"}, | |
| 385 | − {"ADC Right", "NULL", "RIN MUX"}, | |
| 384 | + {"ADC Left", NULL, "LIN MUX"}, | |
| 385 | + {"ADC Right", NULL, "RIN MUX"}, | |
| 386 | 386 | |
| 387 | 387 | /* Analog Loops */ |
| 388 | − {"LIN1 Mixing Circuit", "NULL", "LIN1"}, | |
| 389 | − {"RIN1 Mixing Circuit", "NULL", "RIN1"}, | |
| 390 | − {"LIN2 Mixing Circuit", "NULL", "LIN2"}, | |
| 391 | − {"RIN2 Mixing Circuit", "NULL", "RIN2"}, | |
| 392 | − {"LIN3 Mixing Circuit", "NULL", "LIN3"}, | |
| 393 | − {"RIN3 Mixing Circuit", "NULL", "RIN3"}, | |
| 394 | − {"LIN4 Mixing Circuit", "NULL", "LIN4"}, | |
| 395 | − {"RIN4 Mixing Circuit", "NULL", "RIN4"}, | |
| 388 | + {"LIN1 Mixing Circuit", NULL, "LIN1"}, | |
| 389 | + {"RIN1 Mixing Circuit", NULL, "RIN1"}, | |
| 390 | + {"LIN2 Mixing Circuit", NULL, "LIN2"}, | |
| 391 | + {"RIN2 Mixing Circuit", NULL, "RIN2"}, | |
| 392 | + {"LIN3 Mixing Circuit", NULL, "LIN3"}, | |
| 393 | + {"RIN3 Mixing Circuit", NULL, "RIN3"}, | |
| 394 | + {"LIN4 Mixing Circuit", NULL, "LIN4"}, | |
| 395 | + {"RIN4 Mixing Circuit", NULL, "RIN4"}, | |
| 396 | 396 | |
| 397 | 397 | {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"}, |
| 398 | 398 | {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"}, |
| @@ -286,7 +286,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, · 285 unmodified lines | ||
| 286 | 286 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 287 | 287 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
| 288 | 288 | |
| 289 | − ucontrol->value.enumerated.item[0] = cs4271->deemph; | |
| 289 | + ucontrol->value.integer.value[0] = cs4271->deemph; | |
| 290 | 290 | return 0; |
| 291 | 291 | } |
| 292 | 292 | |
| @@ -296,7 +296,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 296 | 296 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 297 | 297 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
| 298 | 298 | |
| 299 | − cs4271->deemph = ucontrol->value.enumerated.item[0]; | |
| 299 | + cs4271->deemph = ucontrol->value.integer.value[0]; | |
| 300 | 300 | return cs4271_set_deemph(codec); |
| 301 | 301 | } |
| 302 | 302 | |
| @@ -876,11 +876,11 @@ static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { · 875 unmodified lines | ||
| 876 | 876 | |
| 877 | 877 | static const struct snd_soc_dapm_route da732x_dapm_routes[] = { |
| 878 | 878 | /* Inputs */ |
| 879 | − {"AUX1L PGA", "NULL", "AUX1L"}, | |
| 880 | − {"AUX1R PGA", "NULL", "AUX1R"}, | |
| 879 | + {"AUX1L PGA", NULL, "AUX1L"}, | |
| 880 | + {"AUX1R PGA", NULL, "AUX1R"}, | |
| 881 | 881 | {"MIC1 PGA", NULL, "MIC1"}, |
| 882 | − {"MIC2 PGA", "NULL", "MIC2"}, | |
| 883 | − {"MIC3 PGA", "NULL", "MIC3"}, | |
| 882 | + {"MIC2 PGA", NULL, "MIC2"}, | |
| 883 | + {"MIC3 PGA", NULL, "MIC3"}, | |
| 884 | 884 | |
| 885 | 885 | /* Capture Path */ |
| 886 | 886 | {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, |
| @@ -120,7 +120,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol, · 119 unmodified lines | ||
| 120 | 120 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 121 | 121 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); |
| 122 | 122 | |
| 123 | − ucontrol->value.enumerated.item[0] = es8328->deemph; | |
| 123 | + ucontrol->value.integer.value[0] = es8328->deemph; | |
| 124 | 124 | return 0; |
| 125 | 125 | } |
| 126 | 126 | |
| @@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol, · 2 unmodified lines | ||
| 129 | 129 | { |
| 130 | 130 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 131 | 131 | struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); |
| 132 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 132 | + int deemph = ucontrol->value.integer.value[0]; | |
| 133 | 133 | int ret; |
| 134 | 134 | |
| 135 | 135 | if (deemph > 1) |
| @@ -118,7 +118,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, · 117 unmodified lines | ||
| 118 | 118 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 119 | 119 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
| 120 | 120 | |
| 121 | − ucontrol->value.enumerated.item[0] = priv->deemph; | |
| 121 | + ucontrol->value.integer.value[0] = priv->deemph; | |
| 122 | 122 | |
| 123 | 123 | return 0; |
| 124 | 124 | } |
| @@ -129,7 +129,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, · 4 unmodified lines | ||
| 129 | 129 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 130 | 130 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
| 131 | 131 | |
| 132 | − priv->deemph = ucontrol->value.enumerated.item[0]; | |
| 132 | + priv->deemph = ucontrol->value.integer.value[0]; | |
| 133 | 133 | |
| 134 | 134 | return pcm1681_set_deemph(codec); |
| 135 | 135 | } |
| @@ -1198,7 +1198,7 @@ static struct dmi_system_id dmi_dell_dino[] = { · 1197 unmodified lines | ||
| 1198 | 1198 | .ident = "Dell Dino", |
| 1199 | 1199 | .matches = { |
| 1200 | 1200 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 1201 | − DMI_MATCH(DMI_BOARD_NAME, "0144P8") | |
| 1201 | + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343") | |
| 1202 | 1202 | } |
| 1203 | 1203 | }, |
| 1204 | 1204 | { } |
| @@ -1151,13 +1151,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) · 1150 unmodified lines | ||
| 1151 | 1151 | /* Enable VDDC charge pump */ |
| 1152 | 1152 | ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; |
| 1153 | 1153 | } else if (vddio >= 3100 && vdda >= 3100) { |
| 1154 | − /* | |
| 1155 | − * if vddio and vddd > 3.1v, | |
| 1156 | − * charge pump should be clean before set ana_pwr | |
| 1157 | − */ | |
| 1158 | − snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, | |
| 1159 | − SGTL5000_VDDC_CHRGPMP_POWERUP, 0); | |
| 1160 | − | |
| 1154 | + ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; | |
| 1161 | 1155 | /* VDDC use VDDIO rail */ |
| 1162 | 1156 | lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; |
| 1163 | 1157 | lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << |
| @@ -538,8 +538,8 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = { · 537 unmodified lines | ||
| 538 | 538 | /* speaker map */ |
| 539 | 539 | { "IHFOUTL", NULL, "Speaker Rail"}, |
| 540 | 540 | { "IHFOUTR", NULL, "Speaker Rail"}, |
| 541 | − { "IHFOUTL", "NULL", "Speaker Left Playback"}, | |
| 542 | − { "IHFOUTR", "NULL", "Speaker Right Playback"}, | |
| 541 | + { "IHFOUTL", NULL, "Speaker Left Playback"}, | |
| 542 | + { "IHFOUTR", NULL, "Speaker Right Playback"}, | |
| 543 | 543 | { "Speaker Left Playback", NULL, "Speaker Left Filter"}, |
| 544 | 544 | { "Speaker Right Playback", NULL, "Speaker Right Filter"}, |
| 545 | 545 | { "Speaker Left Filter", NULL, "IHFDAC Left"}, |
| @@ -281,7 +281,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, · 280 unmodified lines | ||
| 281 | 281 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 282 | 282 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); |
| 283 | 283 | |
| 284 | − ucontrol->value.enumerated.item[0] = priv->deemph; | |
| 284 | + ucontrol->value.integer.value[0] = priv->deemph; | |
| 285 | 285 | |
| 286 | 286 | return 0; |
| 287 | 287 | } |
| @@ -292,7 +292,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, · 4 unmodified lines | ||
| 292 | 292 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 293 | 293 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); |
| 294 | 294 | |
| 295 | − priv->deemph = ucontrol->value.enumerated.item[0]; | |
| 295 | + priv->deemph = ucontrol->value.integer.value[0]; | |
| 296 | 296 | |
| 297 | 297 | return tas5086_set_deemph(codec); |
| 298 | 298 | } |
| @@ -610,7 +610,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, · 609 unmodified lines | ||
| 610 | 610 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 611 | 611 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
| 612 | 612 | |
| 613 | − ucontrol->value.enumerated.item[0] = wm2000->anc_active; | |
| 613 | + ucontrol->value.integer.value[0] = wm2000->anc_active; | |
| 614 | 614 | |
| 615 | 615 | return 0; |
| 616 | 616 | } |
| @@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 620 | 620 | { |
| 621 | 621 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 622 | 622 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
| 623 | − int anc_active = ucontrol->value.enumerated.item[0]; | |
| 623 | + int anc_active = ucontrol->value.integer.value[0]; | |
| 624 | 624 | int ret; |
| 625 | 625 | |
| 626 | 626 | if (anc_active > 1) |
| @@ -643,7 +643,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, · 16 unmodified lines | ||
| 643 | 643 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 644 | 644 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
| 645 | 645 | |
| 646 | − ucontrol->value.enumerated.item[0] = wm2000->spk_ena; | |
| 646 | + ucontrol->value.integer.value[0] = wm2000->spk_ena; | |
| 647 | 647 | |
| 648 | 648 | return 0; |
| 649 | 649 | } |
| @@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 653 | 653 | { |
| 654 | 654 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 655 | 655 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
| 656 | − int val = ucontrol->value.enumerated.item[0]; | |
| 656 | + int val = ucontrol->value.integer.value[0]; | |
| 657 | 657 | int ret; |
| 658 | 658 | |
| 659 | 659 | if (val > 1) |
| @@ -125,7 +125,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, · 124 unmodified lines | ||
| 125 | 125 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 126 | 126 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 127 | 127 | |
| 128 | − ucontrol->value.enumerated.item[0] = wm8731->deemph; | |
| 128 | + ucontrol->value.integer.value[0] = wm8731->deemph; | |
| 129 | 129 | |
| 130 | 130 | return 0; |
| 131 | 131 | } |
| @@ -135,7 +135,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 135 | 135 | { |
| 136 | 136 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 137 | 137 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 138 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 138 | + int deemph = ucontrol->value.integer.value[0]; | |
| 139 | 139 | int ret = 0; |
| 140 | 140 | |
| 141 | 141 | if (deemph > 1) |
| @@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, · 441 unmodified lines | ||
| 442 | 442 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 443 | 443 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 444 | 444 | |
| 445 | − ucontrol->value.enumerated.item[0] = wm8903->deemph; | |
| 445 | + ucontrol->value.integer.value[0] = wm8903->deemph; | |
| 446 | 446 | |
| 447 | 447 | return 0; |
| 448 | 448 | } |
| @@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, · 3 unmodified lines | ||
| 452 | 452 | { |
| 453 | 453 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 454 | 454 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 455 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 455 | + int deemph = ucontrol->value.integer.value[0]; | |
| 456 | 456 | int ret = 0; |
| 457 | 457 | |
| 458 | 458 | if (deemph > 1) |
| @@ -525,7 +525,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, · 524 unmodified lines | ||
| 525 | 525 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 526 | 526 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 527 | 527 | |
| 528 | − ucontrol->value.enumerated.item[0] = wm8904->deemph; | |
| 528 | + ucontrol->value.integer.value[0] = wm8904->deemph; | |
| 529 | 529 | return 0; |
| 530 | 530 | } |
| 531 | 531 | |
| @@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, · 2 unmodified lines | ||
| 534 | 534 | { |
| 535 | 535 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 536 | 536 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 537 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 537 | + int deemph = ucontrol->value.integer.value[0]; | |
| 538 | 538 | |
| 539 | 539 | if (deemph > 1) |
| 540 | 540 | return -EINVAL; |
| @@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, · 392 unmodified lines | ||
| 393 | 393 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 394 | 394 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
| 395 | 395 | |
| 396 | − ucontrol->value.enumerated.item[0] = wm8955->deemph; | |
| 396 | + ucontrol->value.integer.value[0] = wm8955->deemph; | |
| 397 | 397 | return 0; |
| 398 | 398 | } |
| 399 | 399 | |
| @@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, · 2 unmodified lines | ||
| 402 | 402 | { |
| 403 | 403 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 404 | 404 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
| 405 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 405 | + int deemph = ucontrol->value.integer.value[0]; | |
| 406 | 406 | |
| 407 | 407 | if (deemph > 1) |
| 408 | 408 | return -EINVAL; |
| @@ -184,7 +184,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, · 183 unmodified lines | ||
| 184 | 184 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 185 | 185 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
| 186 | 186 | |
| 187 | − ucontrol->value.enumerated.item[0] = wm8960->deemph; | |
| 187 | + ucontrol->value.integer.value[0] = wm8960->deemph; | |
| 188 | 188 | return 0; |
| 189 | 189 | } |
| 190 | 190 | |
| @@ -193,7 +193,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, · 2 unmodified lines | ||
| 193 | 193 | { |
| 194 | 194 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
| 195 | 195 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
| 196 | − int deemph = ucontrol->value.enumerated.item[0]; | |
| 196 | + int deemph = ucontrol->value.integer.value[0]; | |
| 197 | 197 | |
| 198 | 198 | if (deemph > 1) |
| 199 | 199 | return -EINVAL; |
| @@ -180,7 +180,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, · 179 unmodified lines | ||
| 180 | 180 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); |
| 181 | 181 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); |
| 182 | 182 | struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); |
| 183 | − unsigned int val = ucontrol->value.enumerated.item[0]; | |
| 183 | + unsigned int val = ucontrol->value.integer.value[0]; | |
| 184 | 184 | struct soc_mixer_control *mc = |
| 185 | 185 | (struct soc_mixer_control *)kcontrol->private_value; |
| 186 | 186 | unsigned int mixer, mask, shift, old; |
| @@ -193,7 +193,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, · 6 unmodified lines | ||
| 193 | 193 | |
| 194 | 194 | mutex_lock(&wm9712->lock); |
| 195 | 195 | old = wm9712->hp_mixer[mixer]; |
| 196 | − if (ucontrol->value.enumerated.item[0]) | |
| 196 | + if (ucontrol->value.integer.value[0]) | |
| 197 | 197 | wm9712->hp_mixer[mixer] |= mask; |
| 198 | 198 | else |
| 199 | 199 | wm9712->hp_mixer[mixer] &= ~mask; |
| @@ -231,7 +231,7 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, · 31 unmodified lines | ||
| 231 | 231 | mixer = mc->shift >> 8; |
| 232 | 232 | shift = mc->shift & 0xff; |
| 233 | 233 | |
| 234 | − ucontrol->value.enumerated.item[0] = | |
| 234 | + ucontrol->value.integer.value[0] = | |
| 235 | 235 | (wm9712->hp_mixer[mixer] >> shift) & 1; |
| 236 | 236 | |
| 237 | 237 | return 0; |
| @@ -255,7 +255,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, · 254 unmodified lines | ||
| 255 | 255 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); |
| 256 | 256 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); |
| 257 | 257 | struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); |
| 258 | − unsigned int val = ucontrol->value.enumerated.item[0]; | |
| 258 | + unsigned int val = ucontrol->value.integer.value[0]; | |
| 259 | 259 | struct soc_mixer_control *mc = |
| 260 | 260 | (struct soc_mixer_control *)kcontrol->private_value; |
| 261 | 261 | unsigned int mixer, mask, shift, old; |
| @@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, · 6 unmodified lines | ||
| 268 | 268 | |
| 269 | 269 | mutex_lock(&wm9713->lock); |
| 270 | 270 | old = wm9713->hp_mixer[mixer]; |
| 271 | − if (ucontrol->value.enumerated.item[0]) | |
| 271 | + if (ucontrol->value.integer.value[0]) | |
| 272 | 272 | wm9713->hp_mixer[mixer] |= mask; |
| 273 | 273 | else |
| 274 | 274 | wm9713->hp_mixer[mixer] &= ~mask; |
| @@ -306,7 +306,7 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, · 31 unmodified lines | ||
| 306 | 306 | mixer = mc->shift >> 8; |
| 307 | 307 | shift = mc->shift & 0xff; |
| 308 | 308 | |
| 309 | − ucontrol->value.enumerated.item[0] = | |
| 309 | + ucontrol->value.integer.value[0] = | |
| 310 | 310 | (wm9713->hp_mixer[mixer] >> shift) & 1; |
| 311 | 311 | |
| 312 | 312 | return 0; |
| @@ -1049,7 +1049,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, · 1048 unmodified lines | ||
| 1049 | 1049 | enum spdif_txrate index, bool round) |
| 1050 | 1050 | { |
| 1051 | 1051 | const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 }; |
| 1052 | − bool is_sysclk = clk == spdif_priv->sysclk; | |
| 1052 | + bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk); | |
| 1053 | 1053 | u64 rate_ideal, rate_actual, sub; |
| 1054 | 1054 | u32 sysclk_dfmin, sysclk_dfmax; |
| 1055 | 1055 | u32 txclk_df, sysclk_df, arate; |
| @@ -1143,7 +1143,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, · 87 unmodified lines | ||
| 1143 | 1143 | spdif_priv->txclk_src[index], rate[index]); |
| 1144 | 1144 | dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n", |
| 1145 | 1145 | spdif_priv->txclk_df[index], rate[index]); |
| 1146 | − if (spdif_priv->txclk[index] == spdif_priv->sysclk) | |
| 1146 | + if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk)) | |
| 1147 | 1147 | dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n", |
| 1148 | 1148 | spdif_priv->sysclk_df[index], rate[index]); |
| 1149 | 1149 | dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n", |
| @@ -603,7 +603,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, · 602 unmodified lines | ||
| 603 | 603 | factor = (div2 + 1) * (7 * psr + 1) * 2; |
| 604 | 604 | |
| 605 | 605 | for (i = 0; i < 255; i++) { |
| 606 | − tmprate = freq * factor * (i + 2); | |
| 606 | + tmprate = freq * factor * (i + 1); | |
| 607 | 607 | |
| 608 | 608 | if (baudclk_is_used) |
| 609 | 609 | clkrate = clk_get_rate(ssi_private->baudclk); |
| @@ -1227,7 +1227,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, · 617 unmodified lines | ||
| 1227 | 1227 | ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; |
| 1228 | 1228 | ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; |
| 1229 | 1229 | |
| 1230 | − ret = !of_property_read_u32_array(np, "dmas", dmas, 4); | |
| 1230 | + ret = of_property_read_u32_array(np, "dmas", dmas, 4); | |
| 1231 | 1231 | if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { |
| 1232 | 1232 | ssi_private->use_dual_fifo = true; |
| 1233 | 1233 | /* When using dual fifo mode, we need to keep watermark |
| @@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw) · 206 unmodified lines | ||
| 207 | 207 | module = (void *)module + sizeof(*module) + module->mod_size; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | − /* allocate scratch mem regions */ | |
| 211 | − sst_block_alloc_scratch(dsp); | |
| 212 | − | |
| 213 | 210 | return 0; |
| 214 | 211 | } |
| 215 | 212 | |
| @@ -1732,6 +1732,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw) · 1731 unmodified lines | ||
| 1732 | 1732 | int sst_hsw_dsp_load(struct sst_hsw *hsw) |
| 1733 | 1733 | { |
| 1734 | 1734 | struct sst_dsp *dsp = hsw->dsp; |
| 1735 | + struct sst_fw *sst_fw, *t; | |
| 1735 | 1736 | int ret; |
| 1736 | 1737 | |
| 1737 | 1738 | dev_dbg(hsw->dev, "loading audio DSP...."); |
| @@ -1748,12 +1749,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw) · 10 unmodified lines | ||
| 1748 | 1749 | return ret; |
| 1749 | 1750 | } |
| 1750 | 1751 | |
| 1751 | − ret = sst_fw_reload(hsw->sst_fw); | |
| 1752 | − if (ret < 0) { | |
| 1753 | − dev_err(hsw->dev, "error: SST FW reload failed\n"); | |
| 1754 | − sst_dsp_dma_put_channel(dsp); | |
| 1755 | − return -ENOMEM; | |
| 1752 | + list_for_each_entry_safe_reverse(sst_fw, t, &dsp->fw_list, list) { | |
| 1753 | + ret = sst_fw_reload(sst_fw); | |
| 1754 | + if (ret < 0) { | |
| 1755 | + dev_err(hsw->dev, "error: SST FW reload failed\n"); | |
| 1756 | + sst_dsp_dma_put_channel(dsp); | |
| 1757 | + return -ENOMEM; | |
| 1758 | + } | |
| 1756 | 1759 | } |
| 1760 | + ret = sst_block_alloc_scratch(hsw->dsp); | |
| 1761 | + if (ret < 0) | |
| 1762 | + return -EINVAL; | |
| 1757 | 1763 | |
| 1758 | 1764 | sst_dsp_dma_put_channel(dsp); |
| 1759 | 1765 | return 0; |
| @@ -1809,12 +1815,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw) · 49 unmodified lines | ||
| 1809 | 1815 | |
| 1810 | 1816 | int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw) |
| 1811 | 1817 | { |
| 1812 | − sst_fw_unload(hsw->sst_fw); | |
| 1813 | − sst_block_free_scratch(hsw->dsp); | |
| 1818 | + struct sst_fw *sst_fw, *t; | |
| 1819 | + struct sst_dsp *dsp = hsw->dsp; | |
| 1820 | + | |
| 1821 | + list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) { | |
| 1822 | + sst_fw_unload(sst_fw); | |
| 1823 | + } | |
| 1824 | + sst_block_free_scratch(dsp); | |
| 1814 | 1825 | |
| 1815 | 1826 | hsw->boot_complete = false; |
| 1816 | 1827 | |
| 1817 | − sst_dsp_sleep(hsw->dsp); | |
| 1828 | + sst_dsp_sleep(dsp); | |
| 1818 | 1829 | |
| 1819 | 1830 | return 0; |
| 1820 | 1831 | } |
| @@ -1943,6 +1954,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) · 122 unmodified lines | ||
| 1943 | 1954 | goto fw_err; |
| 1944 | 1955 | } |
| 1945 | 1956 | |
| 1957 | + /* allocate scratch mem regions */ | |
| 1958 | + ret = sst_block_alloc_scratch(hsw->dsp); | |
| 1959 | + if (ret < 0) | |
| 1960 | + goto boot_err; | |
| 1961 | + | |
| 1946 | 1962 | /* wait for DSP boot completion */ |
| 1947 | 1963 | sst_dsp_boot(hsw->dsp); |
| 1948 | 1964 | ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, |
| @@ -579,7 +579,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) · 578 unmodified lines | ||
| 579 | 579 | if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) |
| 580 | 580 | return -EPROBE_DEFER; |
| 581 | 581 | } else { |
| 582 | − if (priv->extclk == priv->clk) { | |
| 582 | + if (clk_is_match(priv->extclk, priv->clk)) { | |
| 583 | 583 | devm_clk_put(&pdev->dev, priv->extclk); |
| 584 | 584 | priv->extclk = ERR_PTR(-EINVAL); |
| 585 | 585 | } else { |
| @@ -347,6 +347,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, · 346 unmodified lines | ||
| 347 | 347 | if (!buf) |
| 348 | 348 | return -ENOMEM; |
| 349 | 349 | |
| 350 | + mutex_lock(&client_mutex); | |
| 351 | + | |
| 350 | 352 | list_for_each_entry(codec, &codec_list, list) { |
| 351 | 353 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", |
| 352 | 354 | codec->component.name); |
| @@ -358,6 +360,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, · 5 unmodified lines | ||
| 358 | 360 | } |
| 359 | 361 | } |
| 360 | 362 | |
| 363 | + mutex_unlock(&client_mutex); | |
| 364 | + | |
| 361 | 365 | if (ret >= 0) |
| 362 | 366 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); |
| 363 | 367 | |
| @@ -382,6 +386,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, · 18 unmodified lines | ||
| 382 | 386 | if (!buf) |
| 383 | 387 | return -ENOMEM; |
| 384 | 388 | |
| 389 | + mutex_lock(&client_mutex); | |
| 390 | + | |
| 385 | 391 | list_for_each_entry(component, &component_list, list) { |
| 386 | 392 | list_for_each_entry(dai, &component->dai_list, list) { |
| 387 | 393 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", |
| @@ -395,6 +401,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, · 7 unmodified lines | ||
| 395 | 401 | } |
| 396 | 402 | } |
| 397 | 403 | |
| 404 | + mutex_unlock(&client_mutex); | |
| 405 | + | |
| 398 | 406 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); |
| 399 | 407 | |
| 400 | 408 | kfree(buf); |
| @@ -418,6 +426,8 @@ static ssize_t platform_list_read_file(struct file *file, · 17 unmodified lines | ||
| 418 | 426 | if (!buf) |
| 419 | 427 | return -ENOMEM; |
| 420 | 428 | |
| 429 | + mutex_lock(&client_mutex); | |
| 430 | + | |
| 421 | 431 | list_for_each_entry(platform, &platform_list, list) { |
| 422 | 432 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", |
| 423 | 433 | platform->component.name); |
| @@ -429,6 +439,8 @@ static ssize_t platform_list_read_file(struct file *file, · 5 unmodified lines | ||
| 429 | 439 | } |
| 430 | 440 | } |
| 431 | 441 | |
| 442 | + mutex_unlock(&client_mutex); | |
| 443 | + | |
| 432 | 444 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); |
| 433 | 445 | |
| 434 | 446 | kfree(buf); |
| @@ -836,6 +848,8 @@ static struct snd_soc_component *soc_find_component( · 401 unmodified lines | ||
| 836 | 848 | { |
| 837 | 849 | struct snd_soc_component *component; |
| 838 | 850 | |
| 851 | + lockdep_assert_held(&client_mutex); | |
| 852 | + | |
| 839 | 853 | list_for_each_entry(component, &component_list, list) { |
| 840 | 854 | if (of_node) { |
| 841 | 855 | if (component->dev->of_node == of_node) |
| @@ -854,6 +868,8 @@ static struct snd_soc_dai *snd_soc_find_dai( · 12 unmodified lines | ||
| 854 | 868 | struct snd_soc_component *component; |
| 855 | 869 | struct snd_soc_dai *dai; |
| 856 | 870 | |
| 871 | + lockdep_assert_held(&client_mutex); | |
| 872 | + | |
| 857 | 873 | /* Find CPU DAI from registered DAIs*/ |
| 858 | 874 | list_for_each_entry(component, &component_list, list) { |
| 859 | 875 | if (dlc->of_node && component->dev->of_node != dlc->of_node) |
| @@ -1508,6 +1524,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) · 648 unmodified lines | ||
| 1508 | 1524 | struct snd_soc_codec *codec; |
| 1509 | 1525 | int ret, i, order; |
| 1510 | 1526 | |
| 1527 | + mutex_lock(&client_mutex); | |
| 1511 | 1528 | mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); |
| 1512 | 1529 | |
| 1513 | 1530 | /* bind DAIs */ |
| @@ -1662,6 +1679,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) · 148 unmodified lines | ||
| 1662 | 1679 | card->instantiated = 1; |
| 1663 | 1680 | snd_soc_dapm_sync(&card->dapm); |
| 1664 | 1681 | mutex_unlock(&card->mutex); |
| 1682 | + mutex_unlock(&client_mutex); | |
| 1665 | 1683 | |
| 1666 | 1684 | return 0; |
| 1667 | 1685 | |
| @@ -1680,6 +1698,7 @@ card_probe_error: · 12 unmodified lines | ||
| 1680 | 1698 | |
| 1681 | 1699 | base_error: |
| 1682 | 1700 | mutex_unlock(&card->mutex); |
| 1701 | + mutex_unlock(&client_mutex); | |
| 1683 | 1702 | |
| 1684 | 1703 | return ret; |
| 1685 | 1704 | } |
| @@ -2713,13 +2732,6 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) · 1027 unmodified lines | ||
| 2713 | 2732 | list_del(&component->list); |
| 2714 | 2733 | } |
| 2715 | 2734 | |
| 2716 | −static void snd_soc_component_del(struct snd_soc_component *component) | |
| 2717 | −{ | |
| 2718 | − mutex_lock(&client_mutex); | |
| 2719 | − snd_soc_component_del_unlocked(component); | |
| 2720 | − mutex_unlock(&client_mutex); | |
| 2721 | −} | |
| 2722 | − | |
| 2723 | 2735 | int snd_soc_register_component(struct device *dev, |
| 2724 | 2736 | const struct snd_soc_component_driver *cmpnt_drv, |
| 2725 | 2737 | struct snd_soc_dai_driver *dai_drv, |
| @@ -2767,14 +2779,17 @@ void snd_soc_unregister_component(struct device *dev) · 41 unmodified lines | ||
| 2767 | 2779 | { |
| 2768 | 2780 | struct snd_soc_component *cmpnt; |
| 2769 | 2781 | |
| 2782 | + mutex_lock(&client_mutex); | |
| 2770 | 2783 | list_for_each_entry(cmpnt, &component_list, list) { |
| 2771 | 2784 | if (dev == cmpnt->dev && cmpnt->registered_as_component) |
| 2772 | 2785 | goto found; |
| 2773 | 2786 | } |
| 2787 | + mutex_unlock(&client_mutex); | |
| 2774 | 2788 | return; |
| 2775 | 2789 | |
| 2776 | 2790 | found: |
| 2777 | − snd_soc_component_del(cmpnt); | |
| 2791 | + snd_soc_component_del_unlocked(cmpnt); | |
| 2792 | + mutex_unlock(&client_mutex); | |
| 2778 | 2793 | snd_soc_component_cleanup(cmpnt); |
| 2779 | 2794 | kfree(cmpnt); |
| 2780 | 2795 | } |
| @@ -2882,10 +2897,14 @@ struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev) · 101 unmodified lines | ||
| 2882 | 2897 | { |
| 2883 | 2898 | struct snd_soc_platform *platform; |
| 2884 | 2899 | |
| 2900 | + mutex_lock(&client_mutex); | |
| 2885 | 2901 | list_for_each_entry(platform, &platform_list, list) { |
| 2886 | − if (dev == platform->dev) | |
| 2902 | + if (dev == platform->dev) { | |
| 2903 | + mutex_unlock(&client_mutex); | |
| 2887 | 2904 | return platform; |
| 2905 | + } | |
| 2888 | 2906 | } |
| 2907 | + mutex_unlock(&client_mutex); | |
| 2889 | 2908 | |
| 2890 | 2909 | return NULL; |
| 2891 | 2910 | } |
| @@ -3090,15 +3109,15 @@ void snd_soc_unregister_codec(struct device *dev) · 198 unmodified lines | ||
| 3090 | 3109 | { |
| 3091 | 3110 | struct snd_soc_codec *codec; |
| 3092 | 3111 | |
| 3112 | + mutex_lock(&client_mutex); | |
| 3093 | 3113 | list_for_each_entry(codec, &codec_list, list) { |
| 3094 | 3114 | if (dev == codec->dev) |
| 3095 | 3115 | goto found; |
| 3096 | 3116 | } |
| 3117 | + mutex_unlock(&client_mutex); | |
| 3097 | 3118 | return; |
| 3098 | 3119 | |
| 3099 | 3120 | found: |
| 3100 | − | |
| 3101 | − mutex_lock(&client_mutex); | |
| 3102 | 3121 | list_del(&codec->list); |
| 3103 | 3122 | snd_soc_component_del_unlocked(&codec->component); |
| 3104 | 3123 | mutex_unlock(&client_mutex); |
| @@ -1773,6 +1773,36 @@ YAMAHA_DEVICE(0x7010, "UB99"), · 1772 unmodified lines | ||
| 1773 | 1773 | } |
| 1774 | 1774 | } |
| 1775 | 1775 | }, |
| 1776 | +{ | |
| 1777 | + USB_DEVICE(0x0582, 0x0159), | |
| 1778 | + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | |
| 1779 | + /* .vendor_name = "Roland", */ | |
| 1780 | + /* .product_name = "UA-22", */ | |
| 1781 | + .ifnum = QUIRK_ANY_INTERFACE, | |
| 1782 | + .type = QUIRK_COMPOSITE, | |
| 1783 | + .data = (const struct snd_usb_audio_quirk[]) { | |
| 1784 | + { | |
| 1785 | + .ifnum = 0, | |
| 1786 | + .type = QUIRK_AUDIO_STANDARD_INTERFACE | |
| 1787 | + }, | |
| 1788 | + { | |
| 1789 | + .ifnum = 1, | |
| 1790 | + .type = QUIRK_AUDIO_STANDARD_INTERFACE | |
| 1791 | + }, | |
| 1792 | + { | |
| 1793 | + .ifnum = 2, | |
| 1794 | + .type = QUIRK_MIDI_FIXED_ENDPOINT, | |
| 1795 | + .data = & (const struct snd_usb_midi_endpoint_info) { | |
| 1796 | + .out_cables = 0x0001, | |
| 1797 | + .in_cables = 0x0001 | |
| 1798 | + } | |
| 1799 | + }, | |
| 1800 | + { | |
| 1801 | + .ifnum = -1 | |
| 1802 | + } | |
| 1803 | + } | |
| 1804 | + } | |
| 1805 | +}, | |
| 1776 | 1806 | /* this catches most recent vendor-specific Roland devices */ |
| 1777 | 1807 | { |
| 1778 | 1808 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | |
| @@ -30,6 +30,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp); · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | static void ins__delete(struct ins_operands *ops) |
| 32 | 32 | { |
| 33 | + if (ops == NULL) | |
| 34 | + return; | |
| 33 | 35 | zfree(&ops->source.raw); |
| 34 | 36 | zfree(&ops->source.name); |
| 35 | 37 | zfree(&ops->target.raw); |
| @@ -209,7 +209,7 @@ $(OUTPUT)%.o: %.c · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | $(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) |
| 211 | 211 | $(ECHO) " CC " $@ |
| 212 | − $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -Wl,-rpath=./ -lrt -lpci -L$(OUTPUT) -o $@ | |
| 212 | + $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@ | |
| 213 | 213 | $(QUIET) $(STRIPCMD) $@ |
| 214 | 214 | |
| 215 | 215 | $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) |
| @@ -30,7 +30,7 @@ static int execveat_(int fd, const char *path, char **argv, char **envp, · 29 unmodified lines | ||
| 30 | 30 | #ifdef __NR_execveat |
| 31 | 31 | return syscall(__NR_execveat, fd, path, argv, envp, flags); |
| 32 | 32 | #else |
| 33 | − errno = -ENOSYS; | |
| 33 | + errno = ENOSYS; | |
| 34 | 34 | return -1; |
| 35 | 35 | #endif |
| 36 | 36 | } |
| @@ -234,6 +234,14 @@ static int run_tests(void) · 197 unmodified lines | ||
| 234 | 234 | int fd_cloexec = open_or_die("execveat", O_RDONLY|O_CLOEXEC); |
| 235 | 235 | int fd_script_cloexec = open_or_die("script", O_RDONLY|O_CLOEXEC); |
| 236 | 236 | |
| 237 | + /* Check if we have execveat at all, and bail early if not */ | |
| 238 | + errno = 0; | |
| 239 | + execveat_(-1, NULL, NULL, NULL, 0); | |
| 240 | + if (errno == ENOSYS) { | |
| 241 | + printf("[FAIL] ENOSYS calling execveat - no kernel support?\n"); | |
| 242 | + return 1; | |
| 243 | + } | |
| 244 | + | |
| 237 | 245 | /* Change file position to confirm it doesn't affect anything */ |
| 238 | 246 | lseek(fd, 10, SEEK_SET); |
| 239 | 247 | |
| @@ -72,6 +72,8 @@ static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, · 71 unmodified lines | ||
| 72 | 72 | { |
| 73 | 73 | if (!(lr_desc.state & LR_STATE_MASK)) |
| 74 | 74 | vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr |= (1ULL << lr); |
| 75 | + else | |
| 76 | + vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr &= ~(1ULL << lr); | |
| 75 | 77 | } |
| 76 | 78 | |
| 77 | 79 | static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) |
| @@ -84,6 +86,11 @@ static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) · 6 unmodified lines | ||
| 84 | 86 | return vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr; |
| 85 | 87 | } |
| 86 | 88 | |
| 89 | +static void vgic_v2_clear_eisr(struct kvm_vcpu *vcpu) | |
| 90 | +{ | |
| 91 | + vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr = 0; | |
| 92 | +} | |
| 93 | + | |
| 87 | 94 | static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu) |
| 88 | 95 | { |
| 89 | 96 | u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr; |
| @@ -148,6 +155,7 @@ static const struct vgic_ops vgic_v2_ops = { · 58 unmodified lines | ||
| 148 | 155 | .sync_lr_elrsr = vgic_v2_sync_lr_elrsr, |
| 149 | 156 | .get_elrsr = vgic_v2_get_elrsr, |
| 150 | 157 | .get_eisr = vgic_v2_get_eisr, |
| 158 | + .clear_eisr = vgic_v2_clear_eisr, | |
| 151 | 159 | .get_interrupt_status = vgic_v2_get_interrupt_status, |
| 152 | 160 | .enable_underflow = vgic_v2_enable_underflow, |
| 153 | 161 | .disable_underflow = vgic_v2_disable_underflow, |
| @@ -104,6 +104,8 @@ static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, · 103 unmodified lines | ||
| 104 | 104 | { |
| 105 | 105 | if (!(lr_desc.state & LR_STATE_MASK)) |
| 106 | 106 | vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr); |
| 107 | + else | |
| 108 | + vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr &= ~(1U << lr); | |
| 107 | 109 | } |
| 108 | 110 | |
| 109 | 111 | static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu) |
| @@ -116,6 +118,11 @@ static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu) · 6 unmodified lines | ||
| 116 | 118 | return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr; |
| 117 | 119 | } |
| 118 | 120 | |
| 121 | +static void vgic_v3_clear_eisr(struct kvm_vcpu *vcpu) | |
| 122 | +{ | |
| 123 | + vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr = 0; | |
| 124 | +} | |
| 125 | + | |
| 119 | 126 | static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu) |
| 120 | 127 | { |
| 121 | 128 | u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr; |
| @@ -192,6 +199,7 @@ static const struct vgic_ops vgic_v3_ops = { · 70 unmodified lines | ||
| 192 | 199 | .sync_lr_elrsr = vgic_v3_sync_lr_elrsr, |
| 193 | 200 | .get_elrsr = vgic_v3_get_elrsr, |
| 194 | 201 | .get_eisr = vgic_v3_get_eisr, |
| 202 | + .clear_eisr = vgic_v3_clear_eisr, | |
| 195 | 203 | .get_interrupt_status = vgic_v3_get_interrupt_status, |
| 196 | 204 | .enable_underflow = vgic_v3_enable_underflow, |
| 197 | 205 | .disable_underflow = vgic_v3_disable_underflow, |
| @@ -883,6 +883,11 @@ static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) · 882 unmodified lines | ||
| 883 | 883 | return vgic_ops->get_eisr(vcpu); |
| 884 | 884 | } |
| 885 | 885 | |
| 886 | +static inline void vgic_clear_eisr(struct kvm_vcpu *vcpu) | |
| 887 | +{ | |
| 888 | + vgic_ops->clear_eisr(vcpu); | |
| 889 | +} | |
| 890 | + | |
| 886 | 891 | static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) |
| 887 | 892 | { |
| 888 | 893 | return vgic_ops->get_interrupt_status(vcpu); |
| @@ -922,6 +927,7 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) · 33 unmodified lines | ||
| 922 | 927 | vgic_set_lr(vcpu, lr_nr, vlr); |
| 923 | 928 | clear_bit(lr_nr, vgic_cpu->lr_used); |
| 924 | 929 | vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; |
| 930 | + vgic_sync_lr_elrsr(vcpu, lr_nr, vlr); | |
| 925 | 931 | } |
| 926 | 932 | |
| 927 | 933 | /* |
| @@ -978,6 +984,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) · 50 unmodified lines | ||
| 978 | 984 | BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); |
| 979 | 985 | vlr.state |= LR_STATE_PENDING; |
| 980 | 986 | vgic_set_lr(vcpu, lr, vlr); |
| 987 | + vgic_sync_lr_elrsr(vcpu, lr, vlr); | |
| 981 | 988 | return true; |
| 982 | 989 | } |
| 983 | 990 | } |
| @@ -999,6 +1006,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) · 15 unmodified lines | ||
| 999 | 1006 | vlr.state |= LR_EOI_INT; |
| 1000 | 1007 | |
| 1001 | 1008 | vgic_set_lr(vcpu, lr, vlr); |
| 1009 | + vgic_sync_lr_elrsr(vcpu, lr, vlr); | |
| 1002 | 1010 | |
| 1003 | 1011 | return true; |
| 1004 | 1012 | } |
| @@ -1136,6 +1144,14 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) · 131 unmodified lines | ||
| 1136 | 1144 | if (status & INT_STATUS_UNDERFLOW) |
| 1137 | 1145 | vgic_disable_underflow(vcpu); |
| 1138 | 1146 | |
| 1147 | + /* | |
| 1148 | + * In the next iterations of the vcpu loop, if we sync the vgic state | |
| 1149 | + * after flushing it, but before entering the guest (this happens for | |
| 1150 | + * pending signals and vmid rollovers), then make sure we don't pick | |
| 1151 | + * up any old maintenance interrupts here. | |
| 1152 | + */ | |
| 1153 | + vgic_clear_eisr(vcpu); | |
| 1154 | + | |
| 1139 | 1155 | return level_pending; |
| 1140 | 1156 | } |
| 1141 | 1157 | |
| @@ -1583,8 +1599,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) · 441 unmodified lines | ||
| 1583 | 1599 | * emulation. So check this here again. KVM_CREATE_DEVICE does |
| 1584 | 1600 | * the proper checks already. |
| 1585 | 1601 | */ |
| 1586 | − if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) | |
| 1587 | − return -ENODEV; | |
| 1602 | + if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) { | |
| 1603 | + ret = -ENODEV; | |
| 1604 | + goto out; | |
| 1605 | + } | |
| 1588 | 1606 | |
| 1589 | 1607 | /* |
| 1590 | 1608 | * Any time a vcpu is run, vcpu_load is called which tries to grab the |
| @@ -2492,6 +2492,7 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) · 2491 unmodified lines | ||
| 2492 | 2492 | case KVM_CAP_SIGNAL_MSI: |
| 2493 | 2493 | #endif |
| 2494 | 2494 | #ifdef CONFIG_HAVE_KVM_IRQFD |
| 2495 | + case KVM_CAP_IRQFD: | |
| 2495 | 2496 | case KVM_CAP_IRQFD_RESAMPLE: |
| 2496 | 2497 | #endif |
| 2497 | 2498 | case KVM_CAP_CHECK_EXTENSION_VM: |