diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 23:17:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-03 23:17:35 -0400 |
commit | e6445f52d9c8b0e6557a45fa7d0e8e088d430a8c (patch) | |
tree | 0c9dbec3a5655beda1848b321c4d9dbeb27987a6 | |
parent | e6dce825fba05f447bd22c865e27233182ab3d79 (diff) | |
parent | ab21b63e8aedfc73565dd9cdd51eb338341177cb (diff) |
Merge tag 'usb-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull usb/phy/extcon updates from Greg KH:
"Here is the big USB, and PHY, and extcon, patchsets for 4.9-rc1.
Full details are in the shortlog, but generally a lot of new hardware
support, usb gadget updates, and Wolfram's great cleanup of USB error
message handling, making the kernel image a tad bit smaller.
All of this has been in linux-next with no reported issues"
* tag 'usb-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (343 commits)
Revert "usbtmc: convert to devm_kzalloc"
USB: serial: cp210x: Add ID for a Juniper console
usb: Kconfig: using select for USB_COMMON dependency
bluetooth: bcm203x: don't print error when allocating urb fails
mmc: host: vub300: don't print error when allocating urb fails
usb: hub: change CLEAR_FEATURE to SET_FEATURE
usb: core: Introduce a USB port LED trigger
USB: bcma: drop Northstar PHY 2.0 initialization code
usb: core: hcd: add missing header dependencies
usb: musb: da8xx: fix error handling message in probe
usb: musb: Fix session based PM for first invalid VBUS
usb: musb: Fix PM runtime for disconnect after unconfigure
musb: Export musb_root_disconnect for use in modules
usb: misc: legousbtower: Fix NULL pointer deference
cdc-acm: hardening against malicious devices
Revert "usb: gadget: NCM: Protect dev->port_usb using dev->lock"
include: extcon: Fix compilation error caused because of incomplete merge
MAINTAINERS: add tree entry for USB Serial
phy-twl4030-usb: initialize charging-related stuff via pm_runtime
phy-twl4030-usb: better handle musb_mailbox() failure
...
234 files changed, 7197 insertions, 2122 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-usbport b/Documentation/ABI/testing/sysfs-class-led-trigger-usbport new file mode 100644 index 000000000000..f440e690daef --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-usbport | |||
@@ -0,0 +1,12 @@ | |||
1 | What: /sys/class/leds/<led>/ports/<port> | ||
2 | Date: September 2016 | ||
3 | KernelVersion: 4.9 | ||
4 | Contact: linux-leds@vger.kernel.org | ||
5 | linux-usb@vger.kernel.org | ||
6 | Description: | ||
7 | Every dir entry represents a single USB port that can be | ||
8 | selected for the USB port trigger. Selecting ports makes trigger | ||
9 | observing them for any connected devices and lighting on LED if | ||
10 | there are any. | ||
11 | Echoing "1" value selects USB port. Echoing "0" unselects it. | ||
12 | Current state can be also read. | ||
diff --git a/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt b/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt new file mode 100644 index 000000000000..35383adb10f1 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | Qualcomm's PM8941 USB ID Extcon device | ||
2 | |||
3 | Some Qualcomm PMICs have a "misc" module that can be used to detect when | ||
4 | the USB ID pin has been pulled low or high. | ||
5 | |||
6 | PROPERTIES | ||
7 | |||
8 | - compatible: | ||
9 | Usage: required | ||
10 | Value type: <string> | ||
11 | Definition: Should contain "qcom,pm8941-misc"; | ||
12 | |||
13 | - reg: | ||
14 | Usage: required | ||
15 | Value type: <u32> | ||
16 | Definition: Should contain the offset to the misc address space | ||
17 | |||
18 | - interrupts: | ||
19 | Usage: required | ||
20 | Value type: <prop-encoded-array> | ||
21 | Definition: Should contain the usb id interrupt | ||
22 | |||
23 | - interrupt-names: | ||
24 | Usage: required | ||
25 | Value type: <stringlist> | ||
26 | Definition: Should contain the string "usb_id" for the usb id interrupt | ||
27 | |||
28 | Example: | ||
29 | |||
30 | pmic { | ||
31 | usb_id: misc@900 { | ||
32 | compatible = "qcom,pm8941-misc"; | ||
33 | reg = <0x900>; | ||
34 | interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; | ||
35 | interrupt-names = "usb_id"; | ||
36 | }; | ||
37 | } | ||
38 | |||
39 | usb-controller { | ||
40 | extcon = <&usb_id>; | ||
41 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt b/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt new file mode 100644 index 000000000000..09aeba94538d --- /dev/null +++ b/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | Driver for Broadcom Northstar USB 3.0 PHY | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy". | ||
6 | - reg: register mappings for DMP (Device Management Plugin) and ChipCommon B | ||
7 | MMI. | ||
8 | - reg-names: "dmp" and "ccb-mii" | ||
9 | |||
10 | Initialization of USB 3.0 PHY depends on Northstar version. There are currently | ||
11 | three known series: Ax, Bx and Cx. | ||
12 | Known A0: BCM4707 rev 0 | ||
13 | Known B0: BCM4707 rev 4, BCM53573 rev 2 | ||
14 | Known B1: BCM4707 rev 6 | ||
15 | Known C0: BCM47094 rev 0 | ||
16 | |||
17 | Example: | ||
18 | usb3-phy { | ||
19 | compatible = "brcm,ns-ax-usb3-phy"; | ||
20 | reg = <0x18105000 0x1000>, <0x18003000 0x1000>; | ||
21 | reg-names = "dmp", "ccb-mii"; | ||
22 | #phy-cells = <0>; | ||
23 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt index 379b84a567cc..1d25b04cd05e 100644 --- a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt | |||
@@ -12,6 +12,16 @@ Required properties: | |||
12 | - interrupts: Should contain phy interrupt | 12 | - interrupts: Should contain phy interrupt |
13 | - fsl,anatop: phandle for anatop register, it is only for imx6 SoC series | 13 | - fsl,anatop: phandle for anatop register, it is only for imx6 SoC series |
14 | 14 | ||
15 | Optional properties: | ||
16 | - fsl,tx-cal-45-dn-ohms: Integer [30-55]. Resistance (in ohms) of switchable | ||
17 | high-speed trimming resistor connected in parallel with the 45 ohm resistor | ||
18 | that terminates the DN output signal. Default: 45 | ||
19 | - fsl,tx-cal-45-dp-ohms: Integer [30-55]. Resistance (in ohms) of switchable | ||
20 | high-speed trimming resistor connected in parallel with the 45 ohm resistor | ||
21 | that terminates the DP output signal. Default: 45 | ||
22 | - fsl,tx-d-cal: Integer [79-119]. Current trimming value (as a percentage) of | ||
23 | the 17.78mA TX reference current. Default: 100 | ||
24 | |||
15 | Example: | 25 | Example: |
16 | usbphy1: usbphy@020c9000 { | 26 | usbphy1: usbphy@020c9000 { |
17 | compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; | 27 | compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; |
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt new file mode 100644 index 000000000000..3c29c77a7018 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt | |||
@@ -0,0 +1,64 @@ | |||
1 | ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK | ||
2 | |||
3 | Required properties (phy (parent) node): | ||
4 | - compatible : should be one of the listed compatibles: | ||
5 | * "rockchip,rk3366-usb2phy" | ||
6 | * "rockchip,rk3399-usb2phy" | ||
7 | - reg : the address offset of grf for usb-phy configuration. | ||
8 | - #clock-cells : should be 0. | ||
9 | - clock-output-names : specify the 480m output clock name. | ||
10 | |||
11 | Optional properties: | ||
12 | - clocks : phandle + phy specifier pair, for the input clock of phy. | ||
13 | - clock-names : input clock name of phy, must be "phyclk". | ||
14 | |||
15 | Required nodes : a sub-node is required for each port the phy provides. | ||
16 | The sub-node name is used to identify host or otg port, | ||
17 | and shall be the following entries: | ||
18 | * "otg-port" : the name of otg port. | ||
19 | * "host-port" : the name of host port. | ||
20 | |||
21 | Required properties (port (child) node): | ||
22 | - #phy-cells : must be 0. See ./phy-bindings.txt for details. | ||
23 | - interrupts : specify an interrupt for each entry in interrupt-names. | ||
24 | - interrupt-names : a list which shall be the following entries: | ||
25 | * "otg-id" : for the otg id interrupt. | ||
26 | * "otg-bvalid" : for the otg vbus interrupt. | ||
27 | * "linestate" : for the host/otg linestate interrupt. | ||
28 | |||
29 | Optional properties: | ||
30 | - phy-supply : phandle to a regulator that provides power to VBUS. | ||
31 | See ./phy-bindings.txt for details. | ||
32 | |||
33 | Example: | ||
34 | |||
35 | grf: syscon@ff770000 { | ||
36 | compatible = "rockchip,rk3366-grf", "syscon", "simple-mfd"; | ||
37 | #address-cells = <1>; | ||
38 | #size-cells = <1>; | ||
39 | |||
40 | ... | ||
41 | |||
42 | u2phy: usb2-phy@700 { | ||
43 | compatible = "rockchip,rk3366-usb2phy"; | ||
44 | reg = <0x700 0x2c>; | ||
45 | #clock-cells = <0>; | ||
46 | clock-output-names = "sclk_otgphy0_480m"; | ||
47 | |||
48 | u2phy_otg: otg-port { | ||
49 | #phy-cells = <0>; | ||
50 | interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>, | ||
51 | <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>, | ||
52 | <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; | ||
53 | interrupt-names = "otg-id", "otg-bvalid", "linestate"; | ||
54 | status = "okay"; | ||
55 | }; | ||
56 | |||
57 | u2phy_host: host-port { | ||
58 | #phy-cells = <0>; | ||
59 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; | ||
60 | interrupt-names = "linestate"; | ||
61 | status = "okay"; | ||
62 | }; | ||
63 | }; | ||
64 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt new file mode 100644 index 000000000000..6ea867e3176f --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt | |||
@@ -0,0 +1,101 @@ | |||
1 | * ROCKCHIP type-c PHY | ||
2 | --------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible : must be "rockchip,rk3399-typec-phy" | ||
6 | - reg: Address and length of the usb phy control register set | ||
7 | - rockchip,grf : phandle to the syscon managing the "general | ||
8 | register files" | ||
9 | - clocks : phandle + clock specifier for the phy clocks | ||
10 | - clock-names : string, clock name, must be "tcpdcore", "tcpdphy-ref"; | ||
11 | - assigned-clocks: main clock, should be <&cru SCLK_UPHY0_TCPDCORE> or | ||
12 | <&cru SCLK_UPHY1_TCPDCORE>; | ||
13 | - assigned-clock-rates : the phy core clk frequency, shall be: 50000000 | ||
14 | - resets : a list of phandle + reset specifier pairs | ||
15 | - reset-names : string reset name, must be: | ||
16 | "uphy", "uphy-pipe", "uphy-tcphy" | ||
17 | - extcon : extcon specifier for the Power Delivery | ||
18 | |||
19 | Note, there are 2 type-c phys for RK3399, and they are almost identical, except | ||
20 | these registers(description below), every register node contains 3 sections: | ||
21 | offset, enable bit, write mask bit. | ||
22 | - rockchip,typec-conn-dir : the register of type-c connector direction, | ||
23 | for type-c phy0, it must be <0xe580 0 16>; | ||
24 | for type-c phy1, it must be <0xe58c 0 16>; | ||
25 | - rockchip,usb3tousb2-en : the register of type-c force usb3 to usb2 enable | ||
26 | control. | ||
27 | for type-c phy0, it must be <0xe580 3 19>; | ||
28 | for type-c phy1, it must be <0xe58c 3 19>; | ||
29 | - rockchip,external-psm : the register of type-c phy external psm clock | ||
30 | selection. | ||
31 | for type-c phy0, it must be <0xe588 14 30>; | ||
32 | for type-c phy1, it must be <0xe594 14 30>; | ||
33 | - rockchip,pipe-status : the register of type-c phy pipe status. | ||
34 | for type-c phy0, it must be <0xe5c0 0 0>; | ||
35 | for type-c phy1, it must be <0xe5c0 16 16>; | ||
36 | |||
37 | Required nodes : a sub-node is required for each port the phy provides. | ||
38 | The sub-node name is used to identify dp or usb3 port, | ||
39 | and shall be the following entries: | ||
40 | * "dp-port" : the name of DP port. | ||
41 | * "usb3-port" : the name of USB3 port. | ||
42 | |||
43 | Required properties (port (child) node): | ||
44 | - #phy-cells : must be 0, See ./phy-bindings.txt for details. | ||
45 | |||
46 | Example: | ||
47 | tcphy0: phy@ff7c0000 { | ||
48 | compatible = "rockchip,rk3399-typec-phy"; | ||
49 | reg = <0x0 0xff7c0000 0x0 0x40000>; | ||
50 | rockchip,grf = <&grf>; | ||
51 | extcon = <&fusb0>; | ||
52 | clocks = <&cru SCLK_UPHY0_TCPDCORE>, | ||
53 | <&cru SCLK_UPHY0_TCPDPHY_REF>; | ||
54 | clock-names = "tcpdcore", "tcpdphy-ref"; | ||
55 | assigned-clocks = <&cru SCLK_UPHY0_TCPDCORE>; | ||
56 | assigned-clock-rates = <50000000>; | ||
57 | resets = <&cru SRST_UPHY0>, | ||
58 | <&cru SRST_UPHY0_PIPE_L00>, | ||
59 | <&cru SRST_P_UPHY0_TCPHY>; | ||
60 | reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; | ||
61 | rockchip,typec-conn-dir = <0xe580 0 16>; | ||
62 | rockchip,usb3tousb2-en = <0xe580 3 19>; | ||
63 | rockchip,external-psm = <0xe588 14 30>; | ||
64 | rockchip,pipe-status = <0xe5c0 0 0>; | ||
65 | |||
66 | tcphy0_dp: dp-port { | ||
67 | #phy-cells = <0>; | ||
68 | }; | ||
69 | |||
70 | tcphy0_usb3: usb3-port { | ||
71 | #phy-cells = <0>; | ||
72 | }; | ||
73 | }; | ||
74 | |||
75 | tcphy1: phy@ff800000 { | ||
76 | compatible = "rockchip,rk3399-typec-phy"; | ||
77 | reg = <0x0 0xff800000 0x0 0x40000>; | ||
78 | rockchip,grf = <&grf>; | ||
79 | extcon = <&fusb1>; | ||
80 | clocks = <&cru SCLK_UPHY1_TCPDCORE>, | ||
81 | <&cru SCLK_UPHY1_TCPDPHY_REF>; | ||
82 | clock-names = "tcpdcore", "tcpdphy-ref"; | ||
83 | assigned-clocks = <&cru SCLK_UPHY1_TCPDCORE>; | ||
84 | assigned-clock-rates = <50000000>; | ||
85 | resets = <&cru SRST_UPHY1>, | ||
86 | <&cru SRST_UPHY1_PIPE_L00>, | ||
87 | <&cru SRST_P_UPHY1_TCPHY>; | ||
88 | reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; | ||
89 | rockchip,typec-conn-dir = <0xe58c 0 16>; | ||
90 | rockchip,usb3tousb2-en = <0xe58c 3 19>; | ||
91 | rockchip,external-psm = <0xe594 14 30>; | ||
92 | rockchip,pipe-status = <0xe5c0 16 16>; | ||
93 | |||
94 | tcphy1_dp: dp-port { | ||
95 | #phy-cells = <0>; | ||
96 | }; | ||
97 | |||
98 | tcphy1_usb3: usb3-port { | ||
99 | #phy-cells = <0>; | ||
100 | }; | ||
101 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt index 2281d6cdecb1..ace9cce2704a 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | |||
@@ -6,6 +6,8 @@ This file provides information on what the device node for the R-Car generation | |||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 | 7 | - compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 |
8 | SoC. | 8 | SoC. |
9 | "renesas,usb2-phy-r8a7796" if the device is a part of an R8A7796 | ||
10 | SoC. | ||
9 | "renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3 compatible device. | 11 | "renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3 compatible device. |
10 | 12 | ||
11 | When compatible with the generic version, nodes must list the | 13 | When compatible with the generic version, nodes must list the |
@@ -30,11 +32,11 @@ Example (R-Car H3): | |||
30 | compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; | 32 | compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; |
31 | reg = <0 0xee080200 0 0x700>; | 33 | reg = <0 0xee080200 0 0x700>; |
32 | interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; | 34 | interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; |
33 | clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; | 35 | clocks = <&cpg CPG_MOD 703>; |
34 | }; | 36 | }; |
35 | 37 | ||
36 | usb-phy@ee0a0200 { | 38 | usb-phy@ee0a0200 { |
37 | compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; | 39 | compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy"; |
38 | reg = <0 0xee0a0200 0 0x700>; | 40 | reg = <0 0xee0a0200 0 0x700>; |
39 | clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; | 41 | clocks = <&cpg CPG_MOD 702>; |
40 | }; | 42 | }; |
diff --git a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt new file mode 100644 index 000000000000..0f6222a672ce --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | Rockchip PCIE PHY | ||
2 | ----------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: rockchip,rk3399-pcie-phy | ||
6 | - #phy-cells: must be 0 | ||
7 | - clocks: Must contain an entry in clock-names. | ||
8 | See ../clocks/clock-bindings.txt for details. | ||
9 | - clock-names: Must be "refclk" | ||
10 | - resets: Must contain an entry in reset-names. | ||
11 | See ../reset/reset.txt for details. | ||
12 | - reset-names: Must be "phy" | ||
13 | |||
14 | Example: | ||
15 | |||
16 | grf: syscon@ff770000 { | ||
17 | compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd"; | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | |||
21 | ... | ||
22 | |||
23 | pcie_phy: pcie-phy { | ||
24 | compatible = "rockchip,rk3399-pcie-phy"; | ||
25 | #phy-cells = <0>; | ||
26 | clocks = <&cru SCLK_PCIEPHY_REF>; | ||
27 | clock-names = "refclk"; | ||
28 | resets = <&cru SRST_PCIEPHY>; | ||
29 | reset-names = "phy"; | ||
30 | }; | ||
31 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt index cc6be9680a6d..57dc388e2fa2 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt | |||
@@ -27,6 +27,9 @@ Optional Properties: | |||
27 | - clocks : phandle + clock specifier for the phy clocks | 27 | - clocks : phandle + clock specifier for the phy clocks |
28 | - clock-names: string, clock name, must be "phyclk" | 28 | - clock-names: string, clock name, must be "phyclk" |
29 | - #clock-cells: for users of the phy-pll, should be 0 | 29 | - #clock-cells: for users of the phy-pll, should be 0 |
30 | - reset-names: Only allow the following entries: | ||
31 | - phy-reset | ||
32 | - resets: Must contain an entry for each entry in reset-names. | ||
30 | 33 | ||
31 | Example: | 34 | Example: |
32 | 35 | ||
diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index 95736d77fbb7..287150db6db4 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | |||
@@ -10,6 +10,7 @@ Required properties: | |||
10 | * allwinner,sun8i-a23-usb-phy | 10 | * allwinner,sun8i-a23-usb-phy |
11 | * allwinner,sun8i-a33-usb-phy | 11 | * allwinner,sun8i-a33-usb-phy |
12 | * allwinner,sun8i-h3-usb-phy | 12 | * allwinner,sun8i-h3-usb-phy |
13 | * allwinner,sun50i-a64-usb-phy | ||
13 | - reg : a list of offset + length pairs | 14 | - reg : a list of offset + length pairs |
14 | - reg-names : | 15 | - reg-names : |
15 | * "phy_ctrl" | 16 | * "phy_ctrl" |
diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index a3b394587874..cd13e6157088 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt | |||
@@ -31,6 +31,8 @@ OMAP USB2 PHY | |||
31 | 31 | ||
32 | Required properties: | 32 | Required properties: |
33 | - compatible: Should be "ti,omap-usb2" | 33 | - compatible: Should be "ti,omap-usb2" |
34 | Should be "ti,dra7x-usb2" for the 1st instance of USB2 PHY on | ||
35 | DRA7x | ||
34 | Should be "ti,dra7x-usb2-phy2" for the 2nd instance of USB2 PHY | 36 | Should be "ti,dra7x-usb2-phy2" for the 2nd instance of USB2 PHY |
35 | in DRA7x | 37 | in DRA7x |
36 | - reg : Address and length of the register set for the device. | 38 | - reg : Address and length of the register set for the device. |
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 341dc67f3472..0e03344e2e8b 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | |||
@@ -81,6 +81,8 @@ i.mx specific properties | |||
81 | - fsl,usbmisc: phandler of non-core register device, with one | 81 | - fsl,usbmisc: phandler of non-core register device, with one |
82 | argument that indicate usb controller index | 82 | argument that indicate usb controller index |
83 | - disable-over-current: disable over current detect | 83 | - disable-over-current: disable over current detect |
84 | - over-current-active-high: over current signal polarity is high active, | ||
85 | typically over current signal polarity is low active. | ||
84 | - external-vbus-divider: enables off-chip resistor divider for Vbus | 86 | - external-vbus-divider: enables off-chip resistor divider for Vbus |
85 | 87 | ||
86 | Example: | 88 | Example: |
diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 20a68bf2b4e7..7d16ebfaa5a1 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt | |||
@@ -26,7 +26,10 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties | |||
26 | - g-use-dma: enable dma usage in gadget driver. | 26 | - g-use-dma: enable dma usage in gadget driver. |
27 | - g-rx-fifo-size: size of rx fifo size in gadget mode. | 27 | - g-rx-fifo-size: size of rx fifo size in gadget mode. |
28 | - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode. | 28 | - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode. |
29 | - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode. | 29 | |
30 | Deprecated properties: | ||
31 | - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) | ||
32 | in gadget mode. | ||
30 | 33 | ||
31 | Example: | 34 | Example: |
32 | 35 | ||
diff --git a/Documentation/devicetree/bindings/usb/dwc3-cavium.txt b/Documentation/devicetree/bindings/usb/dwc3-cavium.txt new file mode 100644 index 000000000000..710b782ccf65 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/dwc3-cavium.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Cavium SuperSpeed DWC3 USB SoC controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain "cavium,octeon-7130-usb-uctl" | ||
5 | |||
6 | Required child node: | ||
7 | A child node must exist to represent the core DWC3 IP block. The name of | ||
8 | the node is not important. The content of the node is defined in dwc3.txt. | ||
9 | |||
10 | Example device node: | ||
11 | |||
12 | uctl@1180069000000 { | ||
13 | compatible = "cavium,octeon-7130-usb-uctl"; | ||
14 | reg = <0x00011800 0x69000000 0x00000000 0x00000100>; | ||
15 | ranges; | ||
16 | #address-cells = <0x00000002>; | ||
17 | #size-cells = <0x00000002>; | ||
18 | refclk-frequency = <0x05f5e100>; | ||
19 | refclk-type-ss = "dlmc_ref_clk0"; | ||
20 | refclk-type-hs = "dlmc_ref_clk0"; | ||
21 | power = <0x00000002 0x00000002 0x00000001>; | ||
22 | xhci@1690000000000 { | ||
23 | compatible = "cavium,octeon-7130-xhci", "synopsys,dwc3"; | ||
24 | reg = <0x00016900 0x00000000 0x00000010 0x00000000>; | ||
25 | interrupt-parent = <0x00000010>; | ||
26 | interrupts = <0x00000009 0x00000004>; | ||
27 | }; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 7d7ce089b003..e3e6983288e3 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt | |||
@@ -13,7 +13,8 @@ Optional properties: | |||
13 | in the array is expected to be a handle to the USB2/HS PHY and | 13 | in the array is expected to be a handle to the USB2/HS PHY and |
14 | the second element is expected to be a handle to the USB3/SS PHY | 14 | the second element is expected to be a handle to the USB3/SS PHY |
15 | - phys: from the *Generic PHY* bindings | 15 | - phys: from the *Generic PHY* bindings |
16 | - phy-names: from the *Generic PHY* bindings | 16 | - phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy" |
17 | or "usb3-phy". | ||
17 | - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable | 18 | - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable |
18 | - snps,disable_scramble_quirk: true when SW should disable data scrambling. | 19 | - snps,disable_scramble_quirk: true when SW should disable data scrambling. |
19 | Only really useful for FPGA builds. | 20 | Only really useful for FPGA builds. |
@@ -39,6 +40,11 @@ Optional properties: | |||
39 | disabling the suspend signal to the PHY. | 40 | disabling the suspend signal to the PHY. |
40 | - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection | 41 | - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection |
41 | in PHY P3 power state. | 42 | in PHY P3 power state. |
43 | - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists | ||
44 | in GUSB2PHYCFG, specify that USB2 PHY doesn't provide | ||
45 | a free-running PHY clock. | ||
46 | - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power | ||
47 | from P0 to P1/P2/P3 without delay. | ||
42 | - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal | 48 | - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal |
43 | utmi_l1_suspend_n, false when asserts utmi_sleep_n | 49 | utmi_l1_suspend_n, false when asserts utmi_sleep_n |
44 | - snps,hird-threshold: HIRD threshold | 50 | - snps,hird-threshold: HIRD threshold |
diff --git a/Documentation/devicetree/bindings/usb/generic.txt b/Documentation/devicetree/bindings/usb/generic.txt index bba825711873..bfadeb1c3bab 100644 --- a/Documentation/devicetree/bindings/usb/generic.txt +++ b/Documentation/devicetree/bindings/usb/generic.txt | |||
@@ -11,6 +11,11 @@ Optional properties: | |||
11 | "peripheral" and "otg". In case this attribute isn't | 11 | "peripheral" and "otg". In case this attribute isn't |
12 | passed via DT, USB DRD controllers should default to | 12 | passed via DT, USB DRD controllers should default to |
13 | OTG. | 13 | OTG. |
14 | - phy_type: tells USB controllers that we want to configure the core to support | ||
15 | a UTMI+ PHY with an 8- or 16-bit interface if UTMI+ is | ||
16 | selected. Valid arguments are "utmi" and "utmi_wide". | ||
17 | In case this isn't passed via DT, USB controllers should | ||
18 | default to HW capability. | ||
14 | - otg-rev: tells usb driver the release number of the OTG and EH supplement | 19 | - otg-rev: tells usb driver the release number of the OTG and EH supplement |
15 | with which the device and its descriptors are compliant, | 20 | with which the device and its descriptors are compliant, |
16 | in binary-coded decimal (i.e. 2.0 is 0200H). This | 21 | in binary-coded decimal (i.e. 2.0 is 0200H). This |
@@ -34,6 +39,7 @@ dwc3@4a030000 { | |||
34 | usb-phy = <&usb2_phy>, <&usb3,phy>; | 39 | usb-phy = <&usb2_phy>, <&usb3,phy>; |
35 | maximum-speed = "super-speed"; | 40 | maximum-speed = "super-speed"; |
36 | dr_mode = "otg"; | 41 | dr_mode = "otg"; |
42 | phy_type = "utmi_wide"; | ||
37 | otg-rev = <0x0200>; | 43 | otg-rev = <0x0200>; |
38 | adp-disable; | 44 | adp-disable; |
39 | }; | 45 | }; |
diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index b6040563e51a..9e18e000339e 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt | |||
@@ -9,6 +9,7 @@ Required properties: | |||
9 | - "renesas,usbhs-r8a7793" for r8a7793 (R-Car M2-N) compatible device | 9 | - "renesas,usbhs-r8a7793" for r8a7793 (R-Car M2-N) compatible device |
10 | - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device | 10 | - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device |
11 | - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device | 11 | - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device |
12 | - "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device | ||
12 | - "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device | 13 | - "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device |
13 | - "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device | 14 | - "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device |
14 | 15 | ||
diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt new file mode 100644 index 000000000000..0536a938e3ab --- /dev/null +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | Rockchip SuperSpeed DWC3 USB SoC controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should contain "rockchip,rk3399-dwc3" for rk3399 SoC | ||
5 | - clocks: A list of phandle + clock-specifier pairs for the | ||
6 | clocks listed in clock-names | ||
7 | - clock-names: Should contain the following: | ||
8 | "ref_clk" Controller reference clk, have to be 24 MHz | ||
9 | "suspend_clk" Controller suspend clk, have to be 24 MHz or 32 KHz | ||
10 | "bus_clk" Master/Core clock, have to be >= 62.5 MHz for SS | ||
11 | operation and >= 30MHz for HS operation | ||
12 | "grf_clk" Controller grf clk | ||
13 | |||
14 | Required child node: | ||
15 | A child node must exist to represent the core DWC3 IP block. The name of | ||
16 | the node is not important. The content of the node is defined in dwc3.txt. | ||
17 | |||
18 | Phy documentation is provided in the following places: | ||
19 | Documentation/devicetree/bindings/phy/rockchip,dwc3-usb-phy.txt | ||
20 | |||
21 | Example device nodes: | ||
22 | |||
23 | usbdrd3_0: usb@fe800000 { | ||
24 | compatible = "rockchip,rk3399-dwc3"; | ||
25 | clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>, | ||
26 | <&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>; | ||
27 | clock-names = "ref_clk", "suspend_clk", | ||
28 | "bus_clk", "grf_clk"; | ||
29 | #address-cells = <2>; | ||
30 | #size-cells = <2>; | ||
31 | ranges; | ||
32 | status = "disabled"; | ||
33 | usbdrd_dwc3_0: dwc3@fe800000 { | ||
34 | compatible = "snps,dwc3"; | ||
35 | reg = <0x0 0xfe800000 0x0 0x100000>; | ||
36 | interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; | ||
37 | dr_mode = "otg"; | ||
38 | status = "disabled"; | ||
39 | }; | ||
40 | }; | ||
41 | |||
42 | usbdrd3_1: usb@fe900000 { | ||
43 | compatible = "rockchip,rk3399-dwc3"; | ||
44 | clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>, | ||
45 | <&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>; | ||
46 | clock-names = "ref_clk", "suspend_clk", | ||
47 | "bus_clk", "grf_clk"; | ||
48 | #address-cells = <2>; | ||
49 | #size-cells = <2>; | ||
50 | ranges; | ||
51 | status = "disabled"; | ||
52 | usbdrd_dwc3_1: dwc3@fe900000 { | ||
53 | compatible = "snps,dwc3"; | ||
54 | reg = <0x0 0xfe900000 0x0 0x100000>; | ||
55 | interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; | ||
56 | dr_mode = "otg"; | ||
57 | status = "disabled"; | ||
58 | }; | ||
59 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/usb4604.txt b/Documentation/devicetree/bindings/usb/usb4604.txt new file mode 100644 index 000000000000..82506d17712c --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb4604.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | SMSC USB4604 High-Speed Hub Controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "smsc,usb4604" | ||
5 | |||
6 | Optional properties: | ||
7 | - reg: Specifies the i2c slave address, it is required and should be 0x2d | ||
8 | if I2C is used. | ||
9 | - reset-gpios: Should specify GPIO for reset. | ||
10 | - initial-mode: Should specify initial mode. | ||
11 | (1 for HUB mode, 2 for STANDBY mode) | ||
12 | |||
13 | Examples: | ||
14 | usb-hub@2d { | ||
15 | compatible = "smsc,usb4604"; | ||
16 | reg = <0x2d>; | ||
17 | reset-gpios = <&gpx3 5 1>; | ||
18 | initial-mode = <1>; | ||
19 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt index 3539d4e7d23e..f1e27faf528e 100644 --- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt +++ b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt | |||
@@ -6,6 +6,7 @@ Required properties: | |||
6 | "fsl,imx6q-usbmisc" for imx6q | 6 | "fsl,imx6q-usbmisc" for imx6q |
7 | "fsl,vf610-usbmisc" for Vybrid vf610 | 7 | "fsl,vf610-usbmisc" for Vybrid vf610 |
8 | "fsl,imx6sx-usbmisc" for imx6sx | 8 | "fsl,imx6sx-usbmisc" for imx6sx |
9 | "fsl,imx7d-usbmisc" for imx7d | ||
9 | - reg: Should contain registers location and length | 10 | - reg: Should contain registers location and length |
10 | 11 | ||
11 | Examples: | 12 | Examples: |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0e285941e3c7..01085cdc47c1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -4248,6 +4248,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
4248 | u = IGNORE_UAS (don't bind to the uas driver); | 4248 | u = IGNORE_UAS (don't bind to the uas driver); |
4249 | w = NO_WP_DETECT (don't test whether the | 4249 | w = NO_WP_DETECT (don't test whether the |
4250 | medium is write-protected). | 4250 | medium is write-protected). |
4251 | y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE | ||
4252 | even if the device claims no cache) | ||
4251 | Example: quirks=0419:aaf5:rl,0421:0433:rc | 4253 | Example: quirks=0419:aaf5:rl,0421:0433:rc |
4252 | 4254 | ||
4253 | user_debug= [KNL,ARM] | 4255 | user_debug= [KNL,ARM] |
diff --git a/Documentation/leds/ledtrig-usbport.txt b/Documentation/leds/ledtrig-usbport.txt new file mode 100644 index 000000000000..69f54bfb4789 --- /dev/null +++ b/Documentation/leds/ledtrig-usbport.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | USB port LED trigger | ||
2 | ==================== | ||
3 | |||
4 | This LED trigger can be used for signalling to the user a presence of USB device | ||
5 | in a given port. It simply turns on LED when device appears and turns it off | ||
6 | when it disappears. | ||
7 | |||
8 | It requires selecting USB ports that should be observed. All available ones are | ||
9 | listed as separated entries in a "ports" subdirectory. Selecting is handled by | ||
10 | echoing "1" to a chosen port. | ||
11 | |||
12 | Please note that this trigger allows selecting multiple USB ports for a single | ||
13 | LED. This can be useful in two cases: | ||
14 | |||
15 | 1) Device with single USB LED and few physical ports | ||
16 | |||
17 | In such a case LED will be turned on as long as there is at least one connected | ||
18 | USB device. | ||
19 | |||
20 | 2) Device with a physical port handled by few controllers | ||
21 | |||
22 | Some devices may have one controller per PHY standard. E.g. USB 3.0 physical | ||
23 | port may be handled by ohci-platform, ehci-platform and xhci-hcd. If there is | ||
24 | only one LED user will most likely want to assign ports from all 3 hubs. | ||
25 | |||
26 | |||
27 | This trigger can be activated from user space on led class devices as shown | ||
28 | below: | ||
29 | |||
30 | echo usbport > trigger | ||
31 | |||
32 | This adds sysfs attributes to the LED that are documented in: | ||
33 | Documentation/ABI/testing/sysfs-class-led-trigger-usbport | ||
34 | |||
35 | Example use-case: | ||
36 | |||
37 | echo usbport > trigger | ||
38 | echo 1 > ports/usb1-port1 | ||
39 | echo 1 > ports/usb2-port1 | ||
40 | cat ports/usb1-port1 | ||
41 | echo 0 > ports/usb1-port1 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 434a43d3864d..d33c0383575b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -12216,7 +12216,7 @@ S: Maintained | |||
12216 | F: drivers/net/usb/lan78xx.* | 12216 | F: drivers/net/usb/lan78xx.* |
12217 | 12217 | ||
12218 | USB MASS STORAGE DRIVER | 12218 | USB MASS STORAGE DRIVER |
12219 | M: Matthew Dharm <mdharm-usb@one-eyed-alien.net> | 12219 | M: Alan Stern <stern@rowland.harvard.edu> |
12220 | L: linux-usb@vger.kernel.org | 12220 | L: linux-usb@vger.kernel.org |
12221 | L: usb-storage@lists.one-eyed-alien.net | 12221 | L: usb-storage@lists.one-eyed-alien.net |
12222 | S: Maintained | 12222 | S: Maintained |
@@ -12300,6 +12300,7 @@ F: drivers/net/usb/rtl8150.c | |||
12300 | USB SERIAL SUBSYSTEM | 12300 | USB SERIAL SUBSYSTEM |
12301 | M: Johan Hovold <johan@kernel.org> | 12301 | M: Johan Hovold <johan@kernel.org> |
12302 | L: linux-usb@vger.kernel.org | 12302 | L: linux-usb@vger.kernel.org |
12303 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git | ||
12303 | S: Maintained | 12304 | S: Maintained |
12304 | F: Documentation/usb/usb-serial.txt | 12305 | F: Documentation/usb/usb-serial.txt |
12305 | F: drivers/usb/serial/ | 12306 | F: drivers/usb/serial/ |
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 5b0ef7bbe8ac..5ce6d4176dc3 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c | |||
@@ -185,10 +185,8 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id | |||
185 | data->state = BCM203X_LOAD_MINIDRV; | 185 | data->state = BCM203X_LOAD_MINIDRV; |
186 | 186 | ||
187 | data->urb = usb_alloc_urb(0, GFP_KERNEL); | 187 | data->urb = usb_alloc_urb(0, GFP_KERNEL); |
188 | if (!data->urb) { | 188 | if (!data->urb) |
189 | BT_ERR("Can't allocate URB"); | ||
190 | return -ENOMEM; | 189 | return -ENOMEM; |
191 | } | ||
192 | 190 | ||
193 | if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { | 191 | if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { |
194 | BT_ERR("Mini driver request failed"); | 192 | BT_ERR("Mini driver request failed"); |
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 3d89e60a3e71..04788d92ea52 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
@@ -96,6 +96,12 @@ config EXTCON_PALMAS | |||
96 | Say Y here to enable support for USB peripheral and USB host | 96 | Say Y here to enable support for USB peripheral and USB host |
97 | detection by palmas usb. | 97 | detection by palmas usb. |
98 | 98 | ||
99 | config EXTCON_QCOM_SPMI_MISC | ||
100 | tristate "Qualcomm USB extcon support" | ||
101 | help | ||
102 | Say Y here to enable SPMI PMIC based USB cable detection | ||
103 | support on Qualcomm PMICs such as PM8941. | ||
104 | |||
99 | config EXTCON_RT8973A | 105 | config EXTCON_RT8973A |
100 | tristate "Richtek RT8973A EXTCON support" | 106 | tristate "Richtek RT8973A EXTCON support" |
101 | depends on I2C | 107 | depends on I2C |
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 972c813c375b..31a0a999c4fb 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o | |||
14 | obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o | 14 | obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o |
15 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o | 15 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o |
16 | obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o | 16 | obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o |
17 | obj-$(CONFIG_EXTCON_QCOM_SPMI_MISC) += extcon-qcom-spmi-misc.o | ||
17 | obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o | 18 | obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o |
18 | obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o | 19 | obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o |
19 | obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o | 20 | obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o |
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c index 44e48aa78a84..bc538708c753 100644 --- a/drivers/extcon/extcon-adc-jack.c +++ b/drivers/extcon/extcon-adc-jack.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Analog Jack extcon driver with ADC-based detection capability. | 4 | * Analog Jack extcon driver with ADC-based detection capability. |
5 | * | 5 | * |
6 | * Copyright (C) 2016 Samsung Electronics | ||
7 | * Chanwoo Choi <cw00.choi@samsung.com> | ||
8 | * | ||
6 | * Copyright (C) 2012 Samsung Electronics | 9 | * Copyright (C) 2012 Samsung Electronics |
7 | * MyungJoo Ham <myungjoo.ham@samsung.com> | 10 | * MyungJoo Ham <myungjoo.ham@samsung.com> |
8 | * | 11 | * |
@@ -58,7 +61,7 @@ static void adc_jack_handler(struct work_struct *work) | |||
58 | struct adc_jack_data *data = container_of(to_delayed_work(work), | 61 | struct adc_jack_data *data = container_of(to_delayed_work(work), |
59 | struct adc_jack_data, | 62 | struct adc_jack_data, |
60 | handler); | 63 | handler); |
61 | u32 state = 0; | 64 | struct adc_jack_cond *def; |
62 | int ret, adc_val; | 65 | int ret, adc_val; |
63 | int i; | 66 | int i; |
64 | 67 | ||
@@ -70,17 +73,18 @@ static void adc_jack_handler(struct work_struct *work) | |||
70 | 73 | ||
71 | /* Get state from adc value with adc_conditions */ | 74 | /* Get state from adc value with adc_conditions */ |
72 | for (i = 0; i < data->num_conditions; i++) { | 75 | for (i = 0; i < data->num_conditions; i++) { |
73 | struct adc_jack_cond *def = &data->adc_conditions[i]; | 76 | def = &data->adc_conditions[i]; |
74 | if (!def->state) | ||
75 | break; | ||
76 | if (def->min_adc <= adc_val && def->max_adc >= adc_val) { | 77 | if (def->min_adc <= adc_val && def->max_adc >= adc_val) { |
77 | state = def->state; | 78 | extcon_set_state_sync(data->edev, def->id, true); |
78 | break; | 79 | return; |
79 | } | 80 | } |
80 | } | 81 | } |
81 | /* if no def has met, it means state = 0 (no cables attached) */ | ||
82 | 82 | ||
83 | extcon_set_state(data->edev, state); | 83 | /* Set the detached state if adc value is not included in the range */ |
84 | for (i = 0; i < data->num_conditions; i++) { | ||
85 | def = &data->adc_conditions[i]; | ||
86 | extcon_set_state_sync(data->edev, def->id, false); | ||
87 | } | ||
84 | } | 88 | } |
85 | 89 | ||
86 | static irqreturn_t adc_jack_irq_thread(int irq, void *_data) | 90 | static irqreturn_t adc_jack_irq_thread(int irq, void *_data) |
@@ -114,16 +118,14 @@ static int adc_jack_probe(struct platform_device *pdev) | |||
114 | return -ENOMEM; | 118 | return -ENOMEM; |
115 | } | 119 | } |
116 | 120 | ||
117 | if (!pdata->adc_conditions || | 121 | if (!pdata->adc_conditions) { |
118 | !pdata->adc_conditions[0].state) { | ||
119 | dev_err(&pdev->dev, "error: adc_conditions not defined.\n"); | 122 | dev_err(&pdev->dev, "error: adc_conditions not defined.\n"); |
120 | return -EINVAL; | 123 | return -EINVAL; |
121 | } | 124 | } |
122 | data->adc_conditions = pdata->adc_conditions; | 125 | data->adc_conditions = pdata->adc_conditions; |
123 | 126 | ||
124 | /* Check the length of array and set num_conditions */ | 127 | /* Check the length of array and set num_conditions */ |
125 | for (i = 0; data->adc_conditions[i].state; i++) | 128 | for (i = 0; data->adc_conditions[i].id != EXTCON_NONE; i++); |
126 | ; | ||
127 | data->num_conditions = i; | 129 | data->num_conditions = i; |
128 | 130 | ||
129 | data->chan = iio_channel_get(&pdev->dev, pdata->consumer_channel); | 131 | data->chan = iio_channel_get(&pdev->dev, pdata->consumer_channel); |
@@ -158,6 +160,7 @@ static int adc_jack_probe(struct platform_device *pdev) | |||
158 | if (data->wakeup_source) | 160 | if (data->wakeup_source) |
159 | device_init_wakeup(&pdev->dev, 1); | 161 | device_init_wakeup(&pdev->dev, 1); |
160 | 162 | ||
163 | adc_jack_handler(&data->handler.work); | ||
161 | return 0; | 164 | return 0; |
162 | } | 165 | } |
163 | 166 | ||
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 1d8e0a57bd51..56e6c4c7c60d 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -183,7 +183,7 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, | |||
183 | if (clamp) | 183 | if (clamp) |
184 | val = ARIZONA_RMV_SHRT_HP1L; | 184 | val = ARIZONA_RMV_SHRT_HP1L; |
185 | break; | 185 | break; |
186 | }; | 186 | } |
187 | 187 | ||
188 | snd_soc_dapm_mutex_lock(arizona->dapm); | 188 | snd_soc_dapm_mutex_lock(arizona->dapm); |
189 | 189 | ||
@@ -614,7 +614,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) | |||
614 | } | 614 | } |
615 | 615 | ||
616 | /* If the cable was removed while measuring ignore the result */ | 616 | /* If the cable was removed while measuring ignore the result */ |
617 | ret = extcon_get_cable_state_(info->edev, EXTCON_MECHANICAL); | 617 | ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); |
618 | if (ret < 0) { | 618 | if (ret < 0) { |
619 | dev_err(arizona->dev, "Failed to check cable state: %d\n", | 619 | dev_err(arizona->dev, "Failed to check cable state: %d\n", |
620 | ret); | 620 | ret); |
@@ -649,7 +649,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) | |||
649 | else | 649 | else |
650 | report = EXTCON_JACK_HEADPHONE; | 650 | report = EXTCON_JACK_HEADPHONE; |
651 | 651 | ||
652 | ret = extcon_set_cable_state_(info->edev, report, true); | 652 | ret = extcon_set_state_sync(info->edev, report, true); |
653 | if (ret != 0) | 653 | if (ret != 0) |
654 | dev_err(arizona->dev, "Failed to report HP/line: %d\n", | 654 | dev_err(arizona->dev, "Failed to report HP/line: %d\n", |
655 | ret); | 655 | ret); |
@@ -732,7 +732,7 @@ err: | |||
732 | ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); | 732 | ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); |
733 | 733 | ||
734 | /* Just report headphone */ | 734 | /* Just report headphone */ |
735 | ret = extcon_set_cable_state_(info->edev, EXTCON_JACK_HEADPHONE, true); | 735 | ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true); |
736 | if (ret != 0) | 736 | if (ret != 0) |
737 | dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); | 737 | dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); |
738 | 738 | ||
@@ -789,7 +789,7 @@ err: | |||
789 | ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); | 789 | ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); |
790 | 790 | ||
791 | /* Just report headphone */ | 791 | /* Just report headphone */ |
792 | ret = extcon_set_cable_state_(info->edev, EXTCON_JACK_HEADPHONE, true); | 792 | ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true); |
793 | if (ret != 0) | 793 | if (ret != 0) |
794 | dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); | 794 | dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); |
795 | 795 | ||
@@ -829,7 +829,7 @@ static void arizona_micd_detect(struct work_struct *work) | |||
829 | mutex_lock(&info->lock); | 829 | mutex_lock(&info->lock); |
830 | 830 | ||
831 | /* If the cable was removed while measuring ignore the result */ | 831 | /* If the cable was removed while measuring ignore the result */ |
832 | ret = extcon_get_cable_state_(info->edev, EXTCON_MECHANICAL); | 832 | ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); |
833 | if (ret < 0) { | 833 | if (ret < 0) { |
834 | dev_err(arizona->dev, "Failed to check cable state: %d\n", | 834 | dev_err(arizona->dev, "Failed to check cable state: %d\n", |
835 | ret); | 835 | ret); |
@@ -914,7 +914,7 @@ static void arizona_micd_detect(struct work_struct *work) | |||
914 | 914 | ||
915 | arizona_identify_headphone(info); | 915 | arizona_identify_headphone(info); |
916 | 916 | ||
917 | ret = extcon_set_cable_state_(info->edev, | 917 | ret = extcon_set_state_sync(info->edev, |
918 | EXTCON_JACK_MICROPHONE, true); | 918 | EXTCON_JACK_MICROPHONE, true); |
919 | if (ret != 0) | 919 | if (ret != 0) |
920 | dev_err(arizona->dev, "Headset report failed: %d\n", | 920 | dev_err(arizona->dev, "Headset report failed: %d\n", |
@@ -1108,7 +1108,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
1108 | 1108 | ||
1109 | if (info->last_jackdet == present) { | 1109 | if (info->last_jackdet == present) { |
1110 | dev_dbg(arizona->dev, "Detected jack\n"); | 1110 | dev_dbg(arizona->dev, "Detected jack\n"); |
1111 | ret = extcon_set_cable_state_(info->edev, | 1111 | ret = extcon_set_state_sync(info->edev, |
1112 | EXTCON_MECHANICAL, true); | 1112 | EXTCON_MECHANICAL, true); |
1113 | 1113 | ||
1114 | if (ret != 0) | 1114 | if (ret != 0) |
@@ -1149,10 +1149,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
1149 | info->micd_ranges[i].key, 0); | 1149 | info->micd_ranges[i].key, 0); |
1150 | input_sync(info->input); | 1150 | input_sync(info->input); |
1151 | 1151 | ||
1152 | ret = extcon_update_state(info->edev, 0xffffffff, 0); | 1152 | for (i = 0; i < ARRAY_SIZE(arizona_cable) - 1; i++) { |
1153 | if (ret != 0) | 1153 | ret = extcon_set_state_sync(info->edev, |
1154 | dev_err(arizona->dev, "Removal report failed: %d\n", | 1154 | arizona_cable[i], false); |
1155 | ret); | 1155 | if (ret != 0) |
1156 | dev_err(arizona->dev, | ||
1157 | "Removal report failed: %d\n", ret); | ||
1158 | } | ||
1156 | 1159 | ||
1157 | regmap_update_bits(arizona->regmap, | 1160 | regmap_update_bits(arizona->regmap, |
1158 | ARIZONA_JACK_DETECT_DEBOUNCE, | 1161 | ARIZONA_JACK_DETECT_DEBOUNCE, |
diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c index fd55c2f2080a..42f41e808292 100644 --- a/drivers/extcon/extcon-axp288.c +++ b/drivers/extcon/extcon-axp288.c | |||
@@ -189,19 +189,19 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) | |||
189 | 189 | ||
190 | switch (chrg_type) { | 190 | switch (chrg_type) { |
191 | case DET_STAT_SDP: | 191 | case DET_STAT_SDP: |
192 | dev_dbg(info->dev, "sdp cable is connecetd\n"); | 192 | dev_dbg(info->dev, "sdp cable is connected\n"); |
193 | notify_otg = true; | 193 | notify_otg = true; |
194 | notify_charger = true; | 194 | notify_charger = true; |
195 | cable = EXTCON_CHG_USB_SDP; | 195 | cable = EXTCON_CHG_USB_SDP; |
196 | break; | 196 | break; |
197 | case DET_STAT_CDP: | 197 | case DET_STAT_CDP: |
198 | dev_dbg(info->dev, "cdp cable is connecetd\n"); | 198 | dev_dbg(info->dev, "cdp cable is connected\n"); |
199 | notify_otg = true; | 199 | notify_otg = true; |
200 | notify_charger = true; | 200 | notify_charger = true; |
201 | cable = EXTCON_CHG_USB_CDP; | 201 | cable = EXTCON_CHG_USB_CDP; |
202 | break; | 202 | break; |
203 | case DET_STAT_DCP: | 203 | case DET_STAT_DCP: |
204 | dev_dbg(info->dev, "dcp cable is connecetd\n"); | 204 | dev_dbg(info->dev, "dcp cable is connected\n"); |
205 | notify_charger = true; | 205 | notify_charger = true; |
206 | cable = EXTCON_CHG_USB_DCP; | 206 | cable = EXTCON_CHG_USB_DCP; |
207 | break; | 207 | break; |
@@ -226,7 +226,7 @@ notify_otg: | |||
226 | } | 226 | } |
227 | 227 | ||
228 | if (notify_charger) | 228 | if (notify_charger) |
229 | extcon_set_cable_state_(info->edev, cable, vbus_attach); | 229 | extcon_set_state_sync(info->edev, cable, vbus_attach); |
230 | 230 | ||
231 | /* Clear the flags on disconnect event */ | 231 | /* Clear the flags on disconnect event */ |
232 | if (!vbus_attach) | 232 | if (!vbus_attach) |
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index d023789f0fda..ebed22f22d75 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c | |||
@@ -49,7 +49,8 @@ static void gpio_extcon_work(struct work_struct *work) | |||
49 | state = gpiod_get_value_cansleep(data->id_gpiod); | 49 | state = gpiod_get_value_cansleep(data->id_gpiod); |
50 | if (data->pdata->gpio_active_low) | 50 | if (data->pdata->gpio_active_low) |
51 | state = !state; | 51 | state = !state; |
52 | extcon_set_state(data->edev, state); | 52 | |
53 | extcon_set_state_sync(data->edev, data->pdata->extcon_id, state); | ||
53 | } | 54 | } |
54 | 55 | ||
55 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | 56 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) |
diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c index 852a7112f451..12e26c4e7763 100644 --- a/drivers/extcon/extcon-max14577.c +++ b/drivers/extcon/extcon-max14577.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2013,2014 Samsung Electronics | 4 | * Copyright (C) 2013,2014 Samsung Electronics |
5 | * Chanwoo Choi <cw00.choi@samsung.com> | 5 | * Chanwoo Choi <cw00.choi@samsung.com> |
6 | * Krzysztof Kozlowski <k.kozlowski@samsung.com> | 6 | * Krzysztof Kozlowski <krzk@kernel.org> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -357,7 +357,7 @@ static int max14577_muic_jig_handler(struct max14577_muic_info *info, | |||
357 | if (ret < 0) | 357 | if (ret < 0) |
358 | return ret; | 358 | return ret; |
359 | 359 | ||
360 | extcon_set_cable_state_(info->edev, EXTCON_JIG, attached); | 360 | extcon_set_state_sync(info->edev, EXTCON_JIG, attached); |
361 | 361 | ||
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
@@ -454,24 +454,24 @@ static int max14577_muic_chg_handler(struct max14577_muic_info *info) | |||
454 | if (ret < 0) | 454 | if (ret < 0) |
455 | return ret; | 455 | return ret; |
456 | 456 | ||
457 | extcon_set_cable_state_(info->edev, EXTCON_USB, attached); | 457 | extcon_set_state_sync(info->edev, EXTCON_USB, attached); |
458 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 458 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
459 | attached); | 459 | attached); |
460 | break; | 460 | break; |
461 | case MAX14577_CHARGER_TYPE_DEDICATED_CHG: | 461 | case MAX14577_CHARGER_TYPE_DEDICATED_CHG: |
462 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 462 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
463 | attached); | 463 | attached); |
464 | break; | 464 | break; |
465 | case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: | 465 | case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: |
466 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, | 466 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP, |
467 | attached); | 467 | attached); |
468 | break; | 468 | break; |
469 | case MAX14577_CHARGER_TYPE_SPECIAL_500MA: | 469 | case MAX14577_CHARGER_TYPE_SPECIAL_500MA: |
470 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, | 470 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW, |
471 | attached); | 471 | attached); |
472 | break; | 472 | break; |
473 | case MAX14577_CHARGER_TYPE_SPECIAL_1A: | 473 | case MAX14577_CHARGER_TYPE_SPECIAL_1A: |
474 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, | 474 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST, |
475 | attached); | 475 | attached); |
476 | break; | 476 | break; |
477 | case MAX14577_CHARGER_TYPE_NONE: | 477 | case MAX14577_CHARGER_TYPE_NONE: |
@@ -791,6 +791,6 @@ static struct platform_driver max14577_muic_driver = { | |||
791 | module_platform_driver(max14577_muic_driver); | 791 | module_platform_driver(max14577_muic_driver); |
792 | 792 | ||
793 | MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver"); | 793 | MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver"); |
794 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>"); | 794 | MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <krzk@kernel.org>"); |
795 | MODULE_LICENSE("GPL"); | 795 | MODULE_LICENSE("GPL"); |
796 | MODULE_ALIAS("platform:extcon-max14577"); | 796 | MODULE_ALIAS("platform:extcon-max14577"); |
diff --git a/drivers/extcon/extcon-max3355.c b/drivers/extcon/extcon-max3355.c index c24abec5d06c..533e16a952b8 100644 --- a/drivers/extcon/extcon-max3355.c +++ b/drivers/extcon/extcon-max3355.c | |||
@@ -39,16 +39,16 @@ static irqreturn_t max3355_id_irq(int irq, void *dev_id) | |||
39 | * As we don't have event for USB peripheral cable attached, | 39 | * As we don't have event for USB peripheral cable attached, |
40 | * we simulate USB peripheral attach here. | 40 | * we simulate USB peripheral attach here. |
41 | */ | 41 | */ |
42 | extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, false); | 42 | extcon_set_state_sync(data->edev, EXTCON_USB_HOST, false); |
43 | extcon_set_cable_state_(data->edev, EXTCON_USB, true); | 43 | extcon_set_state_sync(data->edev, EXTCON_USB, true); |
44 | } else { | 44 | } else { |
45 | /* | 45 | /* |
46 | * ID = 0 means USB HOST cable attached. | 46 | * ID = 0 means USB HOST cable attached. |
47 | * As we don't have event for USB peripheral cable detached, | 47 | * As we don't have event for USB peripheral cable detached, |
48 | * we simulate USB peripheral detach here. | 48 | * we simulate USB peripheral detach here. |
49 | */ | 49 | */ |
50 | extcon_set_cable_state_(data->edev, EXTCON_USB, false); | 50 | extcon_set_state_sync(data->edev, EXTCON_USB, false); |
51 | extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, true); | 51 | extcon_set_state_sync(data->edev, EXTCON_USB_HOST, true); |
52 | } | 52 | } |
53 | 53 | ||
54 | return IRQ_HANDLED; | 54 | return IRQ_HANDLED; |
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index f17cb76b567c..68dbcb814b2f 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c | |||
@@ -505,8 +505,8 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, | |||
505 | if (ret < 0) | 505 | if (ret < 0) |
506 | return ret; | 506 | return ret; |
507 | 507 | ||
508 | extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached); | 508 | extcon_set_state_sync(info->edev, EXTCON_DOCK, attached); |
509 | extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); | 509 | extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); |
510 | goto out; | 510 | goto out; |
511 | case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ | 511 | case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ |
512 | dock_id = EXTCON_DOCK; | 512 | dock_id = EXTCON_DOCK; |
@@ -514,8 +514,8 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, | |||
514 | case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */ | 514 | case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */ |
515 | dock_id = EXTCON_DOCK; | 515 | dock_id = EXTCON_DOCK; |
516 | if (!attached) { | 516 | if (!attached) { |
517 | extcon_set_cable_state_(info->edev, EXTCON_USB, false); | 517 | extcon_set_state_sync(info->edev, EXTCON_USB, false); |
518 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 518 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
519 | false); | 519 | false); |
520 | } | 520 | } |
521 | break; | 521 | break; |
@@ -530,7 +530,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, | |||
530 | attached); | 530 | attached); |
531 | if (ret < 0) | 531 | if (ret < 0) |
532 | return ret; | 532 | return ret; |
533 | extcon_set_cable_state_(info->edev, dock_id, attached); | 533 | extcon_set_state_sync(info->edev, dock_id, attached); |
534 | 534 | ||
535 | out: | 535 | out: |
536 | return 0; | 536 | return 0; |
@@ -596,7 +596,7 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info) | |||
596 | attached); | 596 | attached); |
597 | if (ret < 0) | 597 | if (ret < 0) |
598 | return ret; | 598 | return ret; |
599 | extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached); | 599 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached); |
600 | break; | 600 | break; |
601 | case MAX77693_MUIC_GND_AV_CABLE_LOAD: | 601 | case MAX77693_MUIC_GND_AV_CABLE_LOAD: |
602 | /* Audio Video Cable with load, PATH:AUDIO */ | 602 | /* Audio Video Cable with load, PATH:AUDIO */ |
@@ -604,14 +604,14 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info) | |||
604 | attached); | 604 | attached); |
605 | if (ret < 0) | 605 | if (ret < 0) |
606 | return ret; | 606 | return ret; |
607 | extcon_set_cable_state_(info->edev, EXTCON_USB, attached); | 607 | extcon_set_state_sync(info->edev, EXTCON_USB, attached); |
608 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 608 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
609 | attached); | 609 | attached); |
610 | break; | 610 | break; |
611 | case MAX77693_MUIC_GND_MHL: | 611 | case MAX77693_MUIC_GND_MHL: |
612 | case MAX77693_MUIC_GND_MHL_VB: | 612 | case MAX77693_MUIC_GND_MHL_VB: |
613 | /* MHL or MHL with USB/TA cable */ | 613 | /* MHL or MHL with USB/TA cable */ |
614 | extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); | 614 | extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); |
615 | break; | 615 | break; |
616 | default: | 616 | default: |
617 | dev_err(info->dev, "failed to detect %s cable of gnd type\n", | 617 | dev_err(info->dev, "failed to detect %s cable of gnd type\n", |
@@ -653,7 +653,7 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info, | |||
653 | if (ret < 0) | 653 | if (ret < 0) |
654 | return ret; | 654 | return ret; |
655 | 655 | ||
656 | extcon_set_cable_state_(info->edev, EXTCON_JIG, attached); | 656 | extcon_set_state_sync(info->edev, EXTCON_JIG, attached); |
657 | 657 | ||
658 | return 0; | 658 | return 0; |
659 | } | 659 | } |
@@ -807,10 +807,10 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) | |||
807 | * - Support charging through micro-usb port without | 807 | * - Support charging through micro-usb port without |
808 | * data connection | 808 | * data connection |
809 | */ | 809 | */ |
810 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 810 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
811 | attached); | 811 | attached); |
812 | if (!cable_attached) | 812 | if (!cable_attached) |
813 | extcon_set_cable_state_(info->edev, | 813 | extcon_set_state_sync(info->edev, |
814 | EXTCON_DISP_MHL, cable_attached); | 814 | EXTCON_DISP_MHL, cable_attached); |
815 | break; | 815 | break; |
816 | } | 816 | } |
@@ -834,13 +834,13 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) | |||
834 | * - Support charging through micro-usb port without | 834 | * - Support charging through micro-usb port without |
835 | * data connection. | 835 | * data connection. |
836 | */ | 836 | */ |
837 | extcon_set_cable_state_(info->edev, EXTCON_USB, | 837 | extcon_set_state_sync(info->edev, EXTCON_USB, |
838 | attached); | 838 | attached); |
839 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 839 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
840 | attached); | 840 | attached); |
841 | 841 | ||
842 | if (!cable_attached) | 842 | if (!cable_attached) |
843 | extcon_set_cable_state_(info->edev, EXTCON_DOCK, | 843 | extcon_set_state_sync(info->edev, EXTCON_DOCK, |
844 | cable_attached); | 844 | cable_attached); |
845 | break; | 845 | break; |
846 | case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */ | 846 | case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */ |
@@ -869,9 +869,9 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) | |||
869 | if (ret < 0) | 869 | if (ret < 0) |
870 | return ret; | 870 | return ret; |
871 | 871 | ||
872 | extcon_set_cable_state_(info->edev, EXTCON_DOCK, | 872 | extcon_set_state_sync(info->edev, EXTCON_DOCK, |
873 | attached); | 873 | attached); |
874 | extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, | 874 | extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, |
875 | attached); | 875 | attached); |
876 | break; | 876 | break; |
877 | } | 877 | } |
@@ -905,28 +905,28 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) | |||
905 | if (ret < 0) | 905 | if (ret < 0) |
906 | return ret; | 906 | return ret; |
907 | 907 | ||
908 | extcon_set_cable_state_(info->edev, EXTCON_USB, | 908 | extcon_set_state_sync(info->edev, EXTCON_USB, |
909 | attached); | 909 | attached); |
910 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 910 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
911 | attached); | 911 | attached); |
912 | break; | 912 | break; |
913 | case MAX77693_CHARGER_TYPE_DEDICATED_CHG: | 913 | case MAX77693_CHARGER_TYPE_DEDICATED_CHG: |
914 | /* Only TA cable */ | 914 | /* Only TA cable */ |
915 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 915 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
916 | attached); | 916 | attached); |
917 | break; | 917 | break; |
918 | } | 918 | } |
919 | break; | 919 | break; |
920 | case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT: | 920 | case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT: |
921 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, | 921 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP, |
922 | attached); | 922 | attached); |
923 | break; | 923 | break; |
924 | case MAX77693_CHARGER_TYPE_APPLE_500MA: | 924 | case MAX77693_CHARGER_TYPE_APPLE_500MA: |
925 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, | 925 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW, |
926 | attached); | 926 | attached); |
927 | break; | 927 | break; |
928 | case MAX77693_CHARGER_TYPE_APPLE_1A_2A: | 928 | case MAX77693_CHARGER_TYPE_APPLE_1A_2A: |
929 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, | 929 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST, |
930 | attached); | 930 | attached); |
931 | break; | 931 | break; |
932 | case MAX77693_CHARGER_TYPE_DEAD_BATTERY: | 932 | case MAX77693_CHARGER_TYPE_DEAD_BATTERY: |
diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c index b188bd650efa..5d11fdf36e94 100644 --- a/drivers/extcon/extcon-max77843.c +++ b/drivers/extcon/extcon-max77843.c | |||
@@ -346,7 +346,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) | |||
346 | if (ret < 0) | 346 | if (ret < 0) |
347 | return ret; | 347 | return ret; |
348 | 348 | ||
349 | extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached); | 349 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached); |
350 | break; | 350 | break; |
351 | case MAX77843_MUIC_GND_MHL_VB: | 351 | case MAX77843_MUIC_GND_MHL_VB: |
352 | case MAX77843_MUIC_GND_MHL: | 352 | case MAX77843_MUIC_GND_MHL: |
@@ -356,7 +356,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) | |||
356 | if (ret < 0) | 356 | if (ret < 0) |
357 | return ret; | 357 | return ret; |
358 | 358 | ||
359 | extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); | 359 | extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); |
360 | break; | 360 | break; |
361 | default: | 361 | default: |
362 | dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n", | 362 | dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n", |
@@ -392,7 +392,7 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info, | |||
392 | if (ret < 0) | 392 | if (ret < 0) |
393 | return ret; | 393 | return ret; |
394 | 394 | ||
395 | extcon_set_cable_state_(info->edev, EXTCON_JIG, attached); | 395 | extcon_set_state_sync(info->edev, EXTCON_JIG, attached); |
396 | 396 | ||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
@@ -486,8 +486,8 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
486 | if (ret < 0) | 486 | if (ret < 0) |
487 | return ret; | 487 | return ret; |
488 | 488 | ||
489 | extcon_set_cable_state_(info->edev, EXTCON_USB, attached); | 489 | extcon_set_state_sync(info->edev, EXTCON_USB, attached); |
490 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 490 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
491 | attached); | 491 | attached); |
492 | break; | 492 | break; |
493 | case MAX77843_MUIC_CHG_DOWNSTREAM: | 493 | case MAX77843_MUIC_CHG_DOWNSTREAM: |
@@ -497,7 +497,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
497 | if (ret < 0) | 497 | if (ret < 0) |
498 | return ret; | 498 | return ret; |
499 | 499 | ||
500 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, | 500 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP, |
501 | attached); | 501 | attached); |
502 | break; | 502 | break; |
503 | case MAX77843_MUIC_CHG_DEDICATED: | 503 | case MAX77843_MUIC_CHG_DEDICATED: |
@@ -507,7 +507,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
507 | if (ret < 0) | 507 | if (ret < 0) |
508 | return ret; | 508 | return ret; |
509 | 509 | ||
510 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 510 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
511 | attached); | 511 | attached); |
512 | break; | 512 | break; |
513 | case MAX77843_MUIC_CHG_SPECIAL_500MA: | 513 | case MAX77843_MUIC_CHG_SPECIAL_500MA: |
@@ -517,7 +517,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
517 | if (ret < 0) | 517 | if (ret < 0) |
518 | return ret; | 518 | return ret; |
519 | 519 | ||
520 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, | 520 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW, |
521 | attached); | 521 | attached); |
522 | break; | 522 | break; |
523 | case MAX77843_MUIC_CHG_SPECIAL_1A: | 523 | case MAX77843_MUIC_CHG_SPECIAL_1A: |
@@ -527,7 +527,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
527 | if (ret < 0) | 527 | if (ret < 0) |
528 | return ret; | 528 | return ret; |
529 | 529 | ||
530 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, | 530 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST, |
531 | attached); | 531 | attached); |
532 | break; | 532 | break; |
533 | case MAX77843_MUIC_CHG_GND: | 533 | case MAX77843_MUIC_CHG_GND: |
@@ -536,10 +536,10 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) | |||
536 | 536 | ||
537 | /* Charger cable on MHL accessory is attach or detach */ | 537 | /* Charger cable on MHL accessory is attach or detach */ |
538 | if (gnd_type == MAX77843_MUIC_GND_MHL_VB) | 538 | if (gnd_type == MAX77843_MUIC_GND_MHL_VB) |
539 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 539 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
540 | true); | 540 | true); |
541 | else if (gnd_type == MAX77843_MUIC_GND_MHL) | 541 | else if (gnd_type == MAX77843_MUIC_GND_MHL) |
542 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 542 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
543 | false); | 543 | false); |
544 | break; | 544 | break; |
545 | case MAX77843_MUIC_CHG_NONE: | 545 | case MAX77843_MUIC_CHG_NONE: |
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 9a89320d09a8..4a0612fb9c07 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c | |||
@@ -331,11 +331,11 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, | |||
331 | 331 | ||
332 | switch (usb_type) { | 332 | switch (usb_type) { |
333 | case MAX8997_USB_HOST: | 333 | case MAX8997_USB_HOST: |
334 | extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached); | 334 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached); |
335 | break; | 335 | break; |
336 | case MAX8997_USB_DEVICE: | 336 | case MAX8997_USB_DEVICE: |
337 | extcon_set_cable_state_(info->edev, EXTCON_USB, attached); | 337 | extcon_set_state_sync(info->edev, EXTCON_USB, attached); |
338 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 338 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
339 | attached); | 339 | attached); |
340 | break; | 340 | break; |
341 | default: | 341 | default: |
@@ -361,7 +361,7 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info, | |||
361 | switch (cable_type) { | 361 | switch (cable_type) { |
362 | case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: | 362 | case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: |
363 | case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: | 363 | case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: |
364 | extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached); | 364 | extcon_set_state_sync(info->edev, EXTCON_DOCK, attached); |
365 | break; | 365 | break; |
366 | default: | 366 | default: |
367 | dev_err(info->dev, "failed to detect %s dock device\n", | 367 | dev_err(info->dev, "failed to detect %s dock device\n", |
@@ -384,7 +384,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | |||
384 | return ret; | 384 | return ret; |
385 | } | 385 | } |
386 | 386 | ||
387 | extcon_set_cable_state_(info->edev, EXTCON_JIG, attached); | 387 | extcon_set_state_sync(info->edev, EXTCON_JIG, attached); |
388 | 388 | ||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
@@ -406,7 +406,7 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info) | |||
406 | return ret; | 406 | return ret; |
407 | break; | 407 | break; |
408 | case MAX8997_MUIC_ADC_MHL: | 408 | case MAX8997_MUIC_ADC_MHL: |
409 | extcon_set_cable_state_(info->edev, EXTCON_DISP_MHL, attached); | 409 | extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); |
410 | break; | 410 | break; |
411 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: | 411 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: |
412 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: | 412 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: |
@@ -489,19 +489,19 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info) | |||
489 | } | 489 | } |
490 | break; | 490 | break; |
491 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | 491 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: |
492 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_CDP, | 492 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP, |
493 | attached); | 493 | attached); |
494 | break; | 494 | break; |
495 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | 495 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: |
496 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_DCP, | 496 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, |
497 | attached); | 497 | attached); |
498 | break; | 498 | break; |
499 | case MAX8997_CHARGER_TYPE_500MA: | 499 | case MAX8997_CHARGER_TYPE_500MA: |
500 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SLOW, | 500 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW, |
501 | attached); | 501 | attached); |
502 | break; | 502 | break; |
503 | case MAX8997_CHARGER_TYPE_1A: | 503 | case MAX8997_CHARGER_TYPE_1A: |
504 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_FAST, | 504 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST, |
505 | attached); | 505 | attached); |
506 | break; | 506 | break; |
507 | default: | 507 | default: |
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c index caff46c0e214..634ba70782de 100644 --- a/drivers/extcon/extcon-palmas.c +++ b/drivers/extcon/extcon-palmas.c | |||
@@ -61,7 +61,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) | |||
61 | if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) { | 61 | if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) { |
62 | if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { | 62 | if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { |
63 | palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; | 63 | palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; |
64 | extcon_set_cable_state_(edev, EXTCON_USB, true); | 64 | extcon_set_state_sync(edev, EXTCON_USB, true); |
65 | dev_info(palmas_usb->dev, "USB cable is attached\n"); | 65 | dev_info(palmas_usb->dev, "USB cable is attached\n"); |
66 | } else { | 66 | } else { |
67 | dev_dbg(palmas_usb->dev, | 67 | dev_dbg(palmas_usb->dev, |
@@ -70,7 +70,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) | |||
70 | } else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) { | 70 | } else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) { |
71 | if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { | 71 | if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { |
72 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 72 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
73 | extcon_set_cable_state_(edev, EXTCON_USB, false); | 73 | extcon_set_state_sync(edev, EXTCON_USB, false); |
74 | dev_info(palmas_usb->dev, "USB cable is detached\n"); | 74 | dev_info(palmas_usb->dev, "USB cable is detached\n"); |
75 | } else { | 75 | } else { |
76 | dev_dbg(palmas_usb->dev, | 76 | dev_dbg(palmas_usb->dev, |
@@ -98,7 +98,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) | |||
98 | PALMAS_USB_ID_INT_LATCH_CLR, | 98 | PALMAS_USB_ID_INT_LATCH_CLR, |
99 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); | 99 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); |
100 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; | 100 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; |
101 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, true); | 101 | extcon_set_state_sync(edev, EXTCON_USB_HOST, true); |
102 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); | 102 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); |
103 | } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && | 103 | } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && |
104 | (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { | 104 | (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { |
@@ -106,17 +106,17 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) | |||
106 | PALMAS_USB_ID_INT_LATCH_CLR, | 106 | PALMAS_USB_ID_INT_LATCH_CLR, |
107 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); | 107 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); |
108 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 108 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
109 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, false); | 109 | extcon_set_state_sync(edev, EXTCON_USB_HOST, false); |
110 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | 110 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); |
111 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) && | 111 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) && |
112 | (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) { | 112 | (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) { |
113 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 113 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
114 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, false); | 114 | extcon_set_state_sync(edev, EXTCON_USB_HOST, false); |
115 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | 115 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); |
116 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && | 116 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && |
117 | (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { | 117 | (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { |
118 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; | 118 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; |
119 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, true); | 119 | extcon_set_state_sync(edev, EXTCON_USB_HOST, true); |
120 | dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); | 120 | dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); |
121 | } | 121 | } |
122 | 122 | ||
@@ -137,10 +137,10 @@ static void palmas_gpio_id_detect(struct work_struct *work) | |||
137 | id = gpiod_get_value_cansleep(palmas_usb->id_gpiod); | 137 | id = gpiod_get_value_cansleep(palmas_usb->id_gpiod); |
138 | 138 | ||
139 | if (id) { | 139 | if (id) { |
140 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, false); | 140 | extcon_set_state_sync(edev, EXTCON_USB_HOST, false); |
141 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | 141 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); |
142 | } else { | 142 | } else { |
143 | extcon_set_cable_state_(edev, EXTCON_USB_HOST, true); | 143 | extcon_set_state_sync(edev, EXTCON_USB_HOST, true); |
144 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); | 144 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); |
145 | } | 145 | } |
146 | } | 146 | } |
diff --git a/drivers/extcon/extcon-qcom-spmi-misc.c b/drivers/extcon/extcon-qcom-spmi-misc.c new file mode 100644 index 000000000000..ca957a5f4291 --- /dev/null +++ b/drivers/extcon/extcon-qcom-spmi-misc.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /** | ||
2 | * extcon-qcom-spmi-misc.c - Qualcomm USB extcon driver to support USB ID | ||
3 | * detection based on extcon-usb-gpio.c. | ||
4 | * | ||
5 | * Copyright (C) 2016 Linaro, Ltd. | ||
6 | * Stephen Boyd <stephen.boyd@linaro.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/extcon.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | |||
27 | #define USB_ID_DEBOUNCE_MS 5 /* ms */ | ||
28 | |||
29 | struct qcom_usb_extcon_info { | ||
30 | struct extcon_dev *edev; | ||
31 | int irq; | ||
32 | struct delayed_work wq_detcable; | ||
33 | unsigned long debounce_jiffies; | ||
34 | }; | ||
35 | |||
36 | static const unsigned int qcom_usb_extcon_cable[] = { | ||
37 | EXTCON_USB_HOST, | ||
38 | EXTCON_NONE, | ||
39 | }; | ||
40 | |||
41 | static void qcom_usb_extcon_detect_cable(struct work_struct *work) | ||
42 | { | ||
43 | bool id; | ||
44 | int ret; | ||
45 | struct qcom_usb_extcon_info *info = container_of(to_delayed_work(work), | ||
46 | struct qcom_usb_extcon_info, | ||
47 | wq_detcable); | ||
48 | |||
49 | /* check ID and update cable state */ | ||
50 | ret = irq_get_irqchip_state(info->irq, IRQCHIP_STATE_LINE_LEVEL, &id); | ||
51 | if (ret) | ||
52 | return; | ||
53 | |||
54 | extcon_set_state(info->edev, EXTCON_USB_HOST, !id); | ||
55 | } | ||
56 | |||
57 | static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id) | ||
58 | { | ||
59 | struct qcom_usb_extcon_info *info = dev_id; | ||
60 | |||
61 | queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, | ||
62 | info->debounce_jiffies); | ||
63 | |||
64 | return IRQ_HANDLED; | ||
65 | } | ||
66 | |||
67 | static int qcom_usb_extcon_probe(struct platform_device *pdev) | ||
68 | { | ||
69 | struct device *dev = &pdev->dev; | ||
70 | struct qcom_usb_extcon_info *info; | ||
71 | int ret; | ||
72 | |||
73 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | ||
74 | if (!info) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | info->edev = devm_extcon_dev_allocate(dev, qcom_usb_extcon_cable); | ||
78 | if (IS_ERR(info->edev)) { | ||
79 | dev_err(dev, "failed to allocate extcon device\n"); | ||
80 | return -ENOMEM; | ||
81 | } | ||
82 | |||
83 | ret = devm_extcon_dev_register(dev, info->edev); | ||
84 | if (ret < 0) { | ||
85 | dev_err(dev, "failed to register extcon device\n"); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | info->debounce_jiffies = msecs_to_jiffies(USB_ID_DEBOUNCE_MS); | ||
90 | INIT_DELAYED_WORK(&info->wq_detcable, qcom_usb_extcon_detect_cable); | ||
91 | |||
92 | info->irq = platform_get_irq_byname(pdev, "usb_id"); | ||
93 | if (info->irq < 0) | ||
94 | return info->irq; | ||
95 | |||
96 | ret = devm_request_threaded_irq(dev, info->irq, NULL, | ||
97 | qcom_usb_irq_handler, | ||
98 | IRQF_TRIGGER_RISING | | ||
99 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
100 | pdev->name, info); | ||
101 | if (ret < 0) { | ||
102 | dev_err(dev, "failed to request handler for ID IRQ\n"); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | platform_set_drvdata(pdev, info); | ||
107 | device_init_wakeup(dev, 1); | ||
108 | |||
109 | /* Perform initial detection */ | ||
110 | qcom_usb_extcon_detect_cable(&info->wq_detcable.work); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int qcom_usb_extcon_remove(struct platform_device *pdev) | ||
116 | { | ||
117 | struct qcom_usb_extcon_info *info = platform_get_drvdata(pdev); | ||
118 | |||
119 | cancel_delayed_work_sync(&info->wq_detcable); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | #ifdef CONFIG_PM_SLEEP | ||
125 | static int qcom_usb_extcon_suspend(struct device *dev) | ||
126 | { | ||
127 | struct qcom_usb_extcon_info *info = dev_get_drvdata(dev); | ||
128 | int ret = 0; | ||
129 | |||
130 | if (device_may_wakeup(dev)) | ||
131 | ret = enable_irq_wake(info->irq); | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static int qcom_usb_extcon_resume(struct device *dev) | ||
137 | { | ||
138 | struct qcom_usb_extcon_info *info = dev_get_drvdata(dev); | ||
139 | int ret = 0; | ||
140 | |||
141 | if (device_may_wakeup(dev)) | ||
142 | ret = disable_irq_wake(info->irq); | ||
143 | |||
144 | return ret; | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 | static SIMPLE_DEV_PM_OPS(qcom_usb_extcon_pm_ops, | ||
149 | qcom_usb_extcon_suspend, qcom_usb_extcon_resume); | ||
150 | |||
151 | static const struct of_device_id qcom_usb_extcon_dt_match[] = { | ||
152 | { .compatible = "qcom,pm8941-misc", }, | ||
153 | { } | ||
154 | }; | ||
155 | MODULE_DEVICE_TABLE(of, qcom_usb_extcon_dt_match); | ||
156 | |||
157 | static struct platform_driver qcom_usb_extcon_driver = { | ||
158 | .probe = qcom_usb_extcon_probe, | ||
159 | .remove = qcom_usb_extcon_remove, | ||
160 | .driver = { | ||
161 | .name = "extcon-pm8941-misc", | ||
162 | .pm = &qcom_usb_extcon_pm_ops, | ||
163 | .of_match_table = qcom_usb_extcon_dt_match, | ||
164 | }, | ||
165 | }; | ||
166 | module_platform_driver(qcom_usb_extcon_driver); | ||
167 | |||
168 | MODULE_DESCRIPTION("QCOM USB ID extcon driver"); | ||
169 | MODULE_AUTHOR("Stephen Boyd <stephen.boyd@linaro.org>"); | ||
170 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 97e074d70eca..174c388739ea 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c | |||
@@ -398,9 +398,9 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, | |||
398 | return ret; | 398 | return ret; |
399 | 399 | ||
400 | /* Change the state of external accessory */ | 400 | /* Change the state of external accessory */ |
401 | extcon_set_cable_state_(info->edev, id, attached); | 401 | extcon_set_state_sync(info->edev, id, attached); |
402 | if (id == EXTCON_USB) | 402 | if (id == EXTCON_USB) |
403 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 403 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
404 | attached); | 404 | attached); |
405 | 405 | ||
406 | return 0; | 406 | return 0; |
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index df769a17e736..b22325688503 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c | |||
@@ -411,9 +411,9 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, | |||
411 | return ret; | 411 | return ret; |
412 | 412 | ||
413 | /* Change the state of external accessory */ | 413 | /* Change the state of external accessory */ |
414 | extcon_set_cable_state_(info->edev, id, attached); | 414 | extcon_set_state_sync(info->edev, id, attached); |
415 | if (id == EXTCON_USB) | 415 | if (id == EXTCON_USB) |
416 | extcon_set_cable_state_(info->edev, EXTCON_CHG_USB_SDP, | 416 | extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, |
417 | attached); | 417 | attached); |
418 | 418 | ||
419 | return 0; | 419 | return 0; |
diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index 2512660dc4b9..a27d350f69e3 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c | |||
@@ -63,16 +63,16 @@ static void usb_extcon_detect_cable(struct work_struct *work) | |||
63 | * As we don't have event for USB peripheral cable attached, | 63 | * As we don't have event for USB peripheral cable attached, |
64 | * we simulate USB peripheral attach here. | 64 | * we simulate USB peripheral attach here. |
65 | */ | 65 | */ |
66 | extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, false); | 66 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false); |
67 | extcon_set_cable_state_(info->edev, EXTCON_USB, true); | 67 | extcon_set_state_sync(info->edev, EXTCON_USB, true); |
68 | } else { | 68 | } else { |
69 | /* | 69 | /* |
70 | * ID = 0 means USB HOST cable attached. | 70 | * ID = 0 means USB HOST cable attached. |
71 | * As we don't have event for USB peripheral cable detached, | 71 | * As we don't have event for USB peripheral cable detached, |
72 | * we simulate USB peripheral detach here. | 72 | * we simulate USB peripheral detach here. |
73 | */ | 73 | */ |
74 | extcon_set_cable_state_(info->edev, EXTCON_USB, false); | 74 | extcon_set_state_sync(info->edev, EXTCON_USB, false); |
75 | extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, true); | 75 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true); |
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 8682efc0f57b..78298460d168 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c | |||
@@ -38,43 +38,159 @@ | |||
38 | #define SUPPORTED_CABLE_MAX 32 | 38 | #define SUPPORTED_CABLE_MAX 32 |
39 | #define CABLE_NAME_MAX 30 | 39 | #define CABLE_NAME_MAX 30 |
40 | 40 | ||
41 | static const char *extcon_name[] = { | 41 | struct __extcon_info { |
42 | [EXTCON_NONE] = "NONE", | 42 | unsigned int type; |
43 | unsigned int id; | ||
44 | const char *name; | ||
45 | |||
46 | } extcon_info[] = { | ||
47 | [EXTCON_NONE] = { | ||
48 | .type = EXTCON_TYPE_MISC, | ||
49 | .id = EXTCON_NONE, | ||
50 | .name = "NONE", | ||
51 | }, | ||
43 | 52 | ||
44 | /* USB external connector */ | 53 | /* USB external connector */ |
45 | [EXTCON_USB] = "USB", | 54 | [EXTCON_USB] = { |
46 | [EXTCON_USB_HOST] = "USB-HOST", | 55 | .type = EXTCON_TYPE_USB, |
56 | .id = EXTCON_USB, | ||
57 | .name = "USB", | ||
58 | }, | ||
59 | [EXTCON_USB_HOST] = { | ||
60 | .type = EXTCON_TYPE_USB, | ||
61 | .id = EXTCON_USB_HOST, | ||
62 | .name = "USB_HOST", | ||
63 | }, | ||
47 | 64 | ||
48 | /* Charging external connector */ | 65 | /* Charging external connector */ |
49 | [EXTCON_CHG_USB_SDP] = "SDP", | 66 | [EXTCON_CHG_USB_SDP] = { |
50 | [EXTCON_CHG_USB_DCP] = "DCP", | 67 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, |
51 | [EXTCON_CHG_USB_CDP] = "CDP", | 68 | .id = EXTCON_CHG_USB_SDP, |
52 | [EXTCON_CHG_USB_ACA] = "ACA", | 69 | .name = "SDP", |
53 | [EXTCON_CHG_USB_FAST] = "FAST-CHARGER", | 70 | }, |
54 | [EXTCON_CHG_USB_SLOW] = "SLOW-CHARGER", | 71 | [EXTCON_CHG_USB_DCP] = { |
72 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, | ||
73 | .id = EXTCON_CHG_USB_DCP, | ||
74 | .name = "DCP", | ||
75 | }, | ||
76 | [EXTCON_CHG_USB_CDP] = { | ||
77 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, | ||
78 | .id = EXTCON_CHG_USB_CDP, | ||
79 | .name = "CDP", | ||
80 | }, | ||
81 | [EXTCON_CHG_USB_ACA] = { | ||
82 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, | ||
83 | .id = EXTCON_CHG_USB_ACA, | ||
84 | .name = "ACA", | ||
85 | }, | ||
86 | [EXTCON_CHG_USB_FAST] = { | ||
87 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, | ||
88 | .id = EXTCON_CHG_USB_FAST, | ||
89 | .name = "FAST-CHARGER", | ||
90 | }, | ||
91 | [EXTCON_CHG_USB_SLOW] = { | ||
92 | .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, | ||
93 | .id = EXTCON_CHG_USB_SLOW, | ||
94 | .name = "SLOW-CHARGER", | ||
95 | }, | ||
96 | [EXTCON_CHG_WPT] = { | ||
97 | .type = EXTCON_TYPE_CHG, | ||
98 | .id = EXTCON_CHG_WPT, | ||
99 | .name = "WPT", | ||
100 | }, | ||
55 | 101 | ||
56 | /* Jack external connector */ | 102 | /* Jack external connector */ |
57 | [EXTCON_JACK_MICROPHONE] = "MICROPHONE", | 103 | [EXTCON_JACK_MICROPHONE] = { |
58 | [EXTCON_JACK_HEADPHONE] = "HEADPHONE", | 104 | .type = EXTCON_TYPE_JACK, |
59 | [EXTCON_JACK_LINE_IN] = "LINE-IN", | 105 | .id = EXTCON_JACK_MICROPHONE, |
60 | [EXTCON_JACK_LINE_OUT] = "LINE-OUT", | 106 | .name = "MICROPHONE", |
61 | [EXTCON_JACK_VIDEO_IN] = "VIDEO-IN", | 107 | }, |
62 | [EXTCON_JACK_VIDEO_OUT] = "VIDEO-OUT", | 108 | [EXTCON_JACK_HEADPHONE] = { |
63 | [EXTCON_JACK_SPDIF_IN] = "SPDIF-IN", | 109 | .type = EXTCON_TYPE_JACK, |
64 | [EXTCON_JACK_SPDIF_OUT] = "SPDIF-OUT", | 110 | .id = EXTCON_JACK_HEADPHONE, |
111 | .name = "HEADPHONE", | ||
112 | }, | ||
113 | [EXTCON_JACK_LINE_IN] = { | ||
114 | .type = EXTCON_TYPE_JACK, | ||
115 | .id = EXTCON_JACK_LINE_IN, | ||
116 | .name = "LINE-IN", | ||
117 | }, | ||
118 | [EXTCON_JACK_LINE_OUT] = { | ||
119 | .type = EXTCON_TYPE_JACK, | ||
120 | .id = EXTCON_JACK_LINE_OUT, | ||
121 | .name = "LINE-OUT", | ||
122 | }, | ||
123 | [EXTCON_JACK_VIDEO_IN] = { | ||
124 | .type = EXTCON_TYPE_JACK, | ||
125 | .id = EXTCON_JACK_VIDEO_IN, | ||
126 | .name = "VIDEO-IN", | ||
127 | }, | ||
128 | [EXTCON_JACK_VIDEO_OUT] = { | ||
129 | .type = EXTCON_TYPE_JACK, | ||
130 | .id = EXTCON_JACK_VIDEO_OUT, | ||
131 | .name = "VIDEO-OUT", | ||
132 | }, | ||
133 | [EXTCON_JACK_SPDIF_IN] = { | ||
134 | .type = EXTCON_TYPE_JACK, | ||
135 | .id = EXTCON_JACK_SPDIF_IN, | ||
136 | .name = "SPDIF-IN", | ||
137 | }, | ||
138 | [EXTCON_JACK_SPDIF_OUT] = { | ||
139 | .type = EXTCON_TYPE_JACK, | ||
140 | .id = EXTCON_JACK_SPDIF_OUT, | ||
141 | .name = "SPDIF-OUT", | ||
142 | }, | ||
65 | 143 | ||
66 | /* Display external connector */ | 144 | /* Display external connector */ |
67 | [EXTCON_DISP_HDMI] = "HDMI", | 145 | [EXTCON_DISP_HDMI] = { |
68 | [EXTCON_DISP_MHL] = "MHL", | 146 | .type = EXTCON_TYPE_DISP, |
69 | [EXTCON_DISP_DVI] = "DVI", | 147 | .id = EXTCON_DISP_HDMI, |
70 | [EXTCON_DISP_VGA] = "VGA", | 148 | .name = "HDMI", |
149 | }, | ||
150 | [EXTCON_DISP_MHL] = { | ||
151 | .type = EXTCON_TYPE_DISP, | ||
152 | .id = EXTCON_DISP_MHL, | ||
153 | .name = "MHL", | ||
154 | }, | ||
155 | [EXTCON_DISP_DVI] = { | ||
156 | .type = EXTCON_TYPE_DISP, | ||
157 | .id = EXTCON_DISP_DVI, | ||
158 | .name = "DVI", | ||
159 | }, | ||
160 | [EXTCON_DISP_VGA] = { | ||
161 | .type = EXTCON_TYPE_DISP, | ||
162 | .id = EXTCON_DISP_VGA, | ||
163 | .name = "VGA", | ||
164 | }, | ||
165 | [EXTCON_DISP_DP] = { | ||
166 | .type = EXTCON_TYPE_DISP | EXTCON_TYPE_USB, | ||
167 | .id = EXTCON_DISP_DP, | ||
168 | .name = "DP", | ||
169 | }, | ||
170 | [EXTCON_DISP_HMD] = { | ||
171 | .type = EXTCON_TYPE_DISP | EXTCON_TYPE_USB, | ||
172 | .id = EXTCON_DISP_HMD, | ||
173 | .name = "HMD", | ||
174 | }, | ||
71 | 175 | ||
72 | /* Miscellaneous external connector */ | 176 | /* Miscellaneous external connector */ |
73 | [EXTCON_DOCK] = "DOCK", | 177 | [EXTCON_DOCK] = { |
74 | [EXTCON_JIG] = "JIG", | 178 | .type = EXTCON_TYPE_MISC, |
75 | [EXTCON_MECHANICAL] = "MECHANICAL", | 179 | .id = EXTCON_DOCK, |
76 | 180 | .name = "DOCK", | |
77 | NULL, | 181 | }, |
182 | [EXTCON_JIG] = { | ||
183 | .type = EXTCON_TYPE_MISC, | ||
184 | .id = EXTCON_JIG, | ||
185 | .name = "JIG", | ||
186 | }, | ||
187 | [EXTCON_MECHANICAL] = { | ||
188 | .type = EXTCON_TYPE_MISC, | ||
189 | .id = EXTCON_MECHANICAL, | ||
190 | .name = "MECHANICAL", | ||
191 | }, | ||
192 | |||
193 | { /* sentinel */ } | ||
78 | }; | 194 | }; |
79 | 195 | ||
80 | /** | 196 | /** |
@@ -95,6 +211,16 @@ struct extcon_cable { | |||
95 | struct device_attribute attr_state; | 211 | struct device_attribute attr_state; |
96 | 212 | ||
97 | struct attribute *attrs[3]; /* to be fed to attr_g.attrs */ | 213 | struct attribute *attrs[3]; /* to be fed to attr_g.attrs */ |
214 | |||
215 | union extcon_property_value usb_propval[EXTCON_PROP_USB_CNT]; | ||
216 | union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT]; | ||
217 | union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT]; | ||
218 | union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT]; | ||
219 | |||
220 | unsigned long usb_bits[BITS_TO_LONGS(EXTCON_PROP_USB_CNT)]; | ||
221 | unsigned long chg_bits[BITS_TO_LONGS(EXTCON_PROP_CHG_CNT)]; | ||
222 | unsigned long jack_bits[BITS_TO_LONGS(EXTCON_PROP_JACK_CNT)]; | ||
223 | unsigned long disp_bits[BITS_TO_LONGS(EXTCON_PROP_DISP_CNT)]; | ||
98 | }; | 224 | }; |
99 | 225 | ||
100 | static struct class *extcon_class; | 226 | static struct class *extcon_class; |
@@ -147,14 +273,93 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id | |||
147 | return -EINVAL; | 273 | return -EINVAL; |
148 | } | 274 | } |
149 | 275 | ||
150 | static bool is_extcon_changed(u32 prev, u32 new, int idx, bool *attached) | 276 | static int get_extcon_type(unsigned int prop) |
151 | { | 277 | { |
152 | if (((prev >> idx) & 0x1) != ((new >> idx) & 0x1)) { | 278 | switch (prop) { |
153 | *attached = ((new >> idx) & 0x1) ? true : false; | 279 | case EXTCON_PROP_USB_MIN ... EXTCON_PROP_USB_MAX: |
154 | return true; | 280 | return EXTCON_TYPE_USB; |
281 | case EXTCON_PROP_CHG_MIN ... EXTCON_PROP_CHG_MAX: | ||
282 | return EXTCON_TYPE_CHG; | ||
283 | case EXTCON_PROP_JACK_MIN ... EXTCON_PROP_JACK_MAX: | ||
284 | return EXTCON_TYPE_JACK; | ||
285 | case EXTCON_PROP_DISP_MIN ... EXTCON_PROP_DISP_MAX: | ||
286 | return EXTCON_TYPE_DISP; | ||
287 | default: | ||
288 | return -EINVAL; | ||
155 | } | 289 | } |
290 | } | ||
291 | |||
292 | static bool is_extcon_attached(struct extcon_dev *edev, unsigned int index) | ||
293 | { | ||
294 | return !!(edev->state & BIT(index)); | ||
295 | } | ||
296 | |||
297 | static bool is_extcon_changed(struct extcon_dev *edev, int index, | ||
298 | bool new_state) | ||
299 | { | ||
300 | int state = !!(edev->state & BIT(index)); | ||
301 | return (state != new_state); | ||
302 | } | ||
303 | |||
304 | static bool is_extcon_property_supported(unsigned int id, unsigned int prop) | ||
305 | { | ||
306 | int type; | ||
307 | |||
308 | /* Check whether the property is supported or not. */ | ||
309 | type = get_extcon_type(prop); | ||
310 | if (type < 0) | ||
311 | return false; | ||
156 | 312 | ||
157 | return false; | 313 | /* Check whether a specific extcon id supports the property or not. */ |
314 | return !!(extcon_info[id].type & type); | ||
315 | } | ||
316 | |||
317 | static int is_extcon_property_capability(struct extcon_dev *edev, | ||
318 | unsigned int id, int index,unsigned int prop) | ||
319 | { | ||
320 | struct extcon_cable *cable; | ||
321 | int type, ret; | ||
322 | |||
323 | /* Check whether the property is supported or not. */ | ||
324 | type = get_extcon_type(prop); | ||
325 | if (type < 0) | ||
326 | return type; | ||
327 | |||
328 | cable = &edev->cables[index]; | ||
329 | |||
330 | switch (type) { | ||
331 | case EXTCON_TYPE_USB: | ||
332 | ret = test_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits); | ||
333 | break; | ||
334 | case EXTCON_TYPE_CHG: | ||
335 | ret = test_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits); | ||
336 | break; | ||
337 | case EXTCON_TYPE_JACK: | ||
338 | ret = test_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits); | ||
339 | break; | ||
340 | case EXTCON_TYPE_DISP: | ||
341 | ret = test_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits); | ||
342 | break; | ||
343 | default: | ||
344 | ret = -EINVAL; | ||
345 | } | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static void init_property(struct extcon_dev *edev, unsigned int id, int index) | ||
351 | { | ||
352 | unsigned int type = extcon_info[id].type; | ||
353 | struct extcon_cable *cable = &edev->cables[index]; | ||
354 | |||
355 | if (EXTCON_TYPE_USB & type) | ||
356 | memset(cable->usb_propval, 0, sizeof(cable->usb_propval)); | ||
357 | if (EXTCON_TYPE_CHG & type) | ||
358 | memset(cable->chg_propval, 0, sizeof(cable->chg_propval)); | ||
359 | if (EXTCON_TYPE_JACK & type) | ||
360 | memset(cable->jack_propval, 0, sizeof(cable->jack_propval)); | ||
361 | if (EXTCON_TYPE_DISP & type) | ||
362 | memset(cable->disp_propval, 0, sizeof(cable->disp_propval)); | ||
158 | } | 363 | } |
159 | 364 | ||
160 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, | 365 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, |
@@ -168,32 +373,13 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr, | |||
168 | 373 | ||
169 | for (i = 0; i < edev->max_supported; i++) { | 374 | for (i = 0; i < edev->max_supported; i++) { |
170 | count += sprintf(buf + count, "%s=%d\n", | 375 | count += sprintf(buf + count, "%s=%d\n", |
171 | extcon_name[edev->supported_cable[i]], | 376 | extcon_info[edev->supported_cable[i]].name, |
172 | !!(edev->state & (1 << i))); | 377 | !!(edev->state & (1 << i))); |
173 | } | 378 | } |
174 | 379 | ||
175 | return count; | 380 | return count; |
176 | } | 381 | } |
177 | 382 | static DEVICE_ATTR_RO(state); | |
178 | static ssize_t state_store(struct device *dev, struct device_attribute *attr, | ||
179 | const char *buf, size_t count) | ||
180 | { | ||
181 | u32 state; | ||
182 | ssize_t ret = 0; | ||
183 | struct extcon_dev *edev = dev_get_drvdata(dev); | ||
184 | |||
185 | ret = sscanf(buf, "0x%x", &state); | ||
186 | if (ret == 0) | ||
187 | ret = -EINVAL; | ||
188 | else | ||
189 | ret = extcon_set_state(edev, state); | ||
190 | |||
191 | if (ret < 0) | ||
192 | return ret; | ||
193 | |||
194 | return count; | ||
195 | } | ||
196 | static DEVICE_ATTR_RW(state); | ||
197 | 383 | ||
198 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, | 384 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, |
199 | char *buf) | 385 | char *buf) |
@@ -212,7 +398,7 @@ static ssize_t cable_name_show(struct device *dev, | |||
212 | int i = cable->cable_index; | 398 | int i = cable->cable_index; |
213 | 399 | ||
214 | return sprintf(buf, "%s\n", | 400 | return sprintf(buf, "%s\n", |
215 | extcon_name[cable->edev->supported_cable[i]]); | 401 | extcon_info[cable->edev->supported_cable[i]].name); |
216 | } | 402 | } |
217 | 403 | ||
218 | static ssize_t cable_state_show(struct device *dev, | 404 | static ssize_t cable_state_show(struct device *dev, |
@@ -224,26 +410,17 @@ static ssize_t cable_state_show(struct device *dev, | |||
224 | int i = cable->cable_index; | 410 | int i = cable->cable_index; |
225 | 411 | ||
226 | return sprintf(buf, "%d\n", | 412 | return sprintf(buf, "%d\n", |
227 | extcon_get_cable_state_(cable->edev, | 413 | extcon_get_state(cable->edev, cable->edev->supported_cable[i])); |
228 | cable->edev->supported_cable[i])); | ||
229 | } | 414 | } |
230 | 415 | ||
231 | /** | 416 | /** |
232 | * extcon_update_state() - Update the cable attach states of the extcon device | 417 | * extcon_sync() - Synchronize the states for both the attached/detached |
233 | * only for the masked bits. | 418 | * @edev: the extcon device that has the cable. |
234 | * @edev: the extcon device | ||
235 | * @mask: the bit mask to designate updated bits. | ||
236 | * @state: new cable attach status for @edev | ||
237 | * | ||
238 | * Changing the state sends uevent with environment variable containing | ||
239 | * the name of extcon device (envp[0]) and the state output (envp[1]). | ||
240 | * Tizen uses this format for extcon device to get events from ports. | ||
241 | * Android uses this format as well. | ||
242 | * | 419 | * |
243 | * Note that the notifier provides which bits are changed in the state | 420 | * This function send a notification to synchronize the all states of a |
244 | * variable with the val parameter (second) to the callback. | 421 | * specific external connector |
245 | */ | 422 | */ |
246 | int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state) | 423 | int extcon_sync(struct extcon_dev *edev, unsigned int id) |
247 | { | 424 | { |
248 | char name_buf[120]; | 425 | char name_buf[120]; |
249 | char state_buf[120]; | 426 | char state_buf[120]; |
@@ -252,100 +429,102 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state) | |||
252 | int env_offset = 0; | 429 | int env_offset = 0; |
253 | int length; | 430 | int length; |
254 | int index; | 431 | int index; |
432 | int state; | ||
255 | unsigned long flags; | 433 | unsigned long flags; |
256 | bool attached; | ||
257 | 434 | ||
258 | if (!edev) | 435 | if (!edev) |
259 | return -EINVAL; | 436 | return -EINVAL; |
260 | 437 | ||
261 | spin_lock_irqsave(&edev->lock, flags); | 438 | index = find_cable_index_by_id(edev, id); |
439 | if (index < 0) | ||
440 | return index; | ||
262 | 441 | ||
263 | if (edev->state != ((edev->state & ~mask) | (state & mask))) { | 442 | spin_lock_irqsave(&edev->lock, flags); |
264 | u32 old_state; | ||
265 | 443 | ||
266 | if (check_mutually_exclusive(edev, (edev->state & ~mask) | | 444 | state = !!(edev->state & BIT(index)); |
267 | (state & mask))) { | 445 | raw_notifier_call_chain(&edev->nh[index], state, edev); |
268 | spin_unlock_irqrestore(&edev->lock, flags); | ||
269 | return -EPERM; | ||
270 | } | ||
271 | 446 | ||
272 | old_state = edev->state; | 447 | /* This could be in interrupt handler */ |
273 | edev->state &= ~mask; | 448 | prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); |
274 | edev->state |= state & mask; | 449 | if (!prop_buf) { |
450 | /* Unlock early before uevent */ | ||
451 | spin_unlock_irqrestore(&edev->lock, flags); | ||
275 | 452 | ||
276 | for (index = 0; index < edev->max_supported; index++) { | 453 | dev_err(&edev->dev, "out of memory in extcon_set_state\n"); |
277 | if (is_extcon_changed(old_state, edev->state, index, | 454 | kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE); |
278 | &attached)) | ||
279 | raw_notifier_call_chain(&edev->nh[index], | ||
280 | attached, edev); | ||
281 | } | ||
282 | 455 | ||
283 | /* This could be in interrupt handler */ | 456 | return 0; |
284 | prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); | 457 | } |
285 | if (prop_buf) { | ||
286 | length = name_show(&edev->dev, NULL, prop_buf); | ||
287 | if (length > 0) { | ||
288 | if (prop_buf[length - 1] == '\n') | ||
289 | prop_buf[length - 1] = 0; | ||
290 | snprintf(name_buf, sizeof(name_buf), | ||
291 | "NAME=%s", prop_buf); | ||
292 | envp[env_offset++] = name_buf; | ||
293 | } | ||
294 | length = state_show(&edev->dev, NULL, prop_buf); | ||
295 | if (length > 0) { | ||
296 | if (prop_buf[length - 1] == '\n') | ||
297 | prop_buf[length - 1] = 0; | ||
298 | snprintf(state_buf, sizeof(state_buf), | ||
299 | "STATE=%s", prop_buf); | ||
300 | envp[env_offset++] = state_buf; | ||
301 | } | ||
302 | envp[env_offset] = NULL; | ||
303 | /* Unlock early before uevent */ | ||
304 | spin_unlock_irqrestore(&edev->lock, flags); | ||
305 | 458 | ||
306 | kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp); | 459 | length = name_show(&edev->dev, NULL, prop_buf); |
307 | free_page((unsigned long)prop_buf); | 460 | if (length > 0) { |
308 | } else { | 461 | if (prop_buf[length - 1] == '\n') |
309 | /* Unlock early before uevent */ | 462 | prop_buf[length - 1] = 0; |
310 | spin_unlock_irqrestore(&edev->lock, flags); | 463 | snprintf(name_buf, sizeof(name_buf), "NAME=%s", prop_buf); |
464 | envp[env_offset++] = name_buf; | ||
465 | } | ||
311 | 466 | ||
312 | dev_err(&edev->dev, "out of memory in extcon_set_state\n"); | 467 | length = state_show(&edev->dev, NULL, prop_buf); |
313 | kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE); | 468 | if (length > 0) { |
314 | } | 469 | if (prop_buf[length - 1] == '\n') |
315 | } else { | 470 | prop_buf[length - 1] = 0; |
316 | /* No changes */ | 471 | snprintf(state_buf, sizeof(state_buf), "STATE=%s", prop_buf); |
317 | spin_unlock_irqrestore(&edev->lock, flags); | 472 | envp[env_offset++] = state_buf; |
318 | } | 473 | } |
474 | envp[env_offset] = NULL; | ||
475 | |||
476 | /* Unlock early before uevent */ | ||
477 | spin_unlock_irqrestore(&edev->lock, flags); | ||
478 | kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp); | ||
479 | free_page((unsigned long)prop_buf); | ||
319 | 480 | ||
320 | return 0; | 481 | return 0; |
321 | } | 482 | } |
322 | EXPORT_SYMBOL_GPL(extcon_update_state); | 483 | EXPORT_SYMBOL_GPL(extcon_sync); |
323 | 484 | ||
324 | /** | 485 | /** |
325 | * extcon_set_state() - Set the cable attach states of the extcon device. | 486 | * extcon_get_state() - Get the state of a external connector. |
326 | * @edev: the extcon device | 487 | * @edev: the extcon device that has the cable. |
327 | * @state: new cable attach status for @edev | 488 | * @id: the unique id of each external connector in extcon enumeration. |
328 | * | ||
329 | * Note that notifier provides which bits are changed in the state | ||
330 | * variable with the val parameter (second) to the callback. | ||
331 | */ | 489 | */ |
332 | int extcon_set_state(struct extcon_dev *edev, u32 state) | 490 | int extcon_get_state(struct extcon_dev *edev, const unsigned int id) |
333 | { | 491 | { |
492 | int index, state; | ||
493 | unsigned long flags; | ||
494 | |||
334 | if (!edev) | 495 | if (!edev) |
335 | return -EINVAL; | 496 | return -EINVAL; |
336 | 497 | ||
337 | return extcon_update_state(edev, 0xffffffff, state); | 498 | index = find_cable_index_by_id(edev, id); |
499 | if (index < 0) | ||
500 | return index; | ||
501 | |||
502 | spin_lock_irqsave(&edev->lock, flags); | ||
503 | state = is_extcon_attached(edev, index); | ||
504 | spin_unlock_irqrestore(&edev->lock, flags); | ||
505 | |||
506 | return state; | ||
338 | } | 507 | } |
339 | EXPORT_SYMBOL_GPL(extcon_set_state); | 508 | EXPORT_SYMBOL_GPL(extcon_get_state); |
340 | 509 | ||
341 | /** | 510 | /** |
342 | * extcon_get_cable_state_() - Get the status of a specific cable. | 511 | * extcon_set_state() - Set the state of a external connector. |
343 | * @edev: the extcon device that has the cable. | 512 | * without a notification. |
344 | * @id: the unique id of each external connector in extcon enumeration. | 513 | * @edev: the extcon device that has the cable. |
514 | * @id: the unique id of each external connector | ||
515 | * in extcon enumeration. | ||
516 | * @state: the new cable status. The default semantics is | ||
517 | * true: attached / false: detached. | ||
518 | * | ||
519 | * This function only set the state of a external connector without | ||
520 | * a notification. To synchronize the data of a external connector, | ||
521 | * use extcon_set_state_sync() and extcon_sync(). | ||
345 | */ | 522 | */ |
346 | int extcon_get_cable_state_(struct extcon_dev *edev, const unsigned int id) | 523 | int extcon_set_state(struct extcon_dev *edev, unsigned int id, |
524 | bool cable_state) | ||
347 | { | 525 | { |
348 | int index; | 526 | unsigned long flags; |
527 | int index, ret = 0; | ||
349 | 528 | ||
350 | if (!edev) | 529 | if (!edev) |
351 | return -EINVAL; | 530 | return -EINVAL; |
@@ -354,41 +533,338 @@ int extcon_get_cable_state_(struct extcon_dev *edev, const unsigned int id) | |||
354 | if (index < 0) | 533 | if (index < 0) |
355 | return index; | 534 | return index; |
356 | 535 | ||
357 | if (edev->max_supported && edev->max_supported <= index) | 536 | spin_lock_irqsave(&edev->lock, flags); |
358 | return -EINVAL; | 537 | |
538 | /* Check whether the external connector's state is changed. */ | ||
539 | if (!is_extcon_changed(edev, index, cable_state)) | ||
540 | goto out; | ||
541 | |||
542 | if (check_mutually_exclusive(edev, | ||
543 | (edev->state & ~BIT(index)) | (cable_state & BIT(index)))) { | ||
544 | ret = -EPERM; | ||
545 | goto out; | ||
546 | } | ||
547 | |||
548 | /* | ||
549 | * Initialize the value of extcon property before setting | ||
550 | * the detached state for an external connector. | ||
551 | */ | ||
552 | if (!cable_state) | ||
553 | init_property(edev, id, index); | ||
554 | |||
555 | /* Update the state for a external connector. */ | ||
556 | if (cable_state) | ||
557 | edev->state |= BIT(index); | ||
558 | else | ||
559 | edev->state &= ~(BIT(index)); | ||
560 | out: | ||
561 | spin_unlock_irqrestore(&edev->lock, flags); | ||
359 | 562 | ||
360 | return !!(edev->state & (1 << index)); | 563 | return ret; |
361 | } | 564 | } |
362 | EXPORT_SYMBOL_GPL(extcon_get_cable_state_); | 565 | EXPORT_SYMBOL_GPL(extcon_set_state); |
363 | 566 | ||
364 | /** | 567 | /** |
365 | * extcon_set_cable_state_() - Set the status of a specific cable. | 568 | * extcon_set_state_sync() - Set the state of a external connector |
569 | * with a notification. | ||
366 | * @edev: the extcon device that has the cable. | 570 | * @edev: the extcon device that has the cable. |
367 | * @id: the unique id of each external connector | 571 | * @id: the unique id of each external connector |
368 | * in extcon enumeration. | 572 | * in extcon enumeration. |
369 | * @state: the new cable status. The default semantics is | 573 | * @state: the new cable status. The default semantics is |
370 | * true: attached / false: detached. | 574 | * true: attached / false: detached. |
575 | * | ||
576 | * This function set the state of external connector and synchronize the data | ||
577 | * by usning a notification. | ||
371 | */ | 578 | */ |
372 | int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, | 579 | int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, |
373 | bool cable_state) | 580 | bool cable_state) |
374 | { | 581 | { |
375 | u32 state; | 582 | int ret, index; |
583 | unsigned long flags; | ||
584 | |||
585 | index = find_cable_index_by_id(edev, id); | ||
586 | if (index < 0) | ||
587 | return index; | ||
588 | |||
589 | /* Check whether the external connector's state is changed. */ | ||
590 | spin_lock_irqsave(&edev->lock, flags); | ||
591 | ret = is_extcon_changed(edev, index, cable_state); | ||
592 | spin_unlock_irqrestore(&edev->lock, flags); | ||
593 | if (!ret) | ||
594 | return 0; | ||
595 | |||
596 | ret = extcon_set_state(edev, id, cable_state); | ||
597 | if (ret < 0) | ||
598 | return ret; | ||
599 | |||
600 | return extcon_sync(edev, id); | ||
601 | } | ||
602 | EXPORT_SYMBOL_GPL(extcon_set_state_sync); | ||
603 | |||
604 | /** | ||
605 | * extcon_get_property() - Get the property value of a specific cable. | ||
606 | * @edev: the extcon device that has the cable. | ||
607 | * @id: the unique id of each external connector | ||
608 | * in extcon enumeration. | ||
609 | * @prop: the property id among enum extcon_property. | ||
610 | * @prop_val: the pointer which store the value of property. | ||
611 | * | ||
612 | * When getting the property value of external connector, the external connector | ||
613 | * should be attached. If detached state, function just return 0 without | ||
614 | * property value. Also, the each property should be included in the list of | ||
615 | * supported properties according to the type of external connectors. | ||
616 | * | ||
617 | * Returns 0 if success or error number if fail | ||
618 | */ | ||
619 | int extcon_get_property(struct extcon_dev *edev, unsigned int id, | ||
620 | unsigned int prop, | ||
621 | union extcon_property_value *prop_val) | ||
622 | { | ||
623 | struct extcon_cable *cable; | ||
624 | unsigned long flags; | ||
625 | int index, ret = 0; | ||
626 | |||
627 | *prop_val = (union extcon_property_value)(0); | ||
628 | |||
629 | if (!edev) | ||
630 | return -EINVAL; | ||
631 | |||
632 | /* Check whether the property is supported or not */ | ||
633 | if (!is_extcon_property_supported(id, prop)) | ||
634 | return -EINVAL; | ||
635 | |||
636 | /* Find the cable index of external connector by using id */ | ||
637 | index = find_cable_index_by_id(edev, id); | ||
638 | if (index < 0) | ||
639 | return index; | ||
640 | |||
641 | spin_lock_irqsave(&edev->lock, flags); | ||
642 | |||
643 | /* Check whether the property is available or not. */ | ||
644 | if (!is_extcon_property_capability(edev, id, index, prop)) { | ||
645 | spin_unlock_irqrestore(&edev->lock, flags); | ||
646 | return -EPERM; | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Check whether the external connector is attached. | ||
651 | * If external connector is detached, the user can not | ||
652 | * get the property value. | ||
653 | */ | ||
654 | if (!is_extcon_attached(edev, index)) { | ||
655 | spin_unlock_irqrestore(&edev->lock, flags); | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | cable = &edev->cables[index]; | ||
660 | |||
661 | /* Get the property value according to extcon type */ | ||
662 | switch (prop) { | ||
663 | case EXTCON_PROP_USB_MIN ... EXTCON_PROP_USB_MAX: | ||
664 | *prop_val = cable->usb_propval[prop - EXTCON_PROP_USB_MIN]; | ||
665 | break; | ||
666 | case EXTCON_PROP_CHG_MIN ... EXTCON_PROP_CHG_MAX: | ||
667 | *prop_val = cable->chg_propval[prop - EXTCON_PROP_CHG_MIN]; | ||
668 | break; | ||
669 | case EXTCON_PROP_JACK_MIN ... EXTCON_PROP_JACK_MAX: | ||
670 | *prop_val = cable->jack_propval[prop - EXTCON_PROP_JACK_MIN]; | ||
671 | break; | ||
672 | case EXTCON_PROP_DISP_MIN ... EXTCON_PROP_DISP_MAX: | ||
673 | *prop_val = cable->disp_propval[prop - EXTCON_PROP_DISP_MIN]; | ||
674 | break; | ||
675 | default: | ||
676 | ret = -EINVAL; | ||
677 | break; | ||
678 | } | ||
679 | |||
680 | spin_unlock_irqrestore(&edev->lock, flags); | ||
681 | |||
682 | return ret; | ||
683 | } | ||
684 | EXPORT_SYMBOL_GPL(extcon_get_property); | ||
685 | |||
686 | /** | ||
687 | * extcon_set_property() - Set the property value of a specific cable. | ||
688 | * @edev: the extcon device that has the cable. | ||
689 | * @id: the unique id of each external connector | ||
690 | * in extcon enumeration. | ||
691 | * @prop: the property id among enum extcon_property. | ||
692 | * @prop_val: the pointer including the new value of property. | ||
693 | * | ||
694 | * The each property should be included in the list of supported properties | ||
695 | * according to the type of external connectors. | ||
696 | * | ||
697 | * Returns 0 if success or error number if fail | ||
698 | */ | ||
699 | int extcon_set_property(struct extcon_dev *edev, unsigned int id, | ||
700 | unsigned int prop, | ||
701 | union extcon_property_value prop_val) | ||
702 | { | ||
703 | struct extcon_cable *cable; | ||
704 | unsigned long flags; | ||
705 | int index, ret = 0; | ||
706 | |||
707 | if (!edev) | ||
708 | return -EINVAL; | ||
709 | |||
710 | /* Check whether the property is supported or not */ | ||
711 | if (!is_extcon_property_supported(id, prop)) | ||
712 | return -EINVAL; | ||
713 | |||
714 | /* Find the cable index of external connector by using id */ | ||
715 | index = find_cable_index_by_id(edev, id); | ||
716 | if (index < 0) | ||
717 | return index; | ||
718 | |||
719 | spin_lock_irqsave(&edev->lock, flags); | ||
720 | |||
721 | /* Check whether the property is available or not. */ | ||
722 | if (!is_extcon_property_capability(edev, id, index, prop)) { | ||
723 | spin_unlock_irqrestore(&edev->lock, flags); | ||
724 | return -EPERM; | ||
725 | } | ||
726 | |||
727 | cable = &edev->cables[index]; | ||
728 | |||
729 | /* Set the property value according to extcon type */ | ||
730 | switch (prop) { | ||
731 | case EXTCON_PROP_USB_MIN ... EXTCON_PROP_USB_MAX: | ||
732 | cable->usb_propval[prop - EXTCON_PROP_USB_MIN] = prop_val; | ||
733 | break; | ||
734 | case EXTCON_PROP_CHG_MIN ... EXTCON_PROP_CHG_MAX: | ||
735 | cable->chg_propval[prop - EXTCON_PROP_CHG_MIN] = prop_val; | ||
736 | break; | ||
737 | case EXTCON_PROP_JACK_MIN ... EXTCON_PROP_JACK_MAX: | ||
738 | cable->jack_propval[prop - EXTCON_PROP_JACK_MIN] = prop_val; | ||
739 | break; | ||
740 | case EXTCON_PROP_DISP_MIN ... EXTCON_PROP_DISP_MAX: | ||
741 | cable->disp_propval[prop - EXTCON_PROP_DISP_MIN] = prop_val; | ||
742 | break; | ||
743 | default: | ||
744 | ret = -EINVAL; | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | spin_unlock_irqrestore(&edev->lock, flags); | ||
749 | |||
750 | return ret; | ||
751 | } | ||
752 | EXPORT_SYMBOL_GPL(extcon_set_property); | ||
753 | |||
754 | /** | ||
755 | * extcon_set_property_sync() - Set the property value of a specific cable | ||
756 | with a notification. | ||
757 | * @prop_val: the pointer including the new value of property. | ||
758 | * | ||
759 | * When setting the property value of external connector, the external connector | ||
760 | * should be attached. The each property should be included in the list of | ||
761 | * supported properties according to the type of external connectors. | ||
762 | * | ||
763 | * Returns 0 if success or error number if fail | ||
764 | */ | ||
765 | int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, | ||
766 | unsigned int prop, | ||
767 | union extcon_property_value prop_val) | ||
768 | { | ||
769 | int ret; | ||
770 | |||
771 | ret = extcon_set_property(edev, id, prop, prop_val); | ||
772 | if (ret < 0) | ||
773 | return ret; | ||
774 | |||
775 | return extcon_sync(edev, id); | ||
776 | } | ||
777 | EXPORT_SYMBOL_GPL(extcon_set_property_sync); | ||
778 | |||
779 | /** | ||
780 | * extcon_get_property_capability() - Get the capability of property | ||
781 | * of an external connector. | ||
782 | * @edev: the extcon device that has the cable. | ||
783 | * @id: the unique id of each external connector | ||
784 | * in extcon enumeration. | ||
785 | * @prop: the property id among enum extcon_property. | ||
786 | * | ||
787 | * Returns 1 if the property is available or 0 if not available. | ||
788 | */ | ||
789 | int extcon_get_property_capability(struct extcon_dev *edev, unsigned int id, | ||
790 | unsigned int prop) | ||
791 | { | ||
376 | int index; | 792 | int index; |
377 | 793 | ||
378 | if (!edev) | 794 | if (!edev) |
379 | return -EINVAL; | 795 | return -EINVAL; |
380 | 796 | ||
797 | /* Check whether the property is supported or not */ | ||
798 | if (!is_extcon_property_supported(id, prop)) | ||
799 | return -EINVAL; | ||
800 | |||
801 | /* Find the cable index of external connector by using id */ | ||
381 | index = find_cable_index_by_id(edev, id); | 802 | index = find_cable_index_by_id(edev, id); |
382 | if (index < 0) | 803 | if (index < 0) |
383 | return index; | 804 | return index; |
384 | 805 | ||
385 | if (edev->max_supported && edev->max_supported <= index) | 806 | return is_extcon_property_capability(edev, id, index, prop); |
807 | } | ||
808 | EXPORT_SYMBOL_GPL(extcon_get_property_capability); | ||
809 | |||
810 | /** | ||
811 | * extcon_set_property_capability() - Set the capability of a property | ||
812 | * of an external connector. | ||
813 | * @edev: the extcon device that has the cable. | ||
814 | * @id: the unique id of each external connector | ||
815 | * in extcon enumeration. | ||
816 | * @prop: the property id among enum extcon_property. | ||
817 | * | ||
818 | * This function set the capability of a property for an external connector | ||
819 | * to mark the bit in capability bitmap which mean the available state of | ||
820 | * a property. | ||
821 | * | ||
822 | * Returns 0 if success or error number if fail | ||
823 | */ | ||
824 | int extcon_set_property_capability(struct extcon_dev *edev, unsigned int id, | ||
825 | unsigned int prop) | ||
826 | { | ||
827 | struct extcon_cable *cable; | ||
828 | int index, type, ret = 0; | ||
829 | |||
830 | if (!edev) | ||
386 | return -EINVAL; | 831 | return -EINVAL; |
387 | 832 | ||
388 | state = cable_state ? (1 << index) : 0; | 833 | /* Check whether the property is supported or not. */ |
389 | return extcon_update_state(edev, 1 << index, state); | 834 | if (!is_extcon_property_supported(id, prop)) |
835 | return -EINVAL; | ||
836 | |||
837 | /* Find the cable index of external connector by using id. */ | ||
838 | index = find_cable_index_by_id(edev, id); | ||
839 | if (index < 0) | ||
840 | return index; | ||
841 | |||
842 | type = get_extcon_type(prop); | ||
843 | if (type < 0) | ||
844 | return type; | ||
845 | |||
846 | cable = &edev->cables[index]; | ||
847 | |||
848 | switch (type) { | ||
849 | case EXTCON_TYPE_USB: | ||
850 | __set_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits); | ||
851 | break; | ||
852 | case EXTCON_TYPE_CHG: | ||
853 | __set_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits); | ||
854 | break; | ||
855 | case EXTCON_TYPE_JACK: | ||
856 | __set_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits); | ||
857 | break; | ||
858 | case EXTCON_TYPE_DISP: | ||
859 | __set_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits); | ||
860 | break; | ||
861 | default: | ||
862 | ret = -EINVAL; | ||
863 | } | ||
864 | |||
865 | return ret; | ||
390 | } | 866 | } |
391 | EXPORT_SYMBOL_GPL(extcon_set_cable_state_); | 867 | EXPORT_SYMBOL_GPL(extcon_set_property_capability); |
392 | 868 | ||
393 | /** | 869 | /** |
394 | * extcon_get_extcon_dev() - Get the extcon device instance from the name | 870 | * extcon_get_extcon_dev() - Get the extcon device instance from the name |
@@ -428,7 +904,7 @@ int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, | |||
428 | struct notifier_block *nb) | 904 | struct notifier_block *nb) |
429 | { | 905 | { |
430 | unsigned long flags; | 906 | unsigned long flags; |
431 | int ret, idx; | 907 | int ret, idx = -EINVAL; |
432 | 908 | ||
433 | if (!nb) | 909 | if (!nb) |
434 | return -EINVAL; | 910 | return -EINVAL; |
@@ -846,13 +1322,13 @@ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) | |||
846 | return ERR_PTR(-EINVAL); | 1322 | return ERR_PTR(-EINVAL); |
847 | 1323 | ||
848 | if (!dev->of_node) { | 1324 | if (!dev->of_node) { |
849 | dev_err(dev, "device does not have a device node entry\n"); | 1325 | dev_dbg(dev, "device does not have a device node entry\n"); |
850 | return ERR_PTR(-EINVAL); | 1326 | return ERR_PTR(-EINVAL); |
851 | } | 1327 | } |
852 | 1328 | ||
853 | node = of_parse_phandle(dev->of_node, "extcon", index); | 1329 | node = of_parse_phandle(dev->of_node, "extcon", index); |
854 | if (!node) { | 1330 | if (!node) { |
855 | dev_err(dev, "failed to get phandle in %s node\n", | 1331 | dev_dbg(dev, "failed to get phandle in %s node\n", |
856 | dev->of_node->full_name); | 1332 | dev->of_node->full_name); |
857 | return ERR_PTR(-ENODEV); | 1333 | return ERR_PTR(-ENODEV); |
858 | } | 1334 | } |
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index 6e22af36b637..e038e886731b 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c | |||
@@ -392,7 +392,6 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_dev *dev) | |||
392 | dev_dbg(&pdev->dev, "alloc urb=%d\n", i); | 392 | dev_dbg(&pdev->dev, "alloc urb=%d\n", i); |
393 | dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); | 393 | dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); |
394 | if (!dev->urb_list[i]) { | 394 | if (!dev->urb_list[i]) { |
395 | dev_dbg(&pdev->dev, "failed\n"); | ||
396 | for (j = 0; j < i; j++) | 395 | for (j = 0; j < i; j++) |
397 | usb_free_urb(dev->urb_list[j]); | 396 | usb_free_urb(dev->urb_list[j]); |
398 | return -ENOMEM; | 397 | return -ENOMEM; |
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 091d793f6583..4b132c29f290 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -627,7 +627,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
627 | 627 | ||
628 | radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 628 | radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
629 | if (!radio->int_in_urb) { | 629 | if (!radio->int_in_urb) { |
630 | dev_info(&intf->dev, "could not allocate int_in_urb"); | ||
631 | retval = -ENOMEM; | 630 | retval = -ENOMEM; |
632 | goto err_intbuffer; | 631 | goto err_intbuffer; |
633 | } | 632 | } |
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 65f80b8b9f7a..86cc70fe2534 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -2211,16 +2211,11 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, | |||
2211 | goto exit; | 2211 | goto exit; |
2212 | } | 2212 | } |
2213 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2213 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); |
2214 | if (!rx_urb) { | 2214 | if (!rx_urb) |
2215 | dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__); | ||
2216 | goto rx_urb_alloc_failed; | 2215 | goto rx_urb_alloc_failed; |
2217 | } | ||
2218 | tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2216 | tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
2219 | if (!tx_urb) { | 2217 | if (!tx_urb) |
2220 | dev_err(dev, "%s: usb_alloc_urb failed for display urb", | ||
2221 | __func__); | ||
2222 | goto tx_urb_alloc_failed; | 2218 | goto tx_urb_alloc_failed; |
2223 | } | ||
2224 | 2219 | ||
2225 | mutex_init(&ictx->lock); | 2220 | mutex_init(&ictx->lock); |
2226 | spin_lock_init(&ictx->kc_lock); | 2221 | spin_lock_init(&ictx->kc_lock); |
@@ -2305,10 +2300,8 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, | |||
2305 | int ret = -ENOMEM; | 2300 | int ret = -ENOMEM; |
2306 | 2301 | ||
2307 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2302 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); |
2308 | if (!rx_urb) { | 2303 | if (!rx_urb) |
2309 | pr_err("usb_alloc_urb failed for IR urb\n"); | ||
2310 | goto rx_urb_alloc_failed; | 2304 | goto rx_urb_alloc_failed; |
2311 | } | ||
2312 | 2305 | ||
2313 | mutex_lock(&ictx->lock); | 2306 | mutex_lock(&ictx->lock); |
2314 | 2307 | ||
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 399f44d89a29..ec8016d9b009 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c | |||
@@ -970,10 +970,8 @@ static int redrat3_dev_probe(struct usb_interface *intf, | |||
970 | 970 | ||
971 | /* set up bulk-in endpoint */ | 971 | /* set up bulk-in endpoint */ |
972 | rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL); | 972 | rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL); |
973 | if (!rr3->read_urb) { | 973 | if (!rr3->read_urb) |
974 | dev_err(dev, "Read urb allocation failure\n"); | ||
975 | goto error; | 974 | goto error; |
976 | } | ||
977 | 975 | ||
978 | rr3->ep_in = ep_in; | 976 | rr3->ep_in = ep_in; |
979 | rr3->bulk_in_buf = usb_alloc_coherent(udev, | 977 | rr3->bulk_in_buf = usb_alloc_coherent(udev, |
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index fe031b06935f..3c556ee306cd 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c | |||
@@ -426,7 +426,6 @@ static int airspy_alloc_urbs(struct airspy *s) | |||
426 | dev_dbg(s->dev, "alloc urb=%d\n", i); | 426 | dev_dbg(s->dev, "alloc urb=%d\n", i); |
427 | s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); | 427 | s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); |
428 | if (!s->urb_list[i]) { | 428 | if (!s->urb_list[i]) { |
429 | dev_dbg(s->dev, "failed\n"); | ||
430 | for (j = 0; j < i; j++) | 429 | for (j = 0; j < i; j++) |
431 | usb_free_urb(s->urb_list[j]); | 430 | usb_free_urb(s->urb_list[j]); |
432 | return -ENOMEM; | 431 | return -ENOMEM; |
diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c index 0e8030c071b8..68c3a80ce349 100644 --- a/drivers/media/usb/as102/as102_usb_drv.c +++ b/drivers/media/usb/as102/as102_usb_drv.c | |||
@@ -270,8 +270,6 @@ static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) | |||
270 | 270 | ||
271 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 271 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
272 | if (urb == NULL) { | 272 | if (urb == NULL) { |
273 | dev_dbg(&dev->bus_adap.usb_dev->dev, | ||
274 | "%s: usb_alloc_urb failed\n", __func__); | ||
275 | as102_free_usb_stream_buffer(dev); | 273 | as102_free_usb_stream_buffer(dev); |
276 | return -ENOMEM; | 274 | return -ENOMEM; |
277 | } | 275 | } |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 82b026985868..13b8387082f2 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
@@ -245,7 +245,6 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets, | |||
245 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 245 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
246 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | 246 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); |
247 | if (!urb) { | 247 | if (!urb) { |
248 | au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i); | ||
249 | au0828_uninit_isoc(dev); | 248 | au0828_uninit_isoc(dev); |
250 | return -ENOMEM; | 249 | return -ENOMEM; |
251 | } | 250 | } |
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index c1aa1ab2ece9..13620cdf0599 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c | |||
@@ -662,7 +662,6 @@ static int submit_urbs(struct camera_data *cam) | |||
662 | } | 662 | } |
663 | urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); | 663 | urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); |
664 | if (!urb) { | 664 | if (!urb) { |
665 | ERR("%s: usb_alloc_urb error!\n", __func__); | ||
666 | for (j = 0; j < i; j++) | 665 | for (j = 0; j < i; j++) |
667 | usb_free_urb(cam->sbuf[j].urb); | 666 | usb_free_urb(cam->sbuf[j].urb); |
668 | return -ENOMEM; | 667 | return -ENOMEM; |
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index a6a9508418f8..4cd5fa91612f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c | |||
@@ -293,7 +293,6 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) | |||
293 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); | 293 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); |
294 | urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); | 294 | urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); |
295 | if (!urb) { | 295 | if (!urb) { |
296 | dev_err(dev->dev, "usb_alloc_urb failed!\n"); | ||
297 | for (j = 0; j < i; j++) { | 296 | for (j = 0; j < i; j++) { |
298 | usb_free_urb(dev->adev.urb[j]); | 297 | usb_free_urb(dev->adev.urb[j]); |
299 | kfree(dev->adev.transfer_buffer[j]); | 298 | kfree(dev->adev.transfer_buffer[j]); |
@@ -355,7 +354,6 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) | |||
355 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); | 354 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); |
356 | urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | 355 | urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); |
357 | if (!urb) { | 356 | if (!urb) { |
358 | dev_err(dev->dev, "usb_alloc_urb failed!\n"); | ||
359 | for (j = 0; j < i; j++) { | 357 | for (j = 0; j < i; j++) { |
360 | usb_free_urb(dev->adev.urb[j]); | 358 | usb_free_urb(dev->adev.urb[j]); |
361 | kfree(dev->adev.transfer_buffer[j]); | 359 | kfree(dev->adev.transfer_buffer[j]); |
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 630f4fc5155f..8ec05cb306d8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c | |||
@@ -1035,8 +1035,6 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, | |||
1035 | for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { | 1035 | for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { |
1036 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | 1036 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); |
1037 | if (!urb) { | 1037 | if (!urb) { |
1038 | dev_err(dev->dev, | ||
1039 | "cannot alloc isoc_ctl.urb %i\n", i); | ||
1040 | cx231xx_uninit_isoc(dev); | 1038 | cx231xx_uninit_isoc(dev); |
1041 | return -ENOMEM; | 1039 | return -ENOMEM; |
1042 | } | 1040 | } |
@@ -1172,8 +1170,6 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, | |||
1172 | for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { | 1170 | for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { |
1173 | urb = usb_alloc_urb(0, GFP_KERNEL); | 1171 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1174 | if (!urb) { | 1172 | if (!urb) { |
1175 | dev_err(dev->dev, | ||
1176 | "cannot alloc bulk_ctl.urb %i\n", i); | ||
1177 | cx231xx_uninit_bulk(dev); | 1173 | cx231xx_uninit_bulk(dev); |
1178 | return -ENOMEM; | 1174 | return -ENOMEM; |
1179 | } | 1175 | } |
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 15bb573b78ac..76e901920f6f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c | |||
@@ -442,8 +442,6 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, | |||
442 | 442 | ||
443 | urb = usb_alloc_urb(0, GFP_KERNEL); | 443 | urb = usb_alloc_urb(0, GFP_KERNEL); |
444 | if (!urb) { | 444 | if (!urb) { |
445 | dev_err(dev->dev, | ||
446 | "cannot alloc bulk_ctl.urb %i\n", i); | ||
447 | cx231xx_uninit_vbi_isoc(dev); | 445 | cx231xx_uninit_vbi_isoc(dev); |
448 | return -ENOMEM; | 446 | return -ENOMEM; |
449 | } | 447 | } |
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index bf890c3d9cda..26797979ebce 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c | |||
@@ -783,10 +783,8 @@ int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf) | |||
783 | /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ | 783 | /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ |
784 | 784 | ||
785 | purb = usb_alloc_urb(0, GFP_KERNEL); | 785 | purb = usb_alloc_urb(0, GFP_KERNEL); |
786 | if (purb == NULL) { | 786 | if (purb == NULL) |
787 | err("rc usb alloc urb failed"); | ||
788 | return -ENOMEM; | 787 | return -ENOMEM; |
789 | } | ||
790 | 788 | ||
791 | purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL); | 789 | purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL); |
792 | if (purb->transfer_buffer == NULL) { | 790 | if (purb->transfer_buffer == NULL) { |
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 49a5f9532bd8..78f3687772bf 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c | |||
@@ -850,7 +850,6 @@ static int em28xx_audio_urb_init(struct em28xx *dev) | |||
850 | 850 | ||
851 | urb = usb_alloc_urb(npackets, GFP_ATOMIC); | 851 | urb = usb_alloc_urb(npackets, GFP_ATOMIC); |
852 | if (!urb) { | 852 | if (!urb) { |
853 | em28xx_errdev("usb_alloc_urb failed!\n"); | ||
854 | em28xx_audio_free_urb(dev); | 853 | em28xx_audio_free_urb(dev); |
855 | return -ENOMEM; | 854 | return -ENOMEM; |
856 | } | 855 | } |
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 37456079f490..eebd5d7088d0 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c | |||
@@ -934,7 +934,6 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, | |||
934 | for (i = 0; i < usb_bufs->num_bufs; i++) { | 934 | for (i = 0; i < usb_bufs->num_bufs; i++) { |
935 | urb = usb_alloc_urb(usb_bufs->num_packets, GFP_KERNEL); | 935 | urb = usb_alloc_urb(usb_bufs->num_packets, GFP_KERNEL); |
936 | if (!urb) { | 936 | if (!urb) { |
937 | em28xx_err("cannot alloc usb_ctl.urb %i\n", i); | ||
938 | em28xx_uninit_usb_xfer(dev, mode); | 937 | em28xx_uninit_usb_xfer(dev, mode); |
939 | return -ENOMEM; | 938 | return -ENOMEM; |
940 | } | 939 | } |
diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c index 790baed33963..5fa67b78ad49 100644 --- a/drivers/media/usb/gspca/benq.c +++ b/drivers/media/usb/gspca/benq.c | |||
@@ -95,10 +95,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
95 | #define SD_NPKT 32 | 95 | #define SD_NPKT 32 |
96 | for (n = 0; n < 4; n++) { | 96 | for (n = 0; n < 4; n++) { |
97 | urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); | 97 | urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); |
98 | if (!urb) { | 98 | if (!urb) |
99 | pr_err("usb_alloc_urb failed\n"); | ||
100 | return -ENOMEM; | 99 | return -ENOMEM; |
101 | } | ||
102 | gspca_dev->urb[n] = urb; | 100 | gspca_dev->urb[n] = urb; |
103 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, | 101 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, |
104 | SD_PKT_SZ * SD_NPKT, | 102 | SD_PKT_SZ * SD_NPKT, |
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index b17bd7ebcb47..af2395a76d8b 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c | |||
@@ -795,10 +795,8 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
795 | 795 | ||
796 | for (n = 0; n < nurbs; n++) { | 796 | for (n = 0; n < nurbs; n++) { |
797 | urb = usb_alloc_urb(npkt, GFP_KERNEL); | 797 | urb = usb_alloc_urb(npkt, GFP_KERNEL); |
798 | if (!urb) { | 798 | if (!urb) |
799 | pr_err("usb_alloc_urb failed\n"); | ||
800 | return -ENOMEM; | 799 | return -ENOMEM; |
801 | } | ||
802 | gspca_dev->urb[n] = urb; | 800 | gspca_dev->urb[n] = urb; |
803 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, | 801 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, |
804 | bsize, | 802 | bsize, |
diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c index 0712b1bc90b4..40aaaa9c5f30 100644 --- a/drivers/media/usb/gspca/konica.c +++ b/drivers/media/usb/gspca/konica.c | |||
@@ -208,10 +208,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
208 | packet_size = | 208 | packet_size = |
209 | le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize); | 209 | le16_to_cpu(alt->endpoint[i].desc.wMaxPacketSize); |
210 | urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); | 210 | urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL); |
211 | if (!urb) { | 211 | if (!urb) |
212 | pr_err("usb_alloc_urb failed\n"); | ||
213 | return -ENOMEM; | 212 | return -ENOMEM; |
214 | } | ||
215 | gspca_dev->urb[n] = urb; | 213 | gspca_dev->urb[n] = urb; |
216 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, | 214 | urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev, |
217 | packet_size * SD_NPKT, | 215 | packet_size * SD_NPKT, |
diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index b1e229a44192..c2c8d12e9498 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c | |||
@@ -691,7 +691,6 @@ static int hackrf_alloc_urbs(struct hackrf_dev *dev, bool rcv) | |||
691 | dev_dbg(dev->dev, "alloc urb=%d\n", i); | 691 | dev_dbg(dev->dev, "alloc urb=%d\n", i); |
692 | dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); | 692 | dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); |
693 | if (!dev->urb_list[i]) { | 693 | if (!dev->urb_list[i]) { |
694 | dev_dbg(dev->dev, "failed\n"); | ||
695 | for (j = 0; j < i; j++) | 694 | for (j = 0; j < i; j++) |
696 | usb_free_urb(dev->urb_list[j]); | 695 | usb_free_urb(dev->urb_list[j]); |
697 | return -ENOMEM; | 696 | return -ENOMEM; |
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 2a3a8b470555..6d43d75493ea 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c | |||
@@ -155,10 +155,8 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) | |||
155 | buf->dev = dev; | 155 | buf->dev = dev; |
156 | 156 | ||
157 | urb = usb_alloc_urb(0, GFP_KERNEL); | 157 | urb = usb_alloc_urb(0, GFP_KERNEL); |
158 | if (!urb) { | 158 | if (!urb) |
159 | v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n"); | ||
160 | goto exit_urb; | 159 | goto exit_urb; |
161 | } | ||
162 | buf->urb = urb; | 160 | buf->urb = urb; |
163 | 161 | ||
164 | mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL, | 162 | mem = usb_alloc_coherent(dev->udev, dev->bulk_in_size, GFP_KERNEL, |
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index e7f167d44c61..367eb7e2a31d 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c | |||
@@ -509,7 +509,6 @@ static int msi2500_isoc_init(struct msi2500_dev *dev) | |||
509 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 509 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
510 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | 510 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); |
511 | if (urb == NULL) { | 511 | if (urb == NULL) { |
512 | dev_err(dev->dev, "Failed to allocate urb %d\n", i); | ||
513 | msi2500_isoc_cleanup(dev); | 512 | msi2500_isoc_cleanup(dev); |
514 | return -ENOMEM; | 513 | return -ENOMEM; |
515 | } | 514 | } |
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index b51b27a3fd61..c4454c928776 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c | |||
@@ -410,7 +410,6 @@ retry: | |||
410 | for (i = 0; i < MAX_ISO_BUFS; i++) { | 410 | for (i = 0; i < MAX_ISO_BUFS; i++) { |
411 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | 411 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); |
412 | if (urb == NULL) { | 412 | if (urb == NULL) { |
413 | PWC_ERROR("Failed to allocate urb %d\n", i); | ||
414 | pwc_isoc_cleanup(pdev); | 413 | pwc_isoc_cleanup(pdev); |
415 | return -ENOMEM; | 414 | return -ENOMEM; |
416 | } | 415 | } |
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 43ba71a7d02b..9458eb0ef66f 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
@@ -2113,11 +2113,8 @@ static int s2255_start_readpipe(struct s2255_dev *dev) | |||
2113 | pipe_info->state = 1; | 2113 | pipe_info->state = 1; |
2114 | pipe_info->err_count = 0; | 2114 | pipe_info->err_count = 0; |
2115 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | 2115 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); |
2116 | if (!pipe_info->stream_urb) { | 2116 | if (!pipe_info->stream_urb) |
2117 | dev_err(&dev->udev->dev, | ||
2118 | "ReadStream: Unable to alloc URB\n"); | ||
2119 | return -ENOMEM; | 2117 | return -ENOMEM; |
2120 | } | ||
2121 | /* transfer buffer allocated in board_init */ | 2118 | /* transfer buffer allocated in board_init */ |
2122 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, | 2119 | usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, |
2123 | pipe, | 2120 | pipe, |
@@ -2290,10 +2287,8 @@ static int s2255_probe(struct usb_interface *interface, | |||
2290 | } | 2287 | } |
2291 | 2288 | ||
2292 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); | 2289 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); |
2293 | if (!dev->fw_data->fw_urb) { | 2290 | if (!dev->fw_data->fw_urb) |
2294 | dev_err(&interface->dev, "out of memory!\n"); | ||
2295 | goto errorFWURB; | 2291 | goto errorFWURB; |
2296 | } | ||
2297 | 2292 | ||
2298 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); | 2293 | dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); |
2299 | if (!dev->fw_data->pfw_data) { | 2294 | if (!dev->fw_data->pfw_data) { |
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index 6ecb0b48423f..ce8ebbe395a6 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c | |||
@@ -457,10 +457,8 @@ int stk1160_alloc_isoc(struct stk1160 *dev) | |||
457 | for (i = 0; i < num_bufs; i++) { | 457 | for (i = 0; i < num_bufs; i++) { |
458 | 458 | ||
459 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | 459 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); |
460 | if (!urb) { | 460 | if (!urb) |
461 | stk1160_err("cannot alloc urb[%d]\n", i); | ||
462 | goto free_i_bufs; | 461 | goto free_i_bufs; |
463 | } | ||
464 | dev->isoc_ctl.urb[i] = urb; | 462 | dev->isoc_ctl.urb[i] = urb; |
465 | 463 | ||
466 | #ifndef CONFIG_DMA_NONCOHERENT | 464 | #ifndef CONFIG_DMA_NONCOHERENT |
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index c21c4c004f97..db200c9d796d 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c | |||
@@ -452,10 +452,8 @@ static int stk_prepare_iso(struct stk_camera *dev) | |||
452 | STK_ERROR("isobuf data already allocated\n"); | 452 | STK_ERROR("isobuf data already allocated\n"); |
453 | if (dev->isobufs[i].urb == NULL) { | 453 | if (dev->isobufs[i].urb == NULL) { |
454 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); | 454 | urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); |
455 | if (urb == NULL) { | 455 | if (urb == NULL) |
456 | STK_ERROR("Failed to allocate URB %d\n", i); | ||
457 | goto isobufs_out; | 456 | goto isobufs_out; |
458 | } | ||
459 | dev->isobufs[i].urb = urb; | 457 | dev->isobufs[i].urb = urb; |
460 | } else { | 458 | } else { |
461 | STK_ERROR("Killing URB\n"); | 459 | STK_ERROR("Killing URB\n"); |
diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c index 095f5db1a790..0426b210383b 100644 --- a/drivers/media/usb/tm6000/tm6000-dvb.c +++ b/drivers/media/usb/tm6000/tm6000-dvb.c | |||
@@ -129,10 +129,8 @@ static int tm6000_start_stream(struct tm6000_core *dev) | |||
129 | } | 129 | } |
130 | 130 | ||
131 | dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); | 131 | dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); |
132 | if (dvb->bulk_urb == NULL) { | 132 | if (dvb->bulk_urb == NULL) |
133 | printk(KERN_ERR "tm6000: couldn't allocate urb\n"); | ||
134 | return -ENOMEM; | 133 | return -ENOMEM; |
135 | } | ||
136 | 134 | ||
137 | pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress | 135 | pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress |
138 | & USB_ENDPOINT_NUMBER_MASK); | 136 | & USB_ENDPOINT_NUMBER_MASK); |
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index fa5e8bda2ae4..dee7e7d3d47d 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
@@ -635,7 +635,6 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev) | |||
635 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 635 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
636 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); | 636 | urb = usb_alloc_urb(max_packets, GFP_KERNEL); |
637 | if (!urb) { | 637 | if (!urb) { |
638 | tm6000_err("cannot alloc isoc_ctl.urb %i\n", i); | ||
639 | tm6000_uninit_isoc(dev); | 638 | tm6000_uninit_isoc(dev); |
640 | usb_free_urb(urb); | 639 | usb_free_urb(urb); |
641 | return -ENOMEM; | 640 | return -ENOMEM; |
diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c index 52ac4391582c..c23bf73a68ea 100644 --- a/drivers/media/usb/usbvision/usbvision-core.c +++ b/drivers/media/usb/usbvision/usbvision-core.c | |||
@@ -2303,11 +2303,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
2303 | struct urb *urb; | 2303 | struct urb *urb; |
2304 | 2304 | ||
2305 | urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); | 2305 | urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); |
2306 | if (urb == NULL) { | 2306 | if (urb == NULL) |
2307 | dev_err(&usbvision->dev->dev, | ||
2308 | "%s: usb_alloc_urb() failed\n", __func__); | ||
2309 | return -ENOMEM; | 2307 | return -ENOMEM; |
2310 | } | ||
2311 | usbvision->sbuf[buf_idx].urb = urb; | 2308 | usbvision->sbuf[buf_idx].urb = urb; |
2312 | usbvision->sbuf[buf_idx].data = | 2309 | usbvision->sbuf[buf_idx].data = |
2313 | usb_alloc_coherent(usbvision->dev, | 2310 | usb_alloc_coherent(usbvision->dev, |
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 7433ba5c4bad..cc128db85723 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c | |||
@@ -1045,10 +1045,8 @@ static int zr364xx_start_readpipe(struct zr364xx_camera *cam) | |||
1045 | pipe_info->state = 1; | 1045 | pipe_info->state = 1; |
1046 | pipe_info->err_count = 0; | 1046 | pipe_info->err_count = 0; |
1047 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); | 1047 | pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); |
1048 | if (!pipe_info->stream_urb) { | 1048 | if (!pipe_info->stream_urb) |
1049 | dev_err(&cam->udev->dev, "ReadStream: Unable to alloc URB\n"); | ||
1050 | return -ENOMEM; | 1049 | return -ENOMEM; |
1051 | } | ||
1052 | /* transfer buffer allocated in board_init */ | 1050 | /* transfer buffer allocated in board_init */ |
1053 | usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev, | 1051 | usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev, |
1054 | pipe, | 1052 | pipe, |
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 1e819f98b94f..bb3e0d1dd355 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -2116,13 +2116,11 @@ static int vub300_probe(struct usb_interface *interface, | |||
2116 | command_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 2116 | command_out_urb = usb_alloc_urb(0, GFP_KERNEL); |
2117 | if (!command_out_urb) { | 2117 | if (!command_out_urb) { |
2118 | retval = -ENOMEM; | 2118 | retval = -ENOMEM; |
2119 | dev_err(&udev->dev, "not enough memory for command_out_urb\n"); | ||
2120 | goto error0; | 2119 | goto error0; |
2121 | } | 2120 | } |
2122 | command_res_urb = usb_alloc_urb(0, GFP_KERNEL); | 2121 | command_res_urb = usb_alloc_urb(0, GFP_KERNEL); |
2123 | if (!command_res_urb) { | 2122 | if (!command_res_urb) { |
2124 | retval = -ENOMEM; | 2123 | retval = -ENOMEM; |
2125 | dev_err(&udev->dev, "not enough memory for command_res_urb\n"); | ||
2126 | goto error1; | 2124 | goto error1; |
2127 | } | 2125 | } |
2128 | /* this also allocates memory for our VUB300 mmc host device */ | 2126 | /* this also allocates memory for our VUB300 mmc host device */ |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 19bff3a10f69..fe00f9134d51 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -24,6 +24,15 @@ config PHY_BCM_NS_USB2 | |||
24 | Enable this to support Broadcom USB 2.0 PHY connected to the USB | 24 | Enable this to support Broadcom USB 2.0 PHY connected to the USB |
25 | controller on Northstar family. | 25 | controller on Northstar family. |
26 | 26 | ||
27 | config PHY_BCM_NS_USB3 | ||
28 | tristate "Broadcom Northstar USB 3.0 PHY Driver" | ||
29 | depends on ARCH_BCM_IPROC || COMPILE_TEST | ||
30 | depends on HAS_IOMEM && OF | ||
31 | select GENERIC_PHY | ||
32 | help | ||
33 | Enable this to support Broadcom USB 3.0 PHY connected to the USB | ||
34 | controller on Northstar family. | ||
35 | |||
27 | config PHY_BERLIN_USB | 36 | config PHY_BERLIN_USB |
28 | tristate "Marvell Berlin USB PHY Driver" | 37 | tristate "Marvell Berlin USB PHY Driver" |
29 | depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF | 38 | depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF |
@@ -258,7 +267,9 @@ config PHY_SUN4I_USB | |||
258 | depends on RESET_CONTROLLER | 267 | depends on RESET_CONTROLLER |
259 | depends on EXTCON | 268 | depends on EXTCON |
260 | depends on POWER_SUPPLY | 269 | depends on POWER_SUPPLY |
270 | depends on USB_SUPPORT | ||
261 | select GENERIC_PHY | 271 | select GENERIC_PHY |
272 | select USB_COMMON | ||
262 | help | 273 | help |
263 | Enable this to support the transceiver that is part of Allwinner | 274 | Enable this to support the transceiver that is part of Allwinner |
264 | sunxi SoCs. | 275 | sunxi SoCs. |
@@ -358,6 +369,14 @@ config PHY_ROCKCHIP_USB | |||
358 | help | 369 | help |
359 | Enable this to support the Rockchip USB 2.0 PHY. | 370 | Enable this to support the Rockchip USB 2.0 PHY. |
360 | 371 | ||
372 | config PHY_ROCKCHIP_INNO_USB2 | ||
373 | tristate "Rockchip INNO USB2PHY Driver" | ||
374 | depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF | ||
375 | depends on COMMON_CLK | ||
376 | select GENERIC_PHY | ||
377 | help | ||
378 | Support for Rockchip USB2.0 PHY with Innosilicon IP block. | ||
379 | |||
361 | config PHY_ROCKCHIP_EMMC | 380 | config PHY_ROCKCHIP_EMMC |
362 | tristate "Rockchip EMMC PHY Driver" | 381 | tristate "Rockchip EMMC PHY Driver" |
363 | depends on ARCH_ROCKCHIP && OF | 382 | depends on ARCH_ROCKCHIP && OF |
@@ -372,6 +391,23 @@ config PHY_ROCKCHIP_DP | |||
372 | help | 391 | help |
373 | Enable this to support the Rockchip Display Port PHY. | 392 | Enable this to support the Rockchip Display Port PHY. |
374 | 393 | ||
394 | config PHY_ROCKCHIP_PCIE | ||
395 | tristate "Rockchip PCIe PHY Driver" | ||
396 | depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST | ||
397 | select GENERIC_PHY | ||
398 | select MFD_SYSCON | ||
399 | help | ||
400 | Enable this to support the Rockchip PCIe PHY. | ||
401 | |||
402 | config PHY_ROCKCHIP_TYPEC | ||
403 | tristate "Rockchip TYPEC PHY Driver" | ||
404 | depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST) | ||
405 | select EXTCON | ||
406 | select GENERIC_PHY | ||
407 | select RESET_CONTROLLER | ||
408 | help | ||
409 | Enable this to support the Rockchip USB TYPEC PHY. | ||
410 | |||
375 | config PHY_ST_SPEAR1310_MIPHY | 411 | config PHY_ST_SPEAR1310_MIPHY |
376 | tristate "ST SPEAR1310-MIPHY driver" | 412 | tristate "ST SPEAR1310-MIPHY driver" |
377 | select GENERIC_PHY | 413 | select GENERIC_PHY |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90ae19879b0a..a534cf5be07d 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_GENERIC_PHY) += phy-core.o | 5 | obj-$(CONFIG_GENERIC_PHY) += phy-core.o |
6 | obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o | 6 | obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o |
7 | obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o | ||
7 | obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o | 8 | obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o |
8 | obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o | 9 | obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o |
9 | obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o | 10 | obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o |
@@ -39,8 +40,11 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o | |||
39 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o | 40 | obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o |
40 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o | 41 | obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o |
41 | obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o | 42 | obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o |
43 | obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o | ||
42 | obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o | 44 | obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o |
45 | obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o | ||
43 | obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o | 46 | obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o |
47 | obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o | ||
44 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o | 48 | obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o |
45 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o | 49 | obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o |
46 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o | 50 | obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o |
diff --git a/drivers/phy/phy-bcm-ns-usb3.c b/drivers/phy/phy-bcm-ns-usb3.c new file mode 100644 index 000000000000..f420fa4bebfc --- /dev/null +++ b/drivers/phy/phy-bcm-ns-usb3.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * Broadcom Northstar USB 3.0 PHY Driver | ||
3 | * | ||
4 | * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl> | ||
5 | * | ||
6 | * All magic values used for initialization (and related comments) were obtained | ||
7 | * from Broadcom's SDK: | ||
8 | * Copyright (c) Broadcom Corp, 2012 | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/bcma/bcma.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/phy/phy.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000 /* usecs */ | ||
25 | |||
26 | enum bcm_ns_family { | ||
27 | BCM_NS_UNKNOWN, | ||
28 | BCM_NS_AX, | ||
29 | BCM_NS_BX, | ||
30 | }; | ||
31 | |||
32 | struct bcm_ns_usb3 { | ||
33 | struct device *dev; | ||
34 | enum bcm_ns_family family; | ||
35 | void __iomem *dmp; | ||
36 | void __iomem *ccb_mii; | ||
37 | struct phy *phy; | ||
38 | }; | ||
39 | |||
40 | static const struct of_device_id bcm_ns_usb3_id_table[] = { | ||
41 | { | ||
42 | .compatible = "brcm,ns-ax-usb3-phy", | ||
43 | .data = (int *)BCM_NS_AX, | ||
44 | }, | ||
45 | { | ||
46 | .compatible = "brcm,ns-bx-usb3-phy", | ||
47 | .data = (int *)BCM_NS_BX, | ||
48 | }, | ||
49 | {}, | ||
50 | }; | ||
51 | MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table); | ||
52 | |||
53 | static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr, | ||
54 | u32 mask, u32 value, unsigned long timeout) | ||
55 | { | ||
56 | unsigned long deadline = jiffies + timeout; | ||
57 | u32 val; | ||
58 | |||
59 | do { | ||
60 | val = readl(addr); | ||
61 | if ((val & mask) == value) | ||
62 | return 0; | ||
63 | cpu_relax(); | ||
64 | udelay(10); | ||
65 | } while (!time_after_eq(jiffies, deadline)); | ||
66 | |||
67 | dev_err(usb3->dev, "Timeout waiting for register %p\n", addr); | ||
68 | |||
69 | return -EBUSY; | ||
70 | } | ||
71 | |||
72 | static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3) | ||
73 | { | ||
74 | return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL, | ||
75 | 0x0100, 0x0000, | ||
76 | usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US)); | ||
77 | } | ||
78 | |||
79 | static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value) | ||
80 | { | ||
81 | int err; | ||
82 | |||
83 | err = bcm_ns_usb3_mii_mng_wait_idle(usb3); | ||
84 | if (err < 0) { | ||
85 | dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value); | ||
86 | return err; | ||
87 | } | ||
88 | |||
89 | writel(value, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3) | ||
95 | { | ||
96 | int err; | ||
97 | |||
98 | /* Enable MDIO. Setting MDCDIV as 26 */ | ||
99 | writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL); | ||
100 | |||
101 | /* Wait for MDIO? */ | ||
102 | udelay(2); | ||
103 | |||
104 | /* USB3 PLL Block */ | ||
105 | err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); | ||
106 | if (err < 0) | ||
107 | return err; | ||
108 | |||
109 | /* Assert Ana_Pllseq start */ | ||
110 | bcm_ns_usb3_mii_mng_write32(usb3, 0x58061000); | ||
111 | |||
112 | /* Assert CML Divider ratio to 26 */ | ||
113 | bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); | ||
114 | |||
115 | /* Asserting PLL Reset */ | ||
116 | bcm_ns_usb3_mii_mng_write32(usb3, 0x582ec000); | ||
117 | |||
118 | /* Deaaserting PLL Reset */ | ||
119 | bcm_ns_usb3_mii_mng_write32(usb3, 0x582e8000); | ||
120 | |||
121 | /* Waiting MII Mgt interface idle */ | ||
122 | bcm_ns_usb3_mii_mng_wait_idle(usb3); | ||
123 | |||
124 | /* Deasserting USB3 system reset */ | ||
125 | writel(0, usb3->dmp + BCMA_RESET_CTL); | ||
126 | |||
127 | /* PLL frequency monitor enable */ | ||
128 | bcm_ns_usb3_mii_mng_write32(usb3, 0x58069000); | ||
129 | |||
130 | /* PIPE Block */ | ||
131 | bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8060); | ||
132 | |||
133 | /* CMPMAX & CMPMINTH setting */ | ||
134 | bcm_ns_usb3_mii_mng_write32(usb3, 0x580af30d); | ||
135 | |||
136 | /* DEGLITCH MIN & MAX setting */ | ||
137 | bcm_ns_usb3_mii_mng_write32(usb3, 0x580e6302); | ||
138 | |||
139 | /* TXPMD block */ | ||
140 | bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8040); | ||
141 | |||
142 | /* Enabling SSC */ | ||
143 | bcm_ns_usb3_mii_mng_write32(usb3, 0x58061003); | ||
144 | |||
145 | /* Waiting MII Mgt interface idle */ | ||
146 | bcm_ns_usb3_mii_mng_wait_idle(usb3); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3) | ||
152 | { | ||
153 | int err; | ||
154 | |||
155 | /* Enable MDIO. Setting MDCDIV as 26 */ | ||
156 | writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL); | ||
157 | |||
158 | /* Wait for MDIO? */ | ||
159 | udelay(2); | ||
160 | |||
161 | /* PLL30 block */ | ||
162 | err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); | ||
163 | if (err < 0) | ||
164 | return err; | ||
165 | |||
166 | bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); | ||
167 | |||
168 | bcm_ns_usb3_mii_mng_write32(usb3, 0x587e80e0); | ||
169 | |||
170 | bcm_ns_usb3_mii_mng_write32(usb3, 0x580a009c); | ||
171 | |||
172 | /* Enable SSC */ | ||
173 | bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8040); | ||
174 | |||
175 | bcm_ns_usb3_mii_mng_write32(usb3, 0x580a21d3); | ||
176 | |||
177 | bcm_ns_usb3_mii_mng_write32(usb3, 0x58061003); | ||
178 | |||
179 | /* Waiting MII Mgt interface idle */ | ||
180 | bcm_ns_usb3_mii_mng_wait_idle(usb3); | ||
181 | |||
182 | /* Deasserting USB3 system reset */ | ||
183 | writel(0, usb3->dmp + BCMA_RESET_CTL); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int bcm_ns_usb3_phy_init(struct phy *phy) | ||
189 | { | ||
190 | struct bcm_ns_usb3 *usb3 = phy_get_drvdata(phy); | ||
191 | int err; | ||
192 | |||
193 | /* Perform USB3 system soft reset */ | ||
194 | writel(BCMA_RESET_CTL_RESET, usb3->dmp + BCMA_RESET_CTL); | ||
195 | |||
196 | switch (usb3->family) { | ||
197 | case BCM_NS_AX: | ||
198 | err = bcm_ns_usb3_phy_init_ns_ax(usb3); | ||
199 | break; | ||
200 | case BCM_NS_BX: | ||
201 | err = bcm_ns_usb3_phy_init_ns_bx(usb3); | ||
202 | break; | ||
203 | default: | ||
204 | WARN_ON(1); | ||
205 | err = -ENOTSUPP; | ||
206 | } | ||
207 | |||
208 | return err; | ||
209 | } | ||
210 | |||
211 | static const struct phy_ops ops = { | ||
212 | .init = bcm_ns_usb3_phy_init, | ||
213 | .owner = THIS_MODULE, | ||
214 | }; | ||
215 | |||
216 | static int bcm_ns_usb3_probe(struct platform_device *pdev) | ||
217 | { | ||
218 | struct device *dev = &pdev->dev; | ||
219 | const struct of_device_id *of_id; | ||
220 | struct bcm_ns_usb3 *usb3; | ||
221 | struct resource *res; | ||
222 | struct phy_provider *phy_provider; | ||
223 | |||
224 | usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL); | ||
225 | if (!usb3) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | usb3->dev = dev; | ||
229 | |||
230 | of_id = of_match_device(bcm_ns_usb3_id_table, dev); | ||
231 | if (!of_id) | ||
232 | return -EINVAL; | ||
233 | usb3->family = (enum bcm_ns_family)of_id->data; | ||
234 | |||
235 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmp"); | ||
236 | usb3->dmp = devm_ioremap_resource(dev, res); | ||
237 | if (IS_ERR(usb3->dmp)) { | ||
238 | dev_err(dev, "Failed to map DMP regs\n"); | ||
239 | return PTR_ERR(usb3->dmp); | ||
240 | } | ||
241 | |||
242 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ccb-mii"); | ||
243 | usb3->ccb_mii = devm_ioremap_resource(dev, res); | ||
244 | if (IS_ERR(usb3->ccb_mii)) { | ||
245 | dev_err(dev, "Failed to map ChipCommon B MII regs\n"); | ||
246 | return PTR_ERR(usb3->ccb_mii); | ||
247 | } | ||
248 | |||
249 | usb3->phy = devm_phy_create(dev, NULL, &ops); | ||
250 | if (IS_ERR(usb3->phy)) { | ||
251 | dev_err(dev, "Failed to create PHY\n"); | ||
252 | return PTR_ERR(usb3->phy); | ||
253 | } | ||
254 | |||
255 | phy_set_drvdata(usb3->phy, usb3); | ||
256 | platform_set_drvdata(pdev, usb3); | ||
257 | |||
258 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
259 | if (!IS_ERR(phy_provider)) | ||
260 | dev_info(dev, "Registered Broadcom Northstar USB 3.0 PHY driver\n"); | ||
261 | |||
262 | return PTR_ERR_OR_ZERO(phy_provider); | ||
263 | } | ||
264 | |||
265 | static struct platform_driver bcm_ns_usb3_driver = { | ||
266 | .probe = bcm_ns_usb3_probe, | ||
267 | .driver = { | ||
268 | .name = "bcm_ns_usb3", | ||
269 | .of_match_table = bcm_ns_usb3_id_table, | ||
270 | }, | ||
271 | }; | ||
272 | module_platform_driver(bcm_ns_usb3_driver); | ||
273 | |||
274 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-bcm-ns2-pcie.c b/drivers/phy/phy-bcm-ns2-pcie.c index 9513f7ab1eaa..4c7d11d2b378 100644 --- a/drivers/phy/phy-bcm-ns2-pcie.c +++ b/drivers/phy/phy-bcm-ns2-pcie.c | |||
@@ -18,11 +18,6 @@ | |||
18 | #include <linux/phy.h> | 18 | #include <linux/phy.h> |
19 | #include <linux/phy/phy.h> | 19 | #include <linux/phy/phy.h> |
20 | 20 | ||
21 | struct ns2_pci_phy { | ||
22 | struct mdio_device *mdiodev; | ||
23 | struct phy *phy; | ||
24 | }; | ||
25 | |||
26 | #define BLK_ADDR_REG_OFFSET 0x1f | 21 | #define BLK_ADDR_REG_OFFSET 0x1f |
27 | #define PLL_AFE1_100MHZ_BLK 0x2100 | 22 | #define PLL_AFE1_100MHZ_BLK 0x2100 |
28 | #define PLL_CLK_AMP_OFFSET 0x03 | 23 | #define PLL_CLK_AMP_OFFSET 0x03 |
@@ -30,17 +25,17 @@ struct ns2_pci_phy { | |||
30 | 25 | ||
31 | static int ns2_pci_phy_init(struct phy *p) | 26 | static int ns2_pci_phy_init(struct phy *p) |
32 | { | 27 | { |
33 | struct ns2_pci_phy *phy = phy_get_drvdata(p); | 28 | struct mdio_device *mdiodev = phy_get_drvdata(p); |
34 | int rc; | 29 | int rc; |
35 | 30 | ||
36 | /* select the AFE 100MHz block page */ | 31 | /* select the AFE 100MHz block page */ |
37 | rc = mdiobus_write(phy->mdiodev->bus, phy->mdiodev->addr, | 32 | rc = mdiobus_write(mdiodev->bus, mdiodev->addr, |
38 | BLK_ADDR_REG_OFFSET, PLL_AFE1_100MHZ_BLK); | 33 | BLK_ADDR_REG_OFFSET, PLL_AFE1_100MHZ_BLK); |
39 | if (rc) | 34 | if (rc) |
40 | goto err; | 35 | goto err; |
41 | 36 | ||
42 | /* set the 100 MHz reference clock amplitude to 2.05 v */ | 37 | /* set the 100 MHz reference clock amplitude to 2.05 v */ |
43 | rc = mdiobus_write(phy->mdiodev->bus, phy->mdiodev->addr, | 38 | rc = mdiobus_write(mdiodev->bus, mdiodev->addr, |
44 | PLL_CLK_AMP_OFFSET, PLL_CLK_AMP_2P05V); | 39 | PLL_CLK_AMP_OFFSET, PLL_CLK_AMP_2P05V); |
45 | if (rc) | 40 | if (rc) |
46 | goto err; | 41 | goto err; |
@@ -48,19 +43,19 @@ static int ns2_pci_phy_init(struct phy *p) | |||
48 | return 0; | 43 | return 0; |
49 | 44 | ||
50 | err: | 45 | err: |
51 | dev_err(&phy->mdiodev->dev, "Error %d writing to phy\n", rc); | 46 | dev_err(&mdiodev->dev, "Error %d writing to phy\n", rc); |
52 | return rc; | 47 | return rc; |
53 | } | 48 | } |
54 | 49 | ||
55 | static struct phy_ops ns2_pci_phy_ops = { | 50 | static const struct phy_ops ns2_pci_phy_ops = { |
56 | .init = ns2_pci_phy_init, | 51 | .init = ns2_pci_phy_init, |
52 | .owner = THIS_MODULE, | ||
57 | }; | 53 | }; |
58 | 54 | ||
59 | static int ns2_pci_phy_probe(struct mdio_device *mdiodev) | 55 | static int ns2_pci_phy_probe(struct mdio_device *mdiodev) |
60 | { | 56 | { |
61 | struct device *dev = &mdiodev->dev; | 57 | struct device *dev = &mdiodev->dev; |
62 | struct phy_provider *provider; | 58 | struct phy_provider *provider; |
63 | struct ns2_pci_phy *p; | ||
64 | struct phy *phy; | 59 | struct phy *phy; |
65 | 60 | ||
66 | phy = devm_phy_create(dev, dev->of_node, &ns2_pci_phy_ops); | 61 | phy = devm_phy_create(dev, dev->of_node, &ns2_pci_phy_ops); |
@@ -69,16 +64,7 @@ static int ns2_pci_phy_probe(struct mdio_device *mdiodev) | |||
69 | return PTR_ERR(phy); | 64 | return PTR_ERR(phy); |
70 | } | 65 | } |
71 | 66 | ||
72 | p = devm_kmalloc(dev, sizeof(struct ns2_pci_phy), | 67 | phy_set_drvdata(phy, mdiodev); |
73 | GFP_KERNEL); | ||
74 | if (!p) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | p->mdiodev = mdiodev; | ||
78 | dev_set_drvdata(dev, p); | ||
79 | |||
80 | p->phy = phy; | ||
81 | phy_set_drvdata(phy, p); | ||
82 | 68 | ||
83 | provider = devm_of_phy_provider_register(&phy->dev, | 69 | provider = devm_of_phy_provider_register(&phy->dev, |
84 | of_phy_simple_xlate); | 70 | of_phy_simple_xlate); |
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 8eca906b6e70..a268f4d6f3e9 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -357,6 +357,21 @@ int phy_set_mode(struct phy *phy, enum phy_mode mode) | |||
357 | } | 357 | } |
358 | EXPORT_SYMBOL_GPL(phy_set_mode); | 358 | EXPORT_SYMBOL_GPL(phy_set_mode); |
359 | 359 | ||
360 | int phy_reset(struct phy *phy) | ||
361 | { | ||
362 | int ret; | ||
363 | |||
364 | if (!phy || !phy->ops->reset) | ||
365 | return 0; | ||
366 | |||
367 | mutex_lock(&phy->mutex); | ||
368 | ret = phy->ops->reset(phy); | ||
369 | mutex_unlock(&phy->mutex); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | EXPORT_SYMBOL_GPL(phy_reset); | ||
374 | |||
360 | /** | 375 | /** |
361 | * _of_phy_get() - lookup and obtain a reference to a phy by phandle | 376 | * _of_phy_get() - lookup and obtain a reference to a phy by phandle |
362 | * @np: device_node for which to get the phy | 377 | * @np: device_node for which to get the phy |
diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c index b2e59b6170ac..32ae78c8ca17 100644 --- a/drivers/phy/phy-da8xx-usb.c +++ b/drivers/phy/phy-da8xx-usb.c | |||
@@ -154,7 +154,7 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev) | |||
154 | d_phy->regmap = syscon_regmap_lookup_by_compatible( | 154 | d_phy->regmap = syscon_regmap_lookup_by_compatible( |
155 | "ti,da830-cfgchip"); | 155 | "ti,da830-cfgchip"); |
156 | else | 156 | else |
157 | d_phy->regmap = syscon_regmap_lookup_by_pdevname("syscon.0"); | 157 | d_phy->regmap = syscon_regmap_lookup_by_pdevname("syscon"); |
158 | if (IS_ERR(d_phy->regmap)) { | 158 | if (IS_ERR(d_phy->regmap)) { |
159 | dev_err(dev, "Failed to get syscon\n"); | 159 | dev_err(dev, "Failed to get syscon\n"); |
160 | return PTR_ERR(d_phy->regmap); | 160 | return PTR_ERR(d_phy->regmap); |
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index 20696f53303f..07ed608905ac 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c | |||
@@ -249,7 +249,7 @@ static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst, | |||
249 | static unsigned int | 249 | static unsigned int |
250 | exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) | 250 | exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) |
251 | { | 251 | { |
252 | static u32 reg; | 252 | u32 reg; |
253 | struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); | 253 | struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); |
254 | 254 | ||
255 | /* restore any previous reference clock settings */ | 255 | /* restore any previous reference clock settings */ |
@@ -295,7 +295,7 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) | |||
295 | static unsigned int | 295 | static unsigned int |
296 | exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) | 296 | exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) |
297 | { | 297 | { |
298 | static u32 reg; | 298 | u32 reg; |
299 | struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); | 299 | struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); |
300 | 300 | ||
301 | /* restore any previous reference clock settings */ | 301 | /* restore any previous reference clock settings */ |
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index c134989052f5..fe909fd8144f 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
@@ -133,11 +133,49 @@ static int omap_usb_power_on(struct phy *x) | |||
133 | return omap_usb_phy_power(phy, true); | 133 | return omap_usb_phy_power(phy, true); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int omap_usb2_disable_clocks(struct omap_usb *phy) | ||
137 | { | ||
138 | clk_disable(phy->wkupclk); | ||
139 | if (!IS_ERR(phy->optclk)) | ||
140 | clk_disable(phy->optclk); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int omap_usb2_enable_clocks(struct omap_usb *phy) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | ret = clk_enable(phy->wkupclk); | ||
150 | if (ret < 0) { | ||
151 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | ||
152 | goto err0; | ||
153 | } | ||
154 | |||
155 | if (!IS_ERR(phy->optclk)) { | ||
156 | ret = clk_enable(phy->optclk); | ||
157 | if (ret < 0) { | ||
158 | dev_err(phy->dev, "Failed to enable optclk %d\n", ret); | ||
159 | goto err1; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | |||
165 | err1: | ||
166 | clk_disable(phy->wkupclk); | ||
167 | |||
168 | err0: | ||
169 | return ret; | ||
170 | } | ||
171 | |||
136 | static int omap_usb_init(struct phy *x) | 172 | static int omap_usb_init(struct phy *x) |
137 | { | 173 | { |
138 | struct omap_usb *phy = phy_get_drvdata(x); | 174 | struct omap_usb *phy = phy_get_drvdata(x); |
139 | u32 val; | 175 | u32 val; |
140 | 176 | ||
177 | omap_usb2_enable_clocks(phy); | ||
178 | |||
141 | if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { | 179 | if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { |
142 | /* | 180 | /* |
143 | * | 181 | * |
@@ -155,8 +193,16 @@ static int omap_usb_init(struct phy *x) | |||
155 | return 0; | 193 | return 0; |
156 | } | 194 | } |
157 | 195 | ||
196 | static int omap_usb_exit(struct phy *x) | ||
197 | { | ||
198 | struct omap_usb *phy = phy_get_drvdata(x); | ||
199 | |||
200 | return omap_usb2_disable_clocks(phy); | ||
201 | } | ||
202 | |||
158 | static const struct phy_ops ops = { | 203 | static const struct phy_ops ops = { |
159 | .init = omap_usb_init, | 204 | .init = omap_usb_init, |
205 | .exit = omap_usb_exit, | ||
160 | .power_on = omap_usb_power_on, | 206 | .power_on = omap_usb_power_on, |
161 | .power_off = omap_usb_power_off, | 207 | .power_off = omap_usb_power_off, |
162 | .owner = THIS_MODULE, | 208 | .owner = THIS_MODULE, |
@@ -376,65 +422,11 @@ static int omap_usb2_remove(struct platform_device *pdev) | |||
376 | return 0; | 422 | return 0; |
377 | } | 423 | } |
378 | 424 | ||
379 | #ifdef CONFIG_PM | ||
380 | |||
381 | static int omap_usb2_runtime_suspend(struct device *dev) | ||
382 | { | ||
383 | struct platform_device *pdev = to_platform_device(dev); | ||
384 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
385 | |||
386 | clk_disable(phy->wkupclk); | ||
387 | if (!IS_ERR(phy->optclk)) | ||
388 | clk_disable(phy->optclk); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int omap_usb2_runtime_resume(struct device *dev) | ||
394 | { | ||
395 | struct platform_device *pdev = to_platform_device(dev); | ||
396 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
397 | int ret; | ||
398 | |||
399 | ret = clk_enable(phy->wkupclk); | ||
400 | if (ret < 0) { | ||
401 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | ||
402 | goto err0; | ||
403 | } | ||
404 | |||
405 | if (!IS_ERR(phy->optclk)) { | ||
406 | ret = clk_enable(phy->optclk); | ||
407 | if (ret < 0) { | ||
408 | dev_err(phy->dev, "Failed to enable optclk %d\n", ret); | ||
409 | goto err1; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | return 0; | ||
414 | |||
415 | err1: | ||
416 | clk_disable(phy->wkupclk); | ||
417 | |||
418 | err0: | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | static const struct dev_pm_ops omap_usb2_pm_ops = { | ||
423 | SET_RUNTIME_PM_OPS(omap_usb2_runtime_suspend, omap_usb2_runtime_resume, | ||
424 | NULL) | ||
425 | }; | ||
426 | |||
427 | #define DEV_PM_OPS (&omap_usb2_pm_ops) | ||
428 | #else | ||
429 | #define DEV_PM_OPS NULL | ||
430 | #endif | ||
431 | |||
432 | static struct platform_driver omap_usb2_driver = { | 425 | static struct platform_driver omap_usb2_driver = { |
433 | .probe = omap_usb2_probe, | 426 | .probe = omap_usb2_probe, |
434 | .remove = omap_usb2_remove, | 427 | .remove = omap_usb2_remove, |
435 | .driver = { | 428 | .driver = { |
436 | .name = "omap-usb2", | 429 | .name = "omap-usb2", |
437 | .pm = DEV_PM_OPS, | ||
438 | .of_match_table = omap_usb2_id_table, | 430 | .of_match_table = omap_usb2_id_table, |
439 | }, | 431 | }, |
440 | }; | 432 | }; |
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c index 107cb57c3513..18a5b495ad65 100644 --- a/drivers/phy/phy-qcom-ufs.c +++ b/drivers/phy/phy-qcom-ufs.c | |||
@@ -283,10 +283,8 @@ static int __ufs_qcom_phy_init_vreg(struct phy *phy, | |||
283 | err = 0; | 283 | err = 0; |
284 | } | 284 | } |
285 | snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name); | 285 | snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name); |
286 | if (of_get_property(dev->of_node, prop_name, NULL)) | 286 | vreg->is_always_on = of_property_read_bool(dev->of_node, |
287 | vreg->is_always_on = true; | 287 | prop_name); |
288 | else | ||
289 | vreg->is_always_on = false; | ||
290 | } | 288 | } |
291 | 289 | ||
292 | if (!strcmp(name, "vdda-pll")) { | 290 | if (!strcmp(name, "vdda-pll")) { |
diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c index 31156c9c4707..3d97eadd247d 100644 --- a/drivers/phy/phy-rcar-gen3-usb2.c +++ b/drivers/phy/phy-rcar-gen3-usb2.c | |||
@@ -280,6 +280,7 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) | |||
280 | 280 | ||
281 | static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { | 281 | static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { |
282 | { .compatible = "renesas,usb2-phy-r8a7795" }, | 282 | { .compatible = "renesas,usb2-phy-r8a7795" }, |
283 | { .compatible = "renesas,usb2-phy-r8a7796" }, | ||
283 | { .compatible = "renesas,rcar-gen3-usb2-phy" }, | 284 | { .compatible = "renesas,rcar-gen3-usb2-phy" }, |
284 | { } | 285 | { } |
285 | }; | 286 | }; |
diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c new file mode 100644 index 000000000000..ac203107b071 --- /dev/null +++ b/drivers/phy/phy-rockchip-inno-usb2.c | |||
@@ -0,0 +1,707 @@ | |||
1 | /* | ||
2 | * Rockchip USB2.0 PHY with Innosilicon IP block driver | ||
3 | * | ||
4 | * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/gpio/consumer.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/of_irq.h> | ||
30 | #include <linux/of_platform.h> | ||
31 | #include <linux/phy/phy.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/regmap.h> | ||
34 | #include <linux/mfd/syscon.h> | ||
35 | |||
36 | #define BIT_WRITEABLE_SHIFT 16 | ||
37 | #define SCHEDULE_DELAY (60 * HZ) | ||
38 | |||
39 | enum rockchip_usb2phy_port_id { | ||
40 | USB2PHY_PORT_OTG, | ||
41 | USB2PHY_PORT_HOST, | ||
42 | USB2PHY_NUM_PORTS, | ||
43 | }; | ||
44 | |||
45 | enum rockchip_usb2phy_host_state { | ||
46 | PHY_STATE_HS_ONLINE = 0, | ||
47 | PHY_STATE_DISCONNECT = 1, | ||
48 | PHY_STATE_CONNECT = 2, | ||
49 | PHY_STATE_FS_LS_ONLINE = 4, | ||
50 | }; | ||
51 | |||
52 | struct usb2phy_reg { | ||
53 | unsigned int offset; | ||
54 | unsigned int bitend; | ||
55 | unsigned int bitstart; | ||
56 | unsigned int disable; | ||
57 | unsigned int enable; | ||
58 | }; | ||
59 | |||
60 | /** | ||
61 | * struct rockchip_usb2phy_port_cfg: usb-phy port configuration. | ||
62 | * @phy_sus: phy suspend register. | ||
63 | * @ls_det_en: linestate detection enable register. | ||
64 | * @ls_det_st: linestate detection state register. | ||
65 | * @ls_det_clr: linestate detection clear register. | ||
66 | * @utmi_ls: utmi linestate state register. | ||
67 | * @utmi_hstdet: utmi host disconnect register. | ||
68 | */ | ||
69 | struct rockchip_usb2phy_port_cfg { | ||
70 | struct usb2phy_reg phy_sus; | ||
71 | struct usb2phy_reg ls_det_en; | ||
72 | struct usb2phy_reg ls_det_st; | ||
73 | struct usb2phy_reg ls_det_clr; | ||
74 | struct usb2phy_reg utmi_ls; | ||
75 | struct usb2phy_reg utmi_hstdet; | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * struct rockchip_usb2phy_cfg: usb-phy configuration. | ||
80 | * @reg: the address offset of grf for usb-phy config. | ||
81 | * @num_ports: specify how many ports that the phy has. | ||
82 | * @clkout_ctl: keep on/turn off output clk of phy. | ||
83 | */ | ||
84 | struct rockchip_usb2phy_cfg { | ||
85 | unsigned int reg; | ||
86 | unsigned int num_ports; | ||
87 | struct usb2phy_reg clkout_ctl; | ||
88 | const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; | ||
89 | }; | ||
90 | |||
91 | /** | ||
92 | * struct rockchip_usb2phy_port: usb-phy port data. | ||
93 | * @port_id: flag for otg port or host port. | ||
94 | * @suspended: phy suspended flag. | ||
95 | * @ls_irq: IRQ number assigned for linestate detection. | ||
96 | * @mutex: for register updating in sm_work. | ||
97 | * @sm_work: OTG state machine work. | ||
98 | * @phy_cfg: port register configuration, assigned by driver data. | ||
99 | */ | ||
100 | struct rockchip_usb2phy_port { | ||
101 | struct phy *phy; | ||
102 | unsigned int port_id; | ||
103 | bool suspended; | ||
104 | int ls_irq; | ||
105 | struct mutex mutex; | ||
106 | struct delayed_work sm_work; | ||
107 | const struct rockchip_usb2phy_port_cfg *port_cfg; | ||
108 | }; | ||
109 | |||
110 | /** | ||
111 | * struct rockchip_usb2phy: usb2.0 phy driver data. | ||
112 | * @grf: General Register Files regmap. | ||
113 | * @clk: clock struct of phy input clk. | ||
114 | * @clk480m: clock struct of phy output clk. | ||
115 | * @clk_hw: clock struct of phy output clk management. | ||
116 | * @phy_cfg: phy register configuration, assigned by driver data. | ||
117 | * @ports: phy port instance. | ||
118 | */ | ||
119 | struct rockchip_usb2phy { | ||
120 | struct device *dev; | ||
121 | struct regmap *grf; | ||
122 | struct clk *clk; | ||
123 | struct clk *clk480m; | ||
124 | struct clk_hw clk480m_hw; | ||
125 | const struct rockchip_usb2phy_cfg *phy_cfg; | ||
126 | struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS]; | ||
127 | }; | ||
128 | |||
129 | static inline int property_enable(struct rockchip_usb2phy *rphy, | ||
130 | const struct usb2phy_reg *reg, bool en) | ||
131 | { | ||
132 | unsigned int val, mask, tmp; | ||
133 | |||
134 | tmp = en ? reg->enable : reg->disable; | ||
135 | mask = GENMASK(reg->bitend, reg->bitstart); | ||
136 | val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); | ||
137 | |||
138 | return regmap_write(rphy->grf, reg->offset, val); | ||
139 | } | ||
140 | |||
141 | static inline bool property_enabled(struct rockchip_usb2phy *rphy, | ||
142 | const struct usb2phy_reg *reg) | ||
143 | { | ||
144 | int ret; | ||
145 | unsigned int tmp, orig; | ||
146 | unsigned int mask = GENMASK(reg->bitend, reg->bitstart); | ||
147 | |||
148 | ret = regmap_read(rphy->grf, reg->offset, &orig); | ||
149 | if (ret) | ||
150 | return false; | ||
151 | |||
152 | tmp = (orig & mask) >> reg->bitstart; | ||
153 | return tmp == reg->enable; | ||
154 | } | ||
155 | |||
156 | static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw) | ||
157 | { | ||
158 | struct rockchip_usb2phy *rphy = | ||
159 | container_of(hw, struct rockchip_usb2phy, clk480m_hw); | ||
160 | int ret; | ||
161 | |||
162 | /* turn on 480m clk output if it is off */ | ||
163 | if (!property_enabled(rphy, &rphy->phy_cfg->clkout_ctl)) { | ||
164 | ret = property_enable(rphy, &rphy->phy_cfg->clkout_ctl, true); | ||
165 | if (ret) | ||
166 | return ret; | ||
167 | |||
168 | /* waitting for the clk become stable */ | ||
169 | mdelay(1); | ||
170 | } | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static void rockchip_usb2phy_clk480m_disable(struct clk_hw *hw) | ||
176 | { | ||
177 | struct rockchip_usb2phy *rphy = | ||
178 | container_of(hw, struct rockchip_usb2phy, clk480m_hw); | ||
179 | |||
180 | /* turn off 480m clk output */ | ||
181 | property_enable(rphy, &rphy->phy_cfg->clkout_ctl, false); | ||
182 | } | ||
183 | |||
184 | static int rockchip_usb2phy_clk480m_enabled(struct clk_hw *hw) | ||
185 | { | ||
186 | struct rockchip_usb2phy *rphy = | ||
187 | container_of(hw, struct rockchip_usb2phy, clk480m_hw); | ||
188 | |||
189 | return property_enabled(rphy, &rphy->phy_cfg->clkout_ctl); | ||
190 | } | ||
191 | |||
192 | static unsigned long | ||
193 | rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw, | ||
194 | unsigned long parent_rate) | ||
195 | { | ||
196 | return 480000000; | ||
197 | } | ||
198 | |||
199 | static const struct clk_ops rockchip_usb2phy_clkout_ops = { | ||
200 | .enable = rockchip_usb2phy_clk480m_enable, | ||
201 | .disable = rockchip_usb2phy_clk480m_disable, | ||
202 | .is_enabled = rockchip_usb2phy_clk480m_enabled, | ||
203 | .recalc_rate = rockchip_usb2phy_clk480m_recalc_rate, | ||
204 | }; | ||
205 | |||
206 | static void rockchip_usb2phy_clk480m_unregister(void *data) | ||
207 | { | ||
208 | struct rockchip_usb2phy *rphy = data; | ||
209 | |||
210 | of_clk_del_provider(rphy->dev->of_node); | ||
211 | clk_unregister(rphy->clk480m); | ||
212 | } | ||
213 | |||
214 | static int | ||
215 | rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy) | ||
216 | { | ||
217 | struct device_node *node = rphy->dev->of_node; | ||
218 | struct clk_init_data init; | ||
219 | const char *clk_name; | ||
220 | int ret; | ||
221 | |||
222 | init.flags = 0; | ||
223 | init.name = "clk_usbphy_480m"; | ||
224 | init.ops = &rockchip_usb2phy_clkout_ops; | ||
225 | |||
226 | /* optional override of the clockname */ | ||
227 | of_property_read_string(node, "clock-output-names", &init.name); | ||
228 | |||
229 | if (rphy->clk) { | ||
230 | clk_name = __clk_get_name(rphy->clk); | ||
231 | init.parent_names = &clk_name; | ||
232 | init.num_parents = 1; | ||
233 | } else { | ||
234 | init.parent_names = NULL; | ||
235 | init.num_parents = 0; | ||
236 | } | ||
237 | |||
238 | rphy->clk480m_hw.init = &init; | ||
239 | |||
240 | /* register the clock */ | ||
241 | rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw); | ||
242 | if (IS_ERR(rphy->clk480m)) { | ||
243 | ret = PTR_ERR(rphy->clk480m); | ||
244 | goto err_ret; | ||
245 | } | ||
246 | |||
247 | ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m); | ||
248 | if (ret < 0) | ||
249 | goto err_clk_provider; | ||
250 | |||
251 | ret = devm_add_action(rphy->dev, rockchip_usb2phy_clk480m_unregister, | ||
252 | rphy); | ||
253 | if (ret < 0) | ||
254 | goto err_unreg_action; | ||
255 | |||
256 | return 0; | ||
257 | |||
258 | err_unreg_action: | ||
259 | of_clk_del_provider(node); | ||
260 | err_clk_provider: | ||
261 | clk_unregister(rphy->clk480m); | ||
262 | err_ret: | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static int rockchip_usb2phy_init(struct phy *phy) | ||
267 | { | ||
268 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); | ||
269 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); | ||
270 | int ret; | ||
271 | |||
272 | if (rport->port_id == USB2PHY_PORT_HOST) { | ||
273 | /* clear linestate and enable linestate detect irq */ | ||
274 | mutex_lock(&rport->mutex); | ||
275 | |||
276 | ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true); | ||
277 | if (ret) { | ||
278 | mutex_unlock(&rport->mutex); | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true); | ||
283 | if (ret) { | ||
284 | mutex_unlock(&rport->mutex); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | mutex_unlock(&rport->mutex); | ||
289 | schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY); | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int rockchip_usb2phy_power_on(struct phy *phy) | ||
296 | { | ||
297 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); | ||
298 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); | ||
299 | int ret; | ||
300 | |||
301 | dev_dbg(&rport->phy->dev, "port power on\n"); | ||
302 | |||
303 | if (!rport->suspended) | ||
304 | return 0; | ||
305 | |||
306 | ret = clk_prepare_enable(rphy->clk480m); | ||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | ret = property_enable(rphy, &rport->port_cfg->phy_sus, false); | ||
311 | if (ret) | ||
312 | return ret; | ||
313 | |||
314 | rport->suspended = false; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int rockchip_usb2phy_power_off(struct phy *phy) | ||
319 | { | ||
320 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); | ||
321 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); | ||
322 | int ret; | ||
323 | |||
324 | dev_dbg(&rport->phy->dev, "port power off\n"); | ||
325 | |||
326 | if (rport->suspended) | ||
327 | return 0; | ||
328 | |||
329 | ret = property_enable(rphy, &rport->port_cfg->phy_sus, true); | ||
330 | if (ret) | ||
331 | return ret; | ||
332 | |||
333 | rport->suspended = true; | ||
334 | clk_disable_unprepare(rphy->clk480m); | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int rockchip_usb2phy_exit(struct phy *phy) | ||
340 | { | ||
341 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); | ||
342 | |||
343 | if (rport->port_id == USB2PHY_PORT_HOST) | ||
344 | cancel_delayed_work_sync(&rport->sm_work); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static const struct phy_ops rockchip_usb2phy_ops = { | ||
350 | .init = rockchip_usb2phy_init, | ||
351 | .exit = rockchip_usb2phy_exit, | ||
352 | .power_on = rockchip_usb2phy_power_on, | ||
353 | .power_off = rockchip_usb2phy_power_off, | ||
354 | .owner = THIS_MODULE, | ||
355 | }; | ||
356 | |||
357 | /* | ||
358 | * The function manage host-phy port state and suspend/resume phy port | ||
359 | * to save power. | ||
360 | * | ||
361 | * we rely on utmi_linestate and utmi_hostdisconnect to identify whether | ||
362 | * devices is disconnect or not. Besides, we do not need care it is FS/LS | ||
363 | * disconnected or HS disconnected, actually, we just only need get the | ||
364 | * device is disconnected at last through rearm the delayed work, | ||
365 | * to suspend the phy port in _PHY_STATE_DISCONNECT_ case. | ||
366 | * | ||
367 | * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke | ||
368 | * some clk related APIs, so do not invoke it from interrupt context directly. | ||
369 | */ | ||
370 | static void rockchip_usb2phy_sm_work(struct work_struct *work) | ||
371 | { | ||
372 | struct rockchip_usb2phy_port *rport = | ||
373 | container_of(work, struct rockchip_usb2phy_port, sm_work.work); | ||
374 | struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); | ||
375 | unsigned int sh = rport->port_cfg->utmi_hstdet.bitend - | ||
376 | rport->port_cfg->utmi_hstdet.bitstart + 1; | ||
377 | unsigned int ul, uhd, state; | ||
378 | unsigned int ul_mask, uhd_mask; | ||
379 | int ret; | ||
380 | |||
381 | mutex_lock(&rport->mutex); | ||
382 | |||
383 | ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul); | ||
384 | if (ret < 0) | ||
385 | goto next_schedule; | ||
386 | |||
387 | ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, | ||
388 | &uhd); | ||
389 | if (ret < 0) | ||
390 | goto next_schedule; | ||
391 | |||
392 | uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend, | ||
393 | rport->port_cfg->utmi_hstdet.bitstart); | ||
394 | ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend, | ||
395 | rport->port_cfg->utmi_ls.bitstart); | ||
396 | |||
397 | /* stitch on utmi_ls and utmi_hstdet as phy state */ | ||
398 | state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) | | ||
399 | (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh); | ||
400 | |||
401 | switch (state) { | ||
402 | case PHY_STATE_HS_ONLINE: | ||
403 | dev_dbg(&rport->phy->dev, "HS online\n"); | ||
404 | break; | ||
405 | case PHY_STATE_FS_LS_ONLINE: | ||
406 | /* | ||
407 | * For FS/LS device, the online state share with connect state | ||
408 | * from utmi_ls and utmi_hstdet register, so we distinguish | ||
409 | * them via suspended flag. | ||
410 | * | ||
411 | * Plus, there are two cases, one is D- Line pull-up, and D+ | ||
412 | * line pull-down, the state is 4; another is D+ line pull-up, | ||
413 | * and D- line pull-down, the state is 2. | ||
414 | */ | ||
415 | if (!rport->suspended) { | ||
416 | /* D- line pull-up, D+ line pull-down */ | ||
417 | dev_dbg(&rport->phy->dev, "FS/LS online\n"); | ||
418 | break; | ||
419 | } | ||
420 | /* fall through */ | ||
421 | case PHY_STATE_CONNECT: | ||
422 | if (rport->suspended) { | ||
423 | dev_dbg(&rport->phy->dev, "Connected\n"); | ||
424 | rockchip_usb2phy_power_on(rport->phy); | ||
425 | rport->suspended = false; | ||
426 | } else { | ||
427 | /* D+ line pull-up, D- line pull-down */ | ||
428 | dev_dbg(&rport->phy->dev, "FS/LS online\n"); | ||
429 | } | ||
430 | break; | ||
431 | case PHY_STATE_DISCONNECT: | ||
432 | if (!rport->suspended) { | ||
433 | dev_dbg(&rport->phy->dev, "Disconnected\n"); | ||
434 | rockchip_usb2phy_power_off(rport->phy); | ||
435 | rport->suspended = true; | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * activate the linestate detection to get the next device | ||
440 | * plug-in irq. | ||
441 | */ | ||
442 | property_enable(rphy, &rport->port_cfg->ls_det_clr, true); | ||
443 | property_enable(rphy, &rport->port_cfg->ls_det_en, true); | ||
444 | |||
445 | /* | ||
446 | * we don't need to rearm the delayed work when the phy port | ||
447 | * is suspended. | ||
448 | */ | ||
449 | mutex_unlock(&rport->mutex); | ||
450 | return; | ||
451 | default: | ||
452 | dev_dbg(&rport->phy->dev, "unknown phy state\n"); | ||
453 | break; | ||
454 | } | ||
455 | |||
456 | next_schedule: | ||
457 | mutex_unlock(&rport->mutex); | ||
458 | schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY); | ||
459 | } | ||
460 | |||
461 | static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data) | ||
462 | { | ||
463 | struct rockchip_usb2phy_port *rport = data; | ||
464 | struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); | ||
465 | |||
466 | if (!property_enabled(rphy, &rport->port_cfg->ls_det_st)) | ||
467 | return IRQ_NONE; | ||
468 | |||
469 | mutex_lock(&rport->mutex); | ||
470 | |||
471 | /* disable linestate detect irq and clear its status */ | ||
472 | property_enable(rphy, &rport->port_cfg->ls_det_en, false); | ||
473 | property_enable(rphy, &rport->port_cfg->ls_det_clr, true); | ||
474 | |||
475 | mutex_unlock(&rport->mutex); | ||
476 | |||
477 | /* | ||
478 | * In this case for host phy port, a new device is plugged in, | ||
479 | * meanwhile, if the phy port is suspended, we need rearm the work to | ||
480 | * resume it and mange its states; otherwise, we do nothing about that. | ||
481 | */ | ||
482 | if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST) | ||
483 | rockchip_usb2phy_sm_work(&rport->sm_work.work); | ||
484 | |||
485 | return IRQ_HANDLED; | ||
486 | } | ||
487 | |||
488 | static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, | ||
489 | struct rockchip_usb2phy_port *rport, | ||
490 | struct device_node *child_np) | ||
491 | { | ||
492 | int ret; | ||
493 | |||
494 | rport->port_id = USB2PHY_PORT_HOST; | ||
495 | rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST]; | ||
496 | rport->suspended = true; | ||
497 | |||
498 | mutex_init(&rport->mutex); | ||
499 | INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work); | ||
500 | |||
501 | rport->ls_irq = of_irq_get_byname(child_np, "linestate"); | ||
502 | if (rport->ls_irq < 0) { | ||
503 | dev_err(rphy->dev, "no linestate irq provided\n"); | ||
504 | return rport->ls_irq; | ||
505 | } | ||
506 | |||
507 | ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL, | ||
508 | rockchip_usb2phy_linestate_irq, | ||
509 | IRQF_ONESHOT, | ||
510 | "rockchip_usb2phy", rport); | ||
511 | if (ret) { | ||
512 | dev_err(rphy->dev, "failed to request irq handle\n"); | ||
513 | return ret; | ||
514 | } | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int rockchip_usb2phy_probe(struct platform_device *pdev) | ||
520 | { | ||
521 | struct device *dev = &pdev->dev; | ||
522 | struct device_node *np = dev->of_node; | ||
523 | struct device_node *child_np; | ||
524 | struct phy_provider *provider; | ||
525 | struct rockchip_usb2phy *rphy; | ||
526 | const struct rockchip_usb2phy_cfg *phy_cfgs; | ||
527 | const struct of_device_id *match; | ||
528 | unsigned int reg; | ||
529 | int index, ret; | ||
530 | |||
531 | rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL); | ||
532 | if (!rphy) | ||
533 | return -ENOMEM; | ||
534 | |||
535 | match = of_match_device(dev->driver->of_match_table, dev); | ||
536 | if (!match || !match->data) { | ||
537 | dev_err(dev, "phy configs are not assigned!\n"); | ||
538 | return -EINVAL; | ||
539 | } | ||
540 | |||
541 | if (!dev->parent || !dev->parent->of_node) | ||
542 | return -EINVAL; | ||
543 | |||
544 | rphy->grf = syscon_node_to_regmap(dev->parent->of_node); | ||
545 | if (IS_ERR(rphy->grf)) | ||
546 | return PTR_ERR(rphy->grf); | ||
547 | |||
548 | if (of_property_read_u32(np, "reg", ®)) { | ||
549 | dev_err(dev, "the reg property is not assigned in %s node\n", | ||
550 | np->name); | ||
551 | return -EINVAL; | ||
552 | } | ||
553 | |||
554 | rphy->dev = dev; | ||
555 | phy_cfgs = match->data; | ||
556 | platform_set_drvdata(pdev, rphy); | ||
557 | |||
558 | /* find out a proper config which can be matched with dt. */ | ||
559 | index = 0; | ||
560 | while (phy_cfgs[index].reg) { | ||
561 | if (phy_cfgs[index].reg == reg) { | ||
562 | rphy->phy_cfg = &phy_cfgs[index]; | ||
563 | break; | ||
564 | } | ||
565 | |||
566 | ++index; | ||
567 | } | ||
568 | |||
569 | if (!rphy->phy_cfg) { | ||
570 | dev_err(dev, "no phy-config can be matched with %s node\n", | ||
571 | np->name); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | |||
575 | rphy->clk = of_clk_get_by_name(np, "phyclk"); | ||
576 | if (!IS_ERR(rphy->clk)) { | ||
577 | clk_prepare_enable(rphy->clk); | ||
578 | } else { | ||
579 | dev_info(&pdev->dev, "no phyclk specified\n"); | ||
580 | rphy->clk = NULL; | ||
581 | } | ||
582 | |||
583 | ret = rockchip_usb2phy_clk480m_register(rphy); | ||
584 | if (ret) { | ||
585 | dev_err(dev, "failed to register 480m output clock\n"); | ||
586 | goto disable_clks; | ||
587 | } | ||
588 | |||
589 | index = 0; | ||
590 | for_each_available_child_of_node(np, child_np) { | ||
591 | struct rockchip_usb2phy_port *rport = &rphy->ports[index]; | ||
592 | struct phy *phy; | ||
593 | |||
594 | /* | ||
595 | * This driver aim to support both otg-port and host-port, | ||
596 | * but unfortunately, the otg part is not ready in current, | ||
597 | * so this comments and below codes are interim, which should | ||
598 | * be changed after otg-port is supplied soon. | ||
599 | */ | ||
600 | if (of_node_cmp(child_np->name, "host-port")) | ||
601 | goto next_child; | ||
602 | |||
603 | phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); | ||
604 | if (IS_ERR(phy)) { | ||
605 | dev_err(dev, "failed to create phy\n"); | ||
606 | ret = PTR_ERR(phy); | ||
607 | goto put_child; | ||
608 | } | ||
609 | |||
610 | rport->phy = phy; | ||
611 | phy_set_drvdata(rport->phy, rport); | ||
612 | |||
613 | ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np); | ||
614 | if (ret) | ||
615 | goto put_child; | ||
616 | |||
617 | next_child: | ||
618 | /* to prevent out of boundary */ | ||
619 | if (++index >= rphy->phy_cfg->num_ports) | ||
620 | break; | ||
621 | } | ||
622 | |||
623 | provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
624 | return PTR_ERR_OR_ZERO(provider); | ||
625 | |||
626 | put_child: | ||
627 | of_node_put(child_np); | ||
628 | disable_clks: | ||
629 | if (rphy->clk) { | ||
630 | clk_disable_unprepare(rphy->clk); | ||
631 | clk_put(rphy->clk); | ||
632 | } | ||
633 | return ret; | ||
634 | } | ||
635 | |||
636 | static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = { | ||
637 | { | ||
638 | .reg = 0x700, | ||
639 | .num_ports = 2, | ||
640 | .clkout_ctl = { 0x0724, 15, 15, 1, 0 }, | ||
641 | .port_cfgs = { | ||
642 | [USB2PHY_PORT_HOST] = { | ||
643 | .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 }, | ||
644 | .ls_det_en = { 0x0680, 4, 4, 0, 1 }, | ||
645 | .ls_det_st = { 0x0690, 4, 4, 0, 1 }, | ||
646 | .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }, | ||
647 | .utmi_ls = { 0x049c, 14, 13, 0, 1 }, | ||
648 | .utmi_hstdet = { 0x049c, 12, 12, 0, 1 } | ||
649 | } | ||
650 | }, | ||
651 | }, | ||
652 | { /* sentinel */ } | ||
653 | }; | ||
654 | |||
655 | static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = { | ||
656 | { | ||
657 | .reg = 0xe450, | ||
658 | .num_ports = 2, | ||
659 | .clkout_ctl = { 0xe450, 4, 4, 1, 0 }, | ||
660 | .port_cfgs = { | ||
661 | [USB2PHY_PORT_HOST] = { | ||
662 | .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 }, | ||
663 | .ls_det_en = { 0xe3c0, 6, 6, 0, 1 }, | ||
664 | .ls_det_st = { 0xe3e0, 6, 6, 0, 1 }, | ||
665 | .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 }, | ||
666 | .utmi_ls = { 0xe2ac, 22, 21, 0, 1 }, | ||
667 | .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 } | ||
668 | } | ||
669 | }, | ||
670 | }, | ||
671 | { | ||
672 | .reg = 0xe460, | ||
673 | .num_ports = 2, | ||
674 | .clkout_ctl = { 0xe460, 4, 4, 1, 0 }, | ||
675 | .port_cfgs = { | ||
676 | [USB2PHY_PORT_HOST] = { | ||
677 | .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 }, | ||
678 | .ls_det_en = { 0xe3c0, 11, 11, 0, 1 }, | ||
679 | .ls_det_st = { 0xe3e0, 11, 11, 0, 1 }, | ||
680 | .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 }, | ||
681 | .utmi_ls = { 0xe2ac, 26, 25, 0, 1 }, | ||
682 | .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 } | ||
683 | } | ||
684 | }, | ||
685 | }, | ||
686 | { /* sentinel */ } | ||
687 | }; | ||
688 | |||
689 | static const struct of_device_id rockchip_usb2phy_dt_match[] = { | ||
690 | { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, | ||
691 | { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, | ||
692 | {} | ||
693 | }; | ||
694 | MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match); | ||
695 | |||
696 | static struct platform_driver rockchip_usb2phy_driver = { | ||
697 | .probe = rockchip_usb2phy_probe, | ||
698 | .driver = { | ||
699 | .name = "rockchip-usb2phy", | ||
700 | .of_match_table = rockchip_usb2phy_dt_match, | ||
701 | }, | ||
702 | }; | ||
703 | module_platform_driver(rockchip_usb2phy_driver); | ||
704 | |||
705 | MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>"); | ||
706 | MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver"); | ||
707 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-rockchip-pcie.c b/drivers/phy/phy-rockchip-pcie.c new file mode 100644 index 000000000000..a2b4c6b58aea --- /dev/null +++ b/drivers/phy/phy-rockchip-pcie.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | * Rockchip PCIe PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2016 Shawn Lin <shawn.lin@rock-chips.com> | ||
5 | * Copyright (C) 2016 ROCKCHIP, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/mfd/syscon.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/of_platform.h> | ||
25 | #include <linux/phy/phy.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/regmap.h> | ||
28 | #include <linux/reset.h> | ||
29 | |||
30 | /* | ||
31 | * The higher 16-bit of this register is used for write protection | ||
32 | * only if BIT(x + 16) set to 1 the BIT(x) can be written. | ||
33 | */ | ||
34 | #define HIWORD_UPDATE(val, mask, shift) \ | ||
35 | ((val) << (shift) | (mask) << ((shift) + 16)) | ||
36 | |||
37 | #define PHY_MAX_LANE_NUM 4 | ||
38 | #define PHY_CFG_DATA_SHIFT 7 | ||
39 | #define PHY_CFG_ADDR_SHIFT 1 | ||
40 | #define PHY_CFG_DATA_MASK 0xf | ||
41 | #define PHY_CFG_ADDR_MASK 0x3f | ||
42 | #define PHY_CFG_RD_MASK 0x3ff | ||
43 | #define PHY_CFG_WR_ENABLE 1 | ||
44 | #define PHY_CFG_WR_DISABLE 1 | ||
45 | #define PHY_CFG_WR_SHIFT 0 | ||
46 | #define PHY_CFG_WR_MASK 1 | ||
47 | #define PHY_CFG_PLL_LOCK 0x10 | ||
48 | #define PHY_CFG_CLK_TEST 0x10 | ||
49 | #define PHY_CFG_CLK_SCC 0x12 | ||
50 | #define PHY_CFG_SEPE_RATE BIT(3) | ||
51 | #define PHY_CFG_PLL_100M BIT(3) | ||
52 | #define PHY_PLL_LOCKED BIT(9) | ||
53 | #define PHY_PLL_OUTPUT BIT(10) | ||
54 | #define PHY_LANE_A_STATUS 0x30 | ||
55 | #define PHY_LANE_B_STATUS 0x31 | ||
56 | #define PHY_LANE_C_STATUS 0x32 | ||
57 | #define PHY_LANE_D_STATUS 0x33 | ||
58 | #define PHY_LANE_RX_DET_SHIFT 11 | ||
59 | #define PHY_LANE_RX_DET_TH 0x1 | ||
60 | #define PHY_LANE_IDLE_OFF 0x1 | ||
61 | #define PHY_LANE_IDLE_MASK 0x1 | ||
62 | #define PHY_LANE_IDLE_A_SHIFT 3 | ||
63 | #define PHY_LANE_IDLE_B_SHIFT 4 | ||
64 | #define PHY_LANE_IDLE_C_SHIFT 5 | ||
65 | #define PHY_LANE_IDLE_D_SHIFT 6 | ||
66 | |||
67 | struct rockchip_pcie_data { | ||
68 | unsigned int pcie_conf; | ||
69 | unsigned int pcie_status; | ||
70 | unsigned int pcie_laneoff; | ||
71 | }; | ||
72 | |||
73 | struct rockchip_pcie_phy { | ||
74 | struct rockchip_pcie_data *phy_data; | ||
75 | struct regmap *reg_base; | ||
76 | struct reset_control *phy_rst; | ||
77 | struct clk *clk_pciephy_ref; | ||
78 | }; | ||
79 | |||
80 | static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy, | ||
81 | u32 addr, u32 data) | ||
82 | { | ||
83 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
84 | HIWORD_UPDATE(data, | ||
85 | PHY_CFG_DATA_MASK, | ||
86 | PHY_CFG_DATA_SHIFT) | | ||
87 | HIWORD_UPDATE(addr, | ||
88 | PHY_CFG_ADDR_MASK, | ||
89 | PHY_CFG_ADDR_SHIFT)); | ||
90 | udelay(1); | ||
91 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
92 | HIWORD_UPDATE(PHY_CFG_WR_ENABLE, | ||
93 | PHY_CFG_WR_MASK, | ||
94 | PHY_CFG_WR_SHIFT)); | ||
95 | udelay(1); | ||
96 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
97 | HIWORD_UPDATE(PHY_CFG_WR_DISABLE, | ||
98 | PHY_CFG_WR_MASK, | ||
99 | PHY_CFG_WR_SHIFT)); | ||
100 | } | ||
101 | |||
102 | static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy, | ||
103 | u32 addr) | ||
104 | { | ||
105 | u32 val; | ||
106 | |||
107 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
108 | HIWORD_UPDATE(addr, | ||
109 | PHY_CFG_RD_MASK, | ||
110 | PHY_CFG_ADDR_SHIFT)); | ||
111 | regmap_read(rk_phy->reg_base, | ||
112 | rk_phy->phy_data->pcie_status, | ||
113 | &val); | ||
114 | return val; | ||
115 | } | ||
116 | |||
117 | static int rockchip_pcie_phy_power_off(struct phy *phy) | ||
118 | { | ||
119 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | ||
120 | int err = 0; | ||
121 | |||
122 | err = reset_control_assert(rk_phy->phy_rst); | ||
123 | if (err) { | ||
124 | dev_err(&phy->dev, "assert phy_rst err %d\n", err); | ||
125 | return err; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int rockchip_pcie_phy_power_on(struct phy *phy) | ||
132 | { | ||
133 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | ||
134 | int err = 0; | ||
135 | u32 status; | ||
136 | unsigned long timeout; | ||
137 | |||
138 | err = reset_control_deassert(rk_phy->phy_rst); | ||
139 | if (err) { | ||
140 | dev_err(&phy->dev, "deassert phy_rst err %d\n", err); | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
145 | HIWORD_UPDATE(PHY_CFG_PLL_LOCK, | ||
146 | PHY_CFG_ADDR_MASK, | ||
147 | PHY_CFG_ADDR_SHIFT)); | ||
148 | |||
149 | /* | ||
150 | * No documented timeout value for phy operation below, | ||
151 | * so we make it large enough here. And we use loop-break | ||
152 | * method which should not be harmful. | ||
153 | */ | ||
154 | timeout = jiffies + msecs_to_jiffies(1000); | ||
155 | |||
156 | err = -EINVAL; | ||
157 | while (time_before(jiffies, timeout)) { | ||
158 | regmap_read(rk_phy->reg_base, | ||
159 | rk_phy->phy_data->pcie_status, | ||
160 | &status); | ||
161 | if (status & PHY_PLL_LOCKED) { | ||
162 | dev_dbg(&phy->dev, "pll locked!\n"); | ||
163 | err = 0; | ||
164 | break; | ||
165 | } | ||
166 | msleep(20); | ||
167 | } | ||
168 | |||
169 | if (err) { | ||
170 | dev_err(&phy->dev, "pll lock timeout!\n"); | ||
171 | goto err_pll_lock; | ||
172 | } | ||
173 | |||
174 | phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE); | ||
175 | phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M); | ||
176 | |||
177 | err = -ETIMEDOUT; | ||
178 | while (time_before(jiffies, timeout)) { | ||
179 | regmap_read(rk_phy->reg_base, | ||
180 | rk_phy->phy_data->pcie_status, | ||
181 | &status); | ||
182 | if (!(status & PHY_PLL_OUTPUT)) { | ||
183 | dev_dbg(&phy->dev, "pll output enable done!\n"); | ||
184 | err = 0; | ||
185 | break; | ||
186 | } | ||
187 | msleep(20); | ||
188 | } | ||
189 | |||
190 | if (err) { | ||
191 | dev_err(&phy->dev, "pll output enable timeout!\n"); | ||
192 | goto err_pll_lock; | ||
193 | } | ||
194 | |||
195 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | ||
196 | HIWORD_UPDATE(PHY_CFG_PLL_LOCK, | ||
197 | PHY_CFG_ADDR_MASK, | ||
198 | PHY_CFG_ADDR_SHIFT)); | ||
199 | err = -EINVAL; | ||
200 | while (time_before(jiffies, timeout)) { | ||
201 | regmap_read(rk_phy->reg_base, | ||
202 | rk_phy->phy_data->pcie_status, | ||
203 | &status); | ||
204 | if (status & PHY_PLL_LOCKED) { | ||
205 | dev_dbg(&phy->dev, "pll relocked!\n"); | ||
206 | err = 0; | ||
207 | break; | ||
208 | } | ||
209 | msleep(20); | ||
210 | } | ||
211 | |||
212 | if (err) { | ||
213 | dev_err(&phy->dev, "pll relock timeout!\n"); | ||
214 | goto err_pll_lock; | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | err_pll_lock: | ||
220 | reset_control_assert(rk_phy->phy_rst); | ||
221 | return err; | ||
222 | } | ||
223 | |||
224 | static int rockchip_pcie_phy_init(struct phy *phy) | ||
225 | { | ||
226 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | ||
227 | int err = 0; | ||
228 | |||
229 | err = clk_prepare_enable(rk_phy->clk_pciephy_ref); | ||
230 | if (err) { | ||
231 | dev_err(&phy->dev, "Fail to enable pcie ref clock.\n"); | ||
232 | goto err_refclk; | ||
233 | } | ||
234 | |||
235 | err = reset_control_assert(rk_phy->phy_rst); | ||
236 | if (err) { | ||
237 | dev_err(&phy->dev, "assert phy_rst err %d\n", err); | ||
238 | goto err_reset; | ||
239 | } | ||
240 | |||
241 | return err; | ||
242 | |||
243 | err_reset: | ||
244 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); | ||
245 | err_refclk: | ||
246 | return err; | ||
247 | } | ||
248 | |||
249 | static int rockchip_pcie_phy_exit(struct phy *phy) | ||
250 | { | ||
251 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | ||
252 | int err = 0; | ||
253 | |||
254 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); | ||
255 | |||
256 | err = reset_control_deassert(rk_phy->phy_rst); | ||
257 | if (err) { | ||
258 | dev_err(&phy->dev, "deassert phy_rst err %d\n", err); | ||
259 | goto err_reset; | ||
260 | } | ||
261 | |||
262 | return err; | ||
263 | |||
264 | err_reset: | ||
265 | clk_prepare_enable(rk_phy->clk_pciephy_ref); | ||
266 | return err; | ||
267 | } | ||
268 | |||
269 | static const struct phy_ops ops = { | ||
270 | .init = rockchip_pcie_phy_init, | ||
271 | .exit = rockchip_pcie_phy_exit, | ||
272 | .power_on = rockchip_pcie_phy_power_on, | ||
273 | .power_off = rockchip_pcie_phy_power_off, | ||
274 | .owner = THIS_MODULE, | ||
275 | }; | ||
276 | |||
277 | static const struct rockchip_pcie_data rk3399_pcie_data = { | ||
278 | .pcie_conf = 0xe220, | ||
279 | .pcie_status = 0xe2a4, | ||
280 | .pcie_laneoff = 0xe214, | ||
281 | }; | ||
282 | |||
283 | static const struct of_device_id rockchip_pcie_phy_dt_ids[] = { | ||
284 | { | ||
285 | .compatible = "rockchip,rk3399-pcie-phy", | ||
286 | .data = &rk3399_pcie_data, | ||
287 | }, | ||
288 | {} | ||
289 | }; | ||
290 | |||
291 | MODULE_DEVICE_TABLE(of, rockchip_pcie_phy_dt_ids); | ||
292 | |||
293 | static int rockchip_pcie_phy_probe(struct platform_device *pdev) | ||
294 | { | ||
295 | struct device *dev = &pdev->dev; | ||
296 | struct rockchip_pcie_phy *rk_phy; | ||
297 | struct phy *generic_phy; | ||
298 | struct phy_provider *phy_provider; | ||
299 | struct regmap *grf; | ||
300 | const struct of_device_id *of_id; | ||
301 | |||
302 | grf = syscon_node_to_regmap(dev->parent->of_node); | ||
303 | if (IS_ERR(grf)) { | ||
304 | dev_err(dev, "Cannot find GRF syscon\n"); | ||
305 | return PTR_ERR(grf); | ||
306 | } | ||
307 | |||
308 | rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL); | ||
309 | if (!rk_phy) | ||
310 | return -ENOMEM; | ||
311 | |||
312 | of_id = of_match_device(rockchip_pcie_phy_dt_ids, &pdev->dev); | ||
313 | if (!of_id) | ||
314 | return -EINVAL; | ||
315 | |||
316 | rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data; | ||
317 | rk_phy->reg_base = grf; | ||
318 | |||
319 | rk_phy->phy_rst = devm_reset_control_get(dev, "phy"); | ||
320 | if (IS_ERR(rk_phy->phy_rst)) { | ||
321 | if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER) | ||
322 | dev_err(dev, | ||
323 | "missing phy property for reset controller\n"); | ||
324 | return PTR_ERR(rk_phy->phy_rst); | ||
325 | } | ||
326 | |||
327 | rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk"); | ||
328 | if (IS_ERR(rk_phy->clk_pciephy_ref)) { | ||
329 | dev_err(dev, "refclk not found.\n"); | ||
330 | return PTR_ERR(rk_phy->clk_pciephy_ref); | ||
331 | } | ||
332 | |||
333 | generic_phy = devm_phy_create(dev, dev->of_node, &ops); | ||
334 | if (IS_ERR(generic_phy)) { | ||
335 | dev_err(dev, "failed to create PHY\n"); | ||
336 | return PTR_ERR(generic_phy); | ||
337 | } | ||
338 | |||
339 | phy_set_drvdata(generic_phy, rk_phy); | ||
340 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
341 | |||
342 | return PTR_ERR_OR_ZERO(phy_provider); | ||
343 | } | ||
344 | |||
345 | static struct platform_driver rockchip_pcie_driver = { | ||
346 | .probe = rockchip_pcie_phy_probe, | ||
347 | .driver = { | ||
348 | .name = "rockchip-pcie-phy", | ||
349 | .of_match_table = rockchip_pcie_phy_dt_ids, | ||
350 | }, | ||
351 | }; | ||
352 | |||
353 | module_platform_driver(rockchip_pcie_driver); | ||
354 | |||
355 | MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>"); | ||
356 | MODULE_DESCRIPTION("Rockchip PCIe PHY driver"); | ||
357 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-rockchip-typec.c b/drivers/phy/phy-rockchip-typec.c new file mode 100644 index 000000000000..7cfb0f8995de --- /dev/null +++ b/drivers/phy/phy-rockchip-typec.c | |||
@@ -0,0 +1,1023 @@ | |||
1 | /* | ||
2 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd | ||
3 | * Author: Chris Zhong <zyw@rock-chips.com> | ||
4 | * Kever Yang <kever.yang@rock-chips.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * The ROCKCHIP Type-C PHY has two PLL clocks. The first PLL clock | ||
16 | * is used for USB3, the second PLL clock is used for DP. This Type-C PHY has | ||
17 | * 3 working modes: USB3 only mode, DP only mode, and USB3+DP mode. | ||
18 | * At USB3 only mode, both PLL clocks need to be initialized, this allows the | ||
19 | * PHY to switch mode between USB3 and USB3+DP, without disconnecting the USB | ||
20 | * device. | ||
21 | * In The DP only mode, only the DP PLL needs to be powered on, and the 4 lanes | ||
22 | * are all used for DP. | ||
23 | * | ||
24 | * This driver gets extcon cable state and property, then decides which mode to | ||
25 | * select: | ||
26 | * | ||
27 | * 1. USB3 only mode: | ||
28 | * EXTCON_USB or EXTCON_USB_HOST state is true, and | ||
29 | * EXTCON_PROP_USB_SS property is true. | ||
30 | * EXTCON_DISP_DP state is false. | ||
31 | * | ||
32 | * 2. DP only mode: | ||
33 | * EXTCON_DISP_DP state is true, and | ||
34 | * EXTCON_PROP_USB_SS property is false. | ||
35 | * If EXTCON_USB_HOST state is true, it is DP + USB2 mode, since the USB2 phy | ||
36 | * is a separate phy, so this case is still DP only mode. | ||
37 | * | ||
38 | * 3. USB3+DP mode: | ||
39 | * EXTCON_USB_HOST and EXTCON_DISP_DP are both true, and | ||
40 | * EXTCON_PROP_USB_SS property is true. | ||
41 | * | ||
42 | * This Type-C PHY driver supports normal and flip orientation. The orientation | ||
43 | * is reported by the EXTCON_PROP_USB_TYPEC_POLARITY property: true is flip | ||
44 | * orientation, false is normal orientation. | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | #include <linux/clk.h> | ||
49 | #include <linux/clk-provider.h> | ||
50 | #include <linux/delay.h> | ||
51 | #include <linux/extcon.h> | ||
52 | #include <linux/io.h> | ||
53 | #include <linux/iopoll.h> | ||
54 | #include <linux/kernel.h> | ||
55 | #include <linux/module.h> | ||
56 | #include <linux/mutex.h> | ||
57 | #include <linux/of.h> | ||
58 | #include <linux/of_address.h> | ||
59 | #include <linux/of_platform.h> | ||
60 | #include <linux/platform_device.h> | ||
61 | #include <linux/regmap.h> | ||
62 | #include <linux/reset.h> | ||
63 | |||
64 | #include <linux/mfd/syscon.h> | ||
65 | #include <linux/phy/phy.h> | ||
66 | |||
67 | #define CMN_SSM_BANDGAP (0x21 << 2) | ||
68 | #define CMN_SSM_BIAS (0x22 << 2) | ||
69 | #define CMN_PLLSM0_PLLEN (0x29 << 2) | ||
70 | #define CMN_PLLSM0_PLLPRE (0x2a << 2) | ||
71 | #define CMN_PLLSM0_PLLVREF (0x2b << 2) | ||
72 | #define CMN_PLLSM0_PLLLOCK (0x2c << 2) | ||
73 | #define CMN_PLLSM1_PLLEN (0x31 << 2) | ||
74 | #define CMN_PLLSM1_PLLPRE (0x32 << 2) | ||
75 | #define CMN_PLLSM1_PLLVREF (0x33 << 2) | ||
76 | #define CMN_PLLSM1_PLLLOCK (0x34 << 2) | ||
77 | #define CMN_PLLSM1_USER_DEF_CTRL (0x37 << 2) | ||
78 | #define CMN_ICAL_OVRD (0xc1 << 2) | ||
79 | #define CMN_PLL0_VCOCAL_OVRD (0x83 << 2) | ||
80 | #define CMN_PLL0_VCOCAL_INIT (0x84 << 2) | ||
81 | #define CMN_PLL0_VCOCAL_ITER (0x85 << 2) | ||
82 | #define CMN_PLL0_LOCK_REFCNT_START (0x90 << 2) | ||
83 | #define CMN_PLL0_LOCK_PLLCNT_START (0x92 << 2) | ||
84 | #define CMN_PLL0_LOCK_PLLCNT_THR (0x93 << 2) | ||
85 | #define CMN_PLL0_INTDIV (0x94 << 2) | ||
86 | #define CMN_PLL0_FRACDIV (0x95 << 2) | ||
87 | #define CMN_PLL0_HIGH_THR (0x96 << 2) | ||
88 | #define CMN_PLL0_DSM_DIAG (0x97 << 2) | ||
89 | #define CMN_PLL0_SS_CTRL1 (0x98 << 2) | ||
90 | #define CMN_PLL0_SS_CTRL2 (0x99 << 2) | ||
91 | #define CMN_PLL1_VCOCAL_START (0xa1 << 2) | ||
92 | #define CMN_PLL1_VCOCAL_OVRD (0xa3 << 2) | ||
93 | #define CMN_PLL1_VCOCAL_INIT (0xa4 << 2) | ||
94 | #define CMN_PLL1_VCOCAL_ITER (0xa5 << 2) | ||
95 | #define CMN_PLL1_LOCK_REFCNT_START (0xb0 << 2) | ||
96 | #define CMN_PLL1_LOCK_PLLCNT_START (0xb2 << 2) | ||
97 | #define CMN_PLL1_LOCK_PLLCNT_THR (0xb3 << 2) | ||
98 | #define CMN_PLL1_INTDIV (0xb4 << 2) | ||
99 | #define CMN_PLL1_FRACDIV (0xb5 << 2) | ||
100 | #define CMN_PLL1_HIGH_THR (0xb6 << 2) | ||
101 | #define CMN_PLL1_DSM_DIAG (0xb7 << 2) | ||
102 | #define CMN_PLL1_SS_CTRL1 (0xb8 << 2) | ||
103 | #define CMN_PLL1_SS_CTRL2 (0xb9 << 2) | ||
104 | #define CMN_RXCAL_OVRD (0xd1 << 2) | ||
105 | #define CMN_TXPUCAL_CTRL (0xe0 << 2) | ||
106 | #define CMN_TXPUCAL_OVRD (0xe1 << 2) | ||
107 | #define CMN_TXPDCAL_OVRD (0xf1 << 2) | ||
108 | #define CMN_DIAG_PLL0_FBH_OVRD (0x1c0 << 2) | ||
109 | #define CMN_DIAG_PLL0_FBL_OVRD (0x1c1 << 2) | ||
110 | #define CMN_DIAG_PLL0_OVRD (0x1c2 << 2) | ||
111 | #define CMN_DIAG_PLL0_V2I_TUNE (0x1c5 << 2) | ||
112 | #define CMN_DIAG_PLL0_CP_TUNE (0x1c6 << 2) | ||
113 | #define CMN_DIAG_PLL0_LF_PROG (0x1c7 << 2) | ||
114 | #define CMN_DIAG_PLL1_FBH_OVRD (0x1d0 << 2) | ||
115 | #define CMN_DIAG_PLL1_FBL_OVRD (0x1d1 << 2) | ||
116 | #define CMN_DIAG_PLL1_OVRD (0x1d2 << 2) | ||
117 | #define CMN_DIAG_PLL1_V2I_TUNE (0x1d5 << 2) | ||
118 | #define CMN_DIAG_PLL1_CP_TUNE (0x1d6 << 2) | ||
119 | #define CMN_DIAG_PLL1_LF_PROG (0x1d7 << 2) | ||
120 | #define CMN_DIAG_PLL1_PTATIS_TUNE1 (0x1d8 << 2) | ||
121 | #define CMN_DIAG_PLL1_PTATIS_TUNE2 (0x1d9 << 2) | ||
122 | #define CMN_DIAG_PLL1_INCLK_CTRL (0x1da << 2) | ||
123 | #define CMN_DIAG_HSCLK_SEL (0x1e0 << 2) | ||
124 | |||
125 | #define XCVR_PSM_RCTRL(n) ((0x4001 | ((n) << 9)) << 2) | ||
126 | #define XCVR_PSM_CAL_TMR(n) ((0x4002 | ((n) << 9)) << 2) | ||
127 | #define XCVR_PSM_A0IN_TMR(n) ((0x4003 | ((n) << 9)) << 2) | ||
128 | #define TX_TXCC_CAL_SCLR_MULT(n) ((0x4047 | ((n) << 9)) << 2) | ||
129 | #define TX_TXCC_CPOST_MULT_00(n) ((0x404c | ((n) << 9)) << 2) | ||
130 | #define TX_TXCC_CPOST_MULT_01(n) ((0x404d | ((n) << 9)) << 2) | ||
131 | #define TX_TXCC_CPOST_MULT_10(n) ((0x404e | ((n) << 9)) << 2) | ||
132 | #define TX_TXCC_CPOST_MULT_11(n) ((0x404f | ((n) << 9)) << 2) | ||
133 | #define TX_TXCC_MGNFS_MULT_000(n) ((0x4050 | ((n) << 9)) << 2) | ||
134 | #define TX_TXCC_MGNFS_MULT_001(n) ((0x4051 | ((n) << 9)) << 2) | ||
135 | #define TX_TXCC_MGNFS_MULT_010(n) ((0x4052 | ((n) << 9)) << 2) | ||
136 | #define TX_TXCC_MGNFS_MULT_011(n) ((0x4053 | ((n) << 9)) << 2) | ||
137 | #define TX_TXCC_MGNFS_MULT_100(n) ((0x4054 | ((n) << 9)) << 2) | ||
138 | #define TX_TXCC_MGNFS_MULT_101(n) ((0x4055 | ((n) << 9)) << 2) | ||
139 | #define TX_TXCC_MGNFS_MULT_110(n) ((0x4056 | ((n) << 9)) << 2) | ||
140 | #define TX_TXCC_MGNFS_MULT_111(n) ((0x4057 | ((n) << 9)) << 2) | ||
141 | #define XCVR_DIAG_PLLDRC_CTRL(n) ((0x40e0 | ((n) << 9)) << 2) | ||
142 | #define XCVR_DIAG_BIDI_CTRL(n) ((0x40e8 | ((n) << 9)) << 2) | ||
143 | #define XCVR_DIAG_LANE_FCM_EN_MGN(n) ((0x40f2 | ((n) << 9)) << 2) | ||
144 | #define TX_PSC_A0(n) ((0x4100 | ((n) << 9)) << 2) | ||
145 | #define TX_PSC_A1(n) ((0x4101 | ((n) << 9)) << 2) | ||
146 | #define TX_PSC_A2(n) ((0x4102 | ((n) << 9)) << 2) | ||
147 | #define TX_PSC_A3(n) ((0x4103 | ((n) << 9)) << 2) | ||
148 | #define TX_RCVDET_CTRL(n) ((0x4120 | ((n) << 9)) << 2) | ||
149 | #define TX_RCVDET_EN_TMR(n) ((0x4122 | ((n) << 9)) << 2) | ||
150 | #define TX_RCVDET_ST_TMR(n) ((0x4123 | ((n) << 9)) << 2) | ||
151 | #define TX_DIAG_TX_DRV(n) ((0x41e1 | ((n) << 9)) << 2) | ||
152 | #define TX_DIAG_BGREF_PREDRV_DELAY (0x41e7 << 2) | ||
153 | #define TX_ANA_CTRL_REG_1 (0x5020 << 2) | ||
154 | #define TX_ANA_CTRL_REG_2 (0x5021 << 2) | ||
155 | #define TXDA_COEFF_CALC_CTRL (0x5022 << 2) | ||
156 | #define TX_DIG_CTRL_REG_2 (0x5024 << 2) | ||
157 | #define TXDA_CYA_AUXDA_CYA (0x5025 << 2) | ||
158 | #define TX_ANA_CTRL_REG_3 (0x5026 << 2) | ||
159 | #define TX_ANA_CTRL_REG_4 (0x5027 << 2) | ||
160 | #define TX_ANA_CTRL_REG_5 (0x5029 << 2) | ||
161 | |||
162 | #define RX_PSC_A0(n) ((0x8000 | ((n) << 9)) << 2) | ||
163 | #define RX_PSC_A1(n) ((0x8001 | ((n) << 9)) << 2) | ||
164 | #define RX_PSC_A2(n) ((0x8002 | ((n) << 9)) << 2) | ||
165 | #define RX_PSC_A3(n) ((0x8003 | ((n) << 9)) << 2) | ||
166 | #define RX_PSC_CAL(n) ((0x8006 | ((n) << 9)) << 2) | ||
167 | #define RX_PSC_RDY(n) ((0x8007 | ((n) << 9)) << 2) | ||
168 | #define RX_IQPI_ILL_CAL_OVRD (0x8023 << 2) | ||
169 | #define RX_EPI_ILL_CAL_OVRD (0x8033 << 2) | ||
170 | #define RX_SDCAL0_OVRD (0x8041 << 2) | ||
171 | #define RX_SDCAL1_OVRD (0x8049 << 2) | ||
172 | #define RX_SLC_INIT (0x806d << 2) | ||
173 | #define RX_SLC_RUN (0x806e << 2) | ||
174 | #define RX_CDRLF_CNFG2 (0x8081 << 2) | ||
175 | #define RX_SIGDET_HL_FILT_TMR(n) ((0x8090 | ((n) << 9)) << 2) | ||
176 | #define RX_SLC_IOP0_OVRD (0x8101 << 2) | ||
177 | #define RX_SLC_IOP1_OVRD (0x8105 << 2) | ||
178 | #define RX_SLC_QOP0_OVRD (0x8109 << 2) | ||
179 | #define RX_SLC_QOP1_OVRD (0x810d << 2) | ||
180 | #define RX_SLC_EOP0_OVRD (0x8111 << 2) | ||
181 | #define RX_SLC_EOP1_OVRD (0x8115 << 2) | ||
182 | #define RX_SLC_ION0_OVRD (0x8119 << 2) | ||
183 | #define RX_SLC_ION1_OVRD (0x811d << 2) | ||
184 | #define RX_SLC_QON0_OVRD (0x8121 << 2) | ||
185 | #define RX_SLC_QON1_OVRD (0x8125 << 2) | ||
186 | #define RX_SLC_EON0_OVRD (0x8129 << 2) | ||
187 | #define RX_SLC_EON1_OVRD (0x812d << 2) | ||
188 | #define RX_SLC_IEP0_OVRD (0x8131 << 2) | ||
189 | #define RX_SLC_IEP1_OVRD (0x8135 << 2) | ||
190 | #define RX_SLC_QEP0_OVRD (0x8139 << 2) | ||
191 | #define RX_SLC_QEP1_OVRD (0x813d << 2) | ||
192 | #define RX_SLC_EEP0_OVRD (0x8141 << 2) | ||
193 | #define RX_SLC_EEP1_OVRD (0x8145 << 2) | ||
194 | #define RX_SLC_IEN0_OVRD (0x8149 << 2) | ||
195 | #define RX_SLC_IEN1_OVRD (0x814d << 2) | ||
196 | #define RX_SLC_QEN0_OVRD (0x8151 << 2) | ||
197 | #define RX_SLC_QEN1_OVRD (0x8155 << 2) | ||
198 | #define RX_SLC_EEN0_OVRD (0x8159 << 2) | ||
199 | #define RX_SLC_EEN1_OVRD (0x815d << 2) | ||
200 | #define RX_REE_CTRL_DATA_MASK(n) ((0x81bb | ((n) << 9)) << 2) | ||
201 | #define RX_DIAG_SIGDET_TUNE(n) ((0x81dc | ((n) << 9)) << 2) | ||
202 | #define RX_DIAG_SC2C_DELAY (0x81e1 << 2) | ||
203 | |||
204 | #define PMA_LANE_CFG (0xc000 << 2) | ||
205 | #define PIPE_CMN_CTRL1 (0xc001 << 2) | ||
206 | #define PIPE_CMN_CTRL2 (0xc002 << 2) | ||
207 | #define PIPE_COM_LOCK_CFG1 (0xc003 << 2) | ||
208 | #define PIPE_COM_LOCK_CFG2 (0xc004 << 2) | ||
209 | #define PIPE_RCV_DET_INH (0xc005 << 2) | ||
210 | #define DP_MODE_CTL (0xc008 << 2) | ||
211 | #define DP_CLK_CTL (0xc009 << 2) | ||
212 | #define STS (0xc00F << 2) | ||
213 | #define PHY_ISO_CMN_CTRL (0xc010 << 2) | ||
214 | #define PHY_DP_TX_CTL (0xc408 << 2) | ||
215 | #define PMA_CMN_CTRL1 (0xc800 << 2) | ||
216 | #define PHY_PMA_ISO_CMN_CTRL (0xc810 << 2) | ||
217 | #define PHY_ISOLATION_CTRL (0xc81f << 2) | ||
218 | #define PHY_PMA_ISO_XCVR_CTRL(n) ((0xcc11 | ((n) << 6)) << 2) | ||
219 | #define PHY_PMA_ISO_LINK_MODE(n) ((0xcc12 | ((n) << 6)) << 2) | ||
220 | #define PHY_PMA_ISO_PWRST_CTRL(n) ((0xcc13 | ((n) << 6)) << 2) | ||
221 | #define PHY_PMA_ISO_TX_DATA_LO(n) ((0xcc14 | ((n) << 6)) << 2) | ||
222 | #define PHY_PMA_ISO_TX_DATA_HI(n) ((0xcc15 | ((n) << 6)) << 2) | ||
223 | #define PHY_PMA_ISO_RX_DATA_LO(n) ((0xcc16 | ((n) << 6)) << 2) | ||
224 | #define PHY_PMA_ISO_RX_DATA_HI(n) ((0xcc17 | ((n) << 6)) << 2) | ||
225 | #define TX_BIST_CTRL(n) ((0x4140 | ((n) << 9)) << 2) | ||
226 | #define TX_BIST_UDDWR(n) ((0x4141 | ((n) << 9)) << 2) | ||
227 | |||
228 | /* | ||
229 | * Selects which PLL clock will be driven on the analog high speed | ||
230 | * clock 0: PLL 0 div 1 | ||
231 | * clock 1: PLL 1 div 2 | ||
232 | */ | ||
233 | #define CLK_PLL_CONFIG 0X30 | ||
234 | #define CLK_PLL_MASK 0x33 | ||
235 | |||
236 | #define CMN_READY BIT(0) | ||
237 | |||
238 | #define DP_PLL_CLOCK_ENABLE BIT(2) | ||
239 | #define DP_PLL_ENABLE BIT(0) | ||
240 | #define DP_PLL_DATA_RATE_RBR ((2 << 12) | (4 << 8)) | ||
241 | #define DP_PLL_DATA_RATE_HBR ((2 << 12) | (4 << 8)) | ||
242 | #define DP_PLL_DATA_RATE_HBR2 ((1 << 12) | (2 << 8)) | ||
243 | |||
244 | #define DP_MODE_A0 BIT(4) | ||
245 | #define DP_MODE_A2 BIT(6) | ||
246 | #define DP_MODE_ENTER_A0 0xc101 | ||
247 | #define DP_MODE_ENTER_A2 0xc104 | ||
248 | |||
249 | #define PHY_MODE_SET_TIMEOUT 100000 | ||
250 | |||
251 | #define PIN_ASSIGN_C_E 0x51d9 | ||
252 | #define PIN_ASSIGN_D_F 0x5100 | ||
253 | |||
254 | #define MODE_DISCONNECT 0 | ||
255 | #define MODE_UFP_USB BIT(0) | ||
256 | #define MODE_DFP_USB BIT(1) | ||
257 | #define MODE_DFP_DP BIT(2) | ||
258 | |||
259 | struct usb3phy_reg { | ||
260 | u32 offset; | ||
261 | u32 enable_bit; | ||
262 | u32 write_enable; | ||
263 | }; | ||
264 | |||
265 | struct rockchip_usb3phy_port_cfg { | ||
266 | struct usb3phy_reg typec_conn_dir; | ||
267 | struct usb3phy_reg usb3tousb2_en; | ||
268 | struct usb3phy_reg external_psm; | ||
269 | struct usb3phy_reg pipe_status; | ||
270 | }; | ||
271 | |||
272 | struct rockchip_typec_phy { | ||
273 | struct device *dev; | ||
274 | void __iomem *base; | ||
275 | struct extcon_dev *extcon; | ||
276 | struct regmap *grf_regs; | ||
277 | struct clk *clk_core; | ||
278 | struct clk *clk_ref; | ||
279 | struct reset_control *uphy_rst; | ||
280 | struct reset_control *pipe_rst; | ||
281 | struct reset_control *tcphy_rst; | ||
282 | struct rockchip_usb3phy_port_cfg port_cfgs; | ||
283 | /* mutex to protect access to individual PHYs */ | ||
284 | struct mutex lock; | ||
285 | |||
286 | bool flip; | ||
287 | u8 mode; | ||
288 | }; | ||
289 | |||
290 | struct phy_reg { | ||
291 | u16 value; | ||
292 | u32 addr; | ||
293 | }; | ||
294 | |||
295 | struct phy_reg usb3_pll_cfg[] = { | ||
296 | { 0xf0, CMN_PLL0_VCOCAL_INIT }, | ||
297 | { 0x18, CMN_PLL0_VCOCAL_ITER }, | ||
298 | { 0xd0, CMN_PLL0_INTDIV }, | ||
299 | { 0x4a4a, CMN_PLL0_FRACDIV }, | ||
300 | { 0x34, CMN_PLL0_HIGH_THR }, | ||
301 | { 0x1ee, CMN_PLL0_SS_CTRL1 }, | ||
302 | { 0x7f03, CMN_PLL0_SS_CTRL2 }, | ||
303 | { 0x20, CMN_PLL0_DSM_DIAG }, | ||
304 | { 0, CMN_DIAG_PLL0_OVRD }, | ||
305 | { 0, CMN_DIAG_PLL0_FBH_OVRD }, | ||
306 | { 0, CMN_DIAG_PLL0_FBL_OVRD }, | ||
307 | { 0x7, CMN_DIAG_PLL0_V2I_TUNE }, | ||
308 | { 0x45, CMN_DIAG_PLL0_CP_TUNE }, | ||
309 | { 0x8, CMN_DIAG_PLL0_LF_PROG }, | ||
310 | }; | ||
311 | |||
312 | struct phy_reg dp_pll_cfg[] = { | ||
313 | { 0xf0, CMN_PLL1_VCOCAL_INIT }, | ||
314 | { 0x18, CMN_PLL1_VCOCAL_ITER }, | ||
315 | { 0x30b9, CMN_PLL1_VCOCAL_START }, | ||
316 | { 0x21c, CMN_PLL1_INTDIV }, | ||
317 | { 0, CMN_PLL1_FRACDIV }, | ||
318 | { 0x5, CMN_PLL1_HIGH_THR }, | ||
319 | { 0x35, CMN_PLL1_SS_CTRL1 }, | ||
320 | { 0x7f1e, CMN_PLL1_SS_CTRL2 }, | ||
321 | { 0x20, CMN_PLL1_DSM_DIAG }, | ||
322 | { 0, CMN_PLLSM1_USER_DEF_CTRL }, | ||
323 | { 0, CMN_DIAG_PLL1_OVRD }, | ||
324 | { 0, CMN_DIAG_PLL1_FBH_OVRD }, | ||
325 | { 0, CMN_DIAG_PLL1_FBL_OVRD }, | ||
326 | { 0x6, CMN_DIAG_PLL1_V2I_TUNE }, | ||
327 | { 0x45, CMN_DIAG_PLL1_CP_TUNE }, | ||
328 | { 0x8, CMN_DIAG_PLL1_LF_PROG }, | ||
329 | { 0x100, CMN_DIAG_PLL1_PTATIS_TUNE1 }, | ||
330 | { 0x7, CMN_DIAG_PLL1_PTATIS_TUNE2 }, | ||
331 | { 0x4, CMN_DIAG_PLL1_INCLK_CTRL }, | ||
332 | }; | ||
333 | |||
334 | static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy) | ||
335 | { | ||
336 | u32 i, rdata; | ||
337 | |||
338 | /* | ||
339 | * cmn_ref_clk_sel = 3, select the 24Mhz for clk parent | ||
340 | * cmn_psm_clk_dig_div = 2, set the clk division to 2 | ||
341 | */ | ||
342 | writel(0x830, tcphy->base + PMA_CMN_CTRL1); | ||
343 | for (i = 0; i < 4; i++) { | ||
344 | /* | ||
345 | * The following PHY configuration assumes a 24 MHz reference | ||
346 | * clock. | ||
347 | */ | ||
348 | writel(0x90, tcphy->base + XCVR_DIAG_LANE_FCM_EN_MGN(i)); | ||
349 | writel(0x960, tcphy->base + TX_RCVDET_EN_TMR(i)); | ||
350 | writel(0x30, tcphy->base + TX_RCVDET_ST_TMR(i)); | ||
351 | } | ||
352 | |||
353 | rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL); | ||
354 | rdata &= ~CLK_PLL_MASK; | ||
355 | rdata |= CLK_PLL_CONFIG; | ||
356 | writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL); | ||
357 | } | ||
358 | |||
359 | static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy) | ||
360 | { | ||
361 | u32 i; | ||
362 | |||
363 | /* load the configuration of PLL0 */ | ||
364 | for (i = 0; i < ARRAY_SIZE(usb3_pll_cfg); i++) | ||
365 | writel(usb3_pll_cfg[i].value, | ||
366 | tcphy->base + usb3_pll_cfg[i].addr); | ||
367 | } | ||
368 | |||
369 | static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy) | ||
370 | { | ||
371 | u32 i; | ||
372 | |||
373 | /* set the default mode to RBR */ | ||
374 | writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR, | ||
375 | tcphy->base + DP_CLK_CTL); | ||
376 | |||
377 | /* load the configuration of PLL1 */ | ||
378 | for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++) | ||
379 | writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr); | ||
380 | } | ||
381 | |||
382 | static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) | ||
383 | { | ||
384 | writel(0x7799, tcphy->base + TX_PSC_A0(lane)); | ||
385 | writel(0x7798, tcphy->base + TX_PSC_A1(lane)); | ||
386 | writel(0x5098, tcphy->base + TX_PSC_A2(lane)); | ||
387 | writel(0x5098, tcphy->base + TX_PSC_A3(lane)); | ||
388 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); | ||
389 | writel(0xbf, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); | ||
390 | } | ||
391 | |||
392 | static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) | ||
393 | { | ||
394 | writel(0xa6fd, tcphy->base + RX_PSC_A0(lane)); | ||
395 | writel(0xa6fd, tcphy->base + RX_PSC_A1(lane)); | ||
396 | writel(0xa410, tcphy->base + RX_PSC_A2(lane)); | ||
397 | writel(0x2410, tcphy->base + RX_PSC_A3(lane)); | ||
398 | writel(0x23ff, tcphy->base + RX_PSC_CAL(lane)); | ||
399 | writel(0x13, tcphy->base + RX_SIGDET_HL_FILT_TMR(lane)); | ||
400 | writel(0x03e7, tcphy->base + RX_REE_CTRL_DATA_MASK(lane)); | ||
401 | writel(0x1004, tcphy->base + RX_DIAG_SIGDET_TUNE(lane)); | ||
402 | writel(0x2010, tcphy->base + RX_PSC_RDY(lane)); | ||
403 | writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); | ||
404 | } | ||
405 | |||
406 | static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) | ||
407 | { | ||
408 | u16 rdata; | ||
409 | |||
410 | writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane)); | ||
411 | writel(0x6799, tcphy->base + TX_PSC_A0(lane)); | ||
412 | writel(0x6798, tcphy->base + TX_PSC_A1(lane)); | ||
413 | writel(0x98, tcphy->base + TX_PSC_A2(lane)); | ||
414 | writel(0x98, tcphy->base + TX_PSC_A3(lane)); | ||
415 | |||
416 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); | ||
417 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane)); | ||
418 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane)); | ||
419 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane)); | ||
420 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane)); | ||
421 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane)); | ||
422 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane)); | ||
423 | writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane)); | ||
424 | writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane)); | ||
425 | writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane)); | ||
426 | writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane)); | ||
427 | writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane)); | ||
428 | |||
429 | writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); | ||
430 | writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane)); | ||
431 | |||
432 | rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); | ||
433 | rdata = (rdata & 0x8fff) | 0x6000; | ||
434 | writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); | ||
435 | } | ||
436 | |||
437 | static inline int property_enable(struct rockchip_typec_phy *tcphy, | ||
438 | const struct usb3phy_reg *reg, bool en) | ||
439 | { | ||
440 | u32 mask = 1 << reg->write_enable; | ||
441 | u32 val = en << reg->enable_bit; | ||
442 | |||
443 | return regmap_write(tcphy->grf_regs, reg->offset, val | mask); | ||
444 | } | ||
445 | |||
446 | static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) | ||
447 | { | ||
448 | u16 rdata, rdata2, val; | ||
449 | |||
450 | /* disable txda_cal_latch_en for rewrite the calibration values */ | ||
451 | rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); | ||
452 | val = rdata & 0xdfff; | ||
453 | writel(val, tcphy->base + TX_ANA_CTRL_REG_1); | ||
454 | |||
455 | /* | ||
456 | * read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and | ||
457 | * write it to TX_DIG_CTRL_REG_2[6:0], and delay 1ms to make sure it | ||
458 | * works. | ||
459 | */ | ||
460 | rdata = readl(tcphy->base + TX_DIG_CTRL_REG_2); | ||
461 | rdata = rdata & 0xffc0; | ||
462 | |||
463 | rdata2 = readl(tcphy->base + CMN_TXPUCAL_CTRL); | ||
464 | rdata2 = rdata2 & 0x3f; | ||
465 | |||
466 | val = rdata | rdata2; | ||
467 | writel(val, tcphy->base + TX_DIG_CTRL_REG_2); | ||
468 | usleep_range(1000, 1050); | ||
469 | |||
470 | /* | ||
471 | * Enable signal for latch that sample and holds calibration values. | ||
472 | * Activate this signal for 1 clock cycle to sample new calibration | ||
473 | * values. | ||
474 | */ | ||
475 | rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); | ||
476 | val = rdata | 0x2000; | ||
477 | writel(val, tcphy->base + TX_ANA_CTRL_REG_1); | ||
478 | usleep_range(150, 200); | ||
479 | |||
480 | /* set TX Voltage Level and TX Deemphasis to 0 */ | ||
481 | writel(0, tcphy->base + PHY_DP_TX_CTL); | ||
482 | /* re-enable decap */ | ||
483 | writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2); | ||
484 | writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2); | ||
485 | writel(0x2008, tcphy->base + TX_ANA_CTRL_REG_1); | ||
486 | writel(0x2018, tcphy->base + TX_ANA_CTRL_REG_1); | ||
487 | |||
488 | writel(0, tcphy->base + TX_ANA_CTRL_REG_5); | ||
489 | |||
490 | /* | ||
491 | * Programs txda_drv_ldo_prog[15:0], Sets driver LDO | ||
492 | * voltage 16'h1001 for DP-AUX-TX and RX | ||
493 | */ | ||
494 | writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4); | ||
495 | |||
496 | /* re-enables Bandgap reference for LDO */ | ||
497 | writel(0x2098, tcphy->base + TX_ANA_CTRL_REG_1); | ||
498 | writel(0x2198, tcphy->base + TX_ANA_CTRL_REG_1); | ||
499 | |||
500 | /* | ||
501 | * re-enables the transmitter pre-driver, driver data selection MUX, | ||
502 | * and receiver detect circuits. | ||
503 | */ | ||
504 | writel(0x301, tcphy->base + TX_ANA_CTRL_REG_2); | ||
505 | writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2); | ||
506 | |||
507 | /* | ||
508 | * BIT 12: Controls auxda_polarity, which selects the polarity of the | ||
509 | * xcvr: | ||
510 | * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull | ||
511 | * down aux_m) | ||
512 | * 0, Normal polarity (if TYPE_C, pulls up aux_m and pulls down | ||
513 | * aux_p) | ||
514 | */ | ||
515 | val = 0xa078; | ||
516 | if (!tcphy->flip) | ||
517 | val |= BIT(12); | ||
518 | writel(val, tcphy->base + TX_ANA_CTRL_REG_1); | ||
519 | |||
520 | writel(0, tcphy->base + TX_ANA_CTRL_REG_3); | ||
521 | writel(0, tcphy->base + TX_ANA_CTRL_REG_4); | ||
522 | writel(0, tcphy->base + TX_ANA_CTRL_REG_5); | ||
523 | |||
524 | /* | ||
525 | * Controls low_power_swing_en, set the voltage swing of the driver | ||
526 | * to 400mv. The values below are peak to peak (differential) values. | ||
527 | */ | ||
528 | writel(4, tcphy->base + TXDA_COEFF_CALC_CTRL); | ||
529 | writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA); | ||
530 | |||
531 | /* Controls tx_high_z_tm_en */ | ||
532 | val = readl(tcphy->base + TX_DIG_CTRL_REG_2); | ||
533 | val |= BIT(15); | ||
534 | writel(val, tcphy->base + TX_DIG_CTRL_REG_2); | ||
535 | } | ||
536 | |||
537 | static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode) | ||
538 | { | ||
539 | struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; | ||
540 | int ret, i; | ||
541 | u32 val; | ||
542 | |||
543 | ret = clk_prepare_enable(tcphy->clk_core); | ||
544 | if (ret) { | ||
545 | dev_err(tcphy->dev, "Failed to prepare_enable core clock\n"); | ||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | ret = clk_prepare_enable(tcphy->clk_ref); | ||
550 | if (ret) { | ||
551 | dev_err(tcphy->dev, "Failed to prepare_enable ref clock\n"); | ||
552 | goto err_clk_core; | ||
553 | } | ||
554 | |||
555 | reset_control_deassert(tcphy->tcphy_rst); | ||
556 | |||
557 | property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip); | ||
558 | |||
559 | tcphy_cfg_24m(tcphy); | ||
560 | |||
561 | if (mode == MODE_DFP_DP) { | ||
562 | tcphy_cfg_dp_pll(tcphy); | ||
563 | for (i = 0; i < 4; i++) | ||
564 | tcphy_dp_cfg_lane(tcphy, i); | ||
565 | |||
566 | writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG); | ||
567 | } else { | ||
568 | tcphy_cfg_usb3_pll(tcphy); | ||
569 | tcphy_cfg_dp_pll(tcphy); | ||
570 | if (tcphy->flip) { | ||
571 | tcphy_tx_usb3_cfg_lane(tcphy, 3); | ||
572 | tcphy_rx_usb3_cfg_lane(tcphy, 2); | ||
573 | tcphy_dp_cfg_lane(tcphy, 0); | ||
574 | tcphy_dp_cfg_lane(tcphy, 1); | ||
575 | } else { | ||
576 | tcphy_tx_usb3_cfg_lane(tcphy, 0); | ||
577 | tcphy_rx_usb3_cfg_lane(tcphy, 1); | ||
578 | tcphy_dp_cfg_lane(tcphy, 2); | ||
579 | tcphy_dp_cfg_lane(tcphy, 3); | ||
580 | } | ||
581 | |||
582 | writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG); | ||
583 | } | ||
584 | |||
585 | writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); | ||
586 | |||
587 | reset_control_deassert(tcphy->uphy_rst); | ||
588 | |||
589 | ret = readx_poll_timeout(readl, tcphy->base + PMA_CMN_CTRL1, | ||
590 | val, val & CMN_READY, 10, | ||
591 | PHY_MODE_SET_TIMEOUT); | ||
592 | if (ret < 0) { | ||
593 | dev_err(tcphy->dev, "wait pma ready timeout\n"); | ||
594 | ret = -ETIMEDOUT; | ||
595 | goto err_wait_pma; | ||
596 | } | ||
597 | |||
598 | reset_control_deassert(tcphy->pipe_rst); | ||
599 | |||
600 | return 0; | ||
601 | |||
602 | err_wait_pma: | ||
603 | reset_control_assert(tcphy->uphy_rst); | ||
604 | reset_control_assert(tcphy->tcphy_rst); | ||
605 | clk_disable_unprepare(tcphy->clk_ref); | ||
606 | err_clk_core: | ||
607 | clk_disable_unprepare(tcphy->clk_core); | ||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | static void tcphy_phy_deinit(struct rockchip_typec_phy *tcphy) | ||
612 | { | ||
613 | reset_control_assert(tcphy->tcphy_rst); | ||
614 | reset_control_assert(tcphy->uphy_rst); | ||
615 | reset_control_assert(tcphy->pipe_rst); | ||
616 | clk_disable_unprepare(tcphy->clk_core); | ||
617 | clk_disable_unprepare(tcphy->clk_ref); | ||
618 | } | ||
619 | |||
620 | static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) | ||
621 | { | ||
622 | struct extcon_dev *edev = tcphy->extcon; | ||
623 | union extcon_property_value property; | ||
624 | unsigned int id; | ||
625 | bool dfp, ufp, dp; | ||
626 | u8 mode; | ||
627 | int ret; | ||
628 | |||
629 | ufp = extcon_get_state(edev, EXTCON_USB); | ||
630 | dfp = extcon_get_state(edev, EXTCON_USB_HOST); | ||
631 | dp = extcon_get_state(edev, EXTCON_DISP_DP); | ||
632 | |||
633 | mode = MODE_DFP_USB; | ||
634 | id = EXTCON_USB_HOST; | ||
635 | |||
636 | if (ufp) { | ||
637 | mode = MODE_UFP_USB; | ||
638 | id = EXTCON_USB; | ||
639 | } else if (dp) { | ||
640 | mode = MODE_DFP_DP; | ||
641 | id = EXTCON_DISP_DP; | ||
642 | |||
643 | ret = extcon_get_property(edev, id, EXTCON_PROP_USB_SS, | ||
644 | &property); | ||
645 | if (ret) { | ||
646 | dev_err(tcphy->dev, "get superspeed property failed\n"); | ||
647 | return ret; | ||
648 | } | ||
649 | |||
650 | if (property.intval) | ||
651 | mode |= MODE_DFP_USB; | ||
652 | } | ||
653 | |||
654 | ret = extcon_get_property(edev, id, EXTCON_PROP_USB_TYPEC_POLARITY, | ||
655 | &property); | ||
656 | if (ret) { | ||
657 | dev_err(tcphy->dev, "get polarity property failed\n"); | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | tcphy->flip = property.intval ? 1 : 0; | ||
662 | |||
663 | return mode; | ||
664 | } | ||
665 | |||
666 | static int rockchip_usb3_phy_power_on(struct phy *phy) | ||
667 | { | ||
668 | struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); | ||
669 | struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; | ||
670 | const struct usb3phy_reg *reg = &cfg->pipe_status; | ||
671 | int timeout, new_mode, ret = 0; | ||
672 | u32 val; | ||
673 | |||
674 | mutex_lock(&tcphy->lock); | ||
675 | |||
676 | new_mode = tcphy_get_mode(tcphy); | ||
677 | if (new_mode < 0) { | ||
678 | ret = new_mode; | ||
679 | goto unlock_ret; | ||
680 | } | ||
681 | |||
682 | /* DP-only mode; fall back to USB2 */ | ||
683 | if (!(new_mode & (MODE_DFP_USB | MODE_UFP_USB))) | ||
684 | goto unlock_ret; | ||
685 | |||
686 | if (tcphy->mode == new_mode) | ||
687 | goto unlock_ret; | ||
688 | |||
689 | if (tcphy->mode == MODE_DISCONNECT) | ||
690 | tcphy_phy_init(tcphy, new_mode); | ||
691 | |||
692 | /* wait TCPHY for pipe ready */ | ||
693 | for (timeout = 0; timeout < 100; timeout++) { | ||
694 | regmap_read(tcphy->grf_regs, reg->offset, &val); | ||
695 | if (!(val & BIT(reg->enable_bit))) { | ||
696 | tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB); | ||
697 | goto unlock_ret; | ||
698 | } | ||
699 | usleep_range(10, 20); | ||
700 | } | ||
701 | |||
702 | if (tcphy->mode == MODE_DISCONNECT) | ||
703 | tcphy_phy_deinit(tcphy); | ||
704 | |||
705 | ret = -ETIMEDOUT; | ||
706 | |||
707 | unlock_ret: | ||
708 | mutex_unlock(&tcphy->lock); | ||
709 | return ret; | ||
710 | } | ||
711 | |||
712 | static int rockchip_usb3_phy_power_off(struct phy *phy) | ||
713 | { | ||
714 | struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); | ||
715 | |||
716 | mutex_lock(&tcphy->lock); | ||
717 | |||
718 | if (tcphy->mode == MODE_DISCONNECT) | ||
719 | goto unlock; | ||
720 | |||
721 | tcphy->mode &= ~(MODE_UFP_USB | MODE_DFP_USB); | ||
722 | if (tcphy->mode == MODE_DISCONNECT) | ||
723 | tcphy_phy_deinit(tcphy); | ||
724 | |||
725 | unlock: | ||
726 | mutex_unlock(&tcphy->lock); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static const struct phy_ops rockchip_usb3_phy_ops = { | ||
731 | .power_on = rockchip_usb3_phy_power_on, | ||
732 | .power_off = rockchip_usb3_phy_power_off, | ||
733 | .owner = THIS_MODULE, | ||
734 | }; | ||
735 | |||
736 | static int rockchip_dp_phy_power_on(struct phy *phy) | ||
737 | { | ||
738 | struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); | ||
739 | int new_mode, ret = 0; | ||
740 | u32 val; | ||
741 | |||
742 | mutex_lock(&tcphy->lock); | ||
743 | |||
744 | new_mode = tcphy_get_mode(tcphy); | ||
745 | if (new_mode < 0) { | ||
746 | ret = new_mode; | ||
747 | goto unlock_ret; | ||
748 | } | ||
749 | |||
750 | if (!(new_mode & MODE_DFP_DP)) { | ||
751 | ret = -ENODEV; | ||
752 | goto unlock_ret; | ||
753 | } | ||
754 | |||
755 | if (tcphy->mode == new_mode) | ||
756 | goto unlock_ret; | ||
757 | |||
758 | /* | ||
759 | * If the PHY has been power on, but the mode is not DP only mode, | ||
760 | * re-init the PHY for setting all of 4 lanes to DP. | ||
761 | */ | ||
762 | if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) { | ||
763 | tcphy_phy_deinit(tcphy); | ||
764 | tcphy_phy_init(tcphy, new_mode); | ||
765 | } else if (tcphy->mode == MODE_DISCONNECT) { | ||
766 | tcphy_phy_init(tcphy, new_mode); | ||
767 | } | ||
768 | |||
769 | ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, | ||
770 | val, val & DP_MODE_A2, 1000, | ||
771 | PHY_MODE_SET_TIMEOUT); | ||
772 | if (ret < 0) { | ||
773 | dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n"); | ||
774 | goto power_on_finish; | ||
775 | } | ||
776 | |||
777 | tcphy_dp_aux_calibration(tcphy); | ||
778 | |||
779 | writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL); | ||
780 | |||
781 | ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, | ||
782 | val, val & DP_MODE_A0, 1000, | ||
783 | PHY_MODE_SET_TIMEOUT); | ||
784 | if (ret < 0) { | ||
785 | writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); | ||
786 | dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n"); | ||
787 | goto power_on_finish; | ||
788 | } | ||
789 | |||
790 | tcphy->mode |= MODE_DFP_DP; | ||
791 | |||
792 | power_on_finish: | ||
793 | if (tcphy->mode == MODE_DISCONNECT) | ||
794 | tcphy_phy_deinit(tcphy); | ||
795 | unlock_ret: | ||
796 | mutex_unlock(&tcphy->lock); | ||
797 | return ret; | ||
798 | } | ||
799 | |||
800 | static int rockchip_dp_phy_power_off(struct phy *phy) | ||
801 | { | ||
802 | struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); | ||
803 | |||
804 | mutex_lock(&tcphy->lock); | ||
805 | |||
806 | if (tcphy->mode == MODE_DISCONNECT) | ||
807 | goto unlock; | ||
808 | |||
809 | tcphy->mode &= ~MODE_DFP_DP; | ||
810 | |||
811 | writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL); | ||
812 | |||
813 | if (tcphy->mode == MODE_DISCONNECT) | ||
814 | tcphy_phy_deinit(tcphy); | ||
815 | |||
816 | unlock: | ||
817 | mutex_unlock(&tcphy->lock); | ||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | static const struct phy_ops rockchip_dp_phy_ops = { | ||
822 | .power_on = rockchip_dp_phy_power_on, | ||
823 | .power_off = rockchip_dp_phy_power_off, | ||
824 | .owner = THIS_MODULE, | ||
825 | }; | ||
826 | |||
827 | static int tcphy_get_param(struct device *dev, | ||
828 | struct usb3phy_reg *reg, | ||
829 | const char *name) | ||
830 | { | ||
831 | u32 buffer[3]; | ||
832 | int ret; | ||
833 | |||
834 | ret = of_property_read_u32_array(dev->of_node, name, buffer, 3); | ||
835 | if (ret) { | ||
836 | dev_err(dev, "Can not parse %s\n", name); | ||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | reg->offset = buffer[0]; | ||
841 | reg->enable_bit = buffer[1]; | ||
842 | reg->write_enable = buffer[2]; | ||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy, | ||
847 | struct device *dev) | ||
848 | { | ||
849 | struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; | ||
850 | int ret; | ||
851 | |||
852 | ret = tcphy_get_param(dev, &cfg->typec_conn_dir, | ||
853 | "rockchip,typec-conn-dir"); | ||
854 | if (ret) | ||
855 | return ret; | ||
856 | |||
857 | ret = tcphy_get_param(dev, &cfg->usb3tousb2_en, | ||
858 | "rockchip,usb3tousb2-en"); | ||
859 | if (ret) | ||
860 | return ret; | ||
861 | |||
862 | ret = tcphy_get_param(dev, &cfg->external_psm, | ||
863 | "rockchip,external-psm"); | ||
864 | if (ret) | ||
865 | return ret; | ||
866 | |||
867 | ret = tcphy_get_param(dev, &cfg->pipe_status, | ||
868 | "rockchip,pipe-status"); | ||
869 | if (ret) | ||
870 | return ret; | ||
871 | |||
872 | tcphy->grf_regs = syscon_regmap_lookup_by_phandle(dev->of_node, | ||
873 | "rockchip,grf"); | ||
874 | if (IS_ERR(tcphy->grf_regs)) { | ||
875 | dev_err(dev, "could not find grf dt node\n"); | ||
876 | return PTR_ERR(tcphy->grf_regs); | ||
877 | } | ||
878 | |||
879 | tcphy->clk_core = devm_clk_get(dev, "tcpdcore"); | ||
880 | if (IS_ERR(tcphy->clk_core)) { | ||
881 | dev_err(dev, "could not get uphy core clock\n"); | ||
882 | return PTR_ERR(tcphy->clk_core); | ||
883 | } | ||
884 | |||
885 | tcphy->clk_ref = devm_clk_get(dev, "tcpdphy-ref"); | ||
886 | if (IS_ERR(tcphy->clk_ref)) { | ||
887 | dev_err(dev, "could not get uphy ref clock\n"); | ||
888 | return PTR_ERR(tcphy->clk_ref); | ||
889 | } | ||
890 | |||
891 | tcphy->uphy_rst = devm_reset_control_get(dev, "uphy"); | ||
892 | if (IS_ERR(tcphy->uphy_rst)) { | ||
893 | dev_err(dev, "no uphy_rst reset control found\n"); | ||
894 | return PTR_ERR(tcphy->uphy_rst); | ||
895 | } | ||
896 | |||
897 | tcphy->pipe_rst = devm_reset_control_get(dev, "uphy-pipe"); | ||
898 | if (IS_ERR(tcphy->pipe_rst)) { | ||
899 | dev_err(dev, "no pipe_rst reset control found\n"); | ||
900 | return PTR_ERR(tcphy->pipe_rst); | ||
901 | } | ||
902 | |||
903 | tcphy->tcphy_rst = devm_reset_control_get(dev, "uphy-tcphy"); | ||
904 | if (IS_ERR(tcphy->tcphy_rst)) { | ||
905 | dev_err(dev, "no tcphy_rst reset control found\n"); | ||
906 | return PTR_ERR(tcphy->tcphy_rst); | ||
907 | } | ||
908 | |||
909 | return 0; | ||
910 | } | ||
911 | |||
912 | static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy) | ||
913 | { | ||
914 | struct rockchip_usb3phy_port_cfg *cfg = &tcphy->port_cfgs; | ||
915 | |||
916 | reset_control_assert(tcphy->tcphy_rst); | ||
917 | reset_control_assert(tcphy->uphy_rst); | ||
918 | reset_control_assert(tcphy->pipe_rst); | ||
919 | |||
920 | /* select external psm clock */ | ||
921 | property_enable(tcphy, &cfg->external_psm, 1); | ||
922 | property_enable(tcphy, &cfg->usb3tousb2_en, 0); | ||
923 | |||
924 | tcphy->mode = MODE_DISCONNECT; | ||
925 | } | ||
926 | |||
927 | static int rockchip_typec_phy_probe(struct platform_device *pdev) | ||
928 | { | ||
929 | struct device *dev = &pdev->dev; | ||
930 | struct device_node *np = dev->of_node; | ||
931 | struct device_node *child_np; | ||
932 | struct rockchip_typec_phy *tcphy; | ||
933 | struct phy_provider *phy_provider; | ||
934 | struct resource *res; | ||
935 | int ret; | ||
936 | |||
937 | tcphy = devm_kzalloc(dev, sizeof(*tcphy), GFP_KERNEL); | ||
938 | if (!tcphy) | ||
939 | return -ENOMEM; | ||
940 | |||
941 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
942 | tcphy->base = devm_ioremap_resource(dev, res); | ||
943 | if (IS_ERR(tcphy->base)) | ||
944 | return PTR_ERR(tcphy->base); | ||
945 | |||
946 | ret = tcphy_parse_dt(tcphy, dev); | ||
947 | if (ret) | ||
948 | return ret; | ||
949 | |||
950 | tcphy->dev = dev; | ||
951 | platform_set_drvdata(pdev, tcphy); | ||
952 | mutex_init(&tcphy->lock); | ||
953 | |||
954 | typec_phy_pre_init(tcphy); | ||
955 | |||
956 | tcphy->extcon = extcon_get_edev_by_phandle(dev, 0); | ||
957 | if (IS_ERR(tcphy->extcon)) { | ||
958 | if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER) | ||
959 | dev_err(dev, "Invalid or missing extcon\n"); | ||
960 | return PTR_ERR(tcphy->extcon); | ||
961 | } | ||
962 | |||
963 | pm_runtime_enable(dev); | ||
964 | |||
965 | for_each_available_child_of_node(np, child_np) { | ||
966 | struct phy *phy; | ||
967 | |||
968 | if (!of_node_cmp(child_np->name, "dp-port")) | ||
969 | phy = devm_phy_create(dev, child_np, | ||
970 | &rockchip_dp_phy_ops); | ||
971 | else if (!of_node_cmp(child_np->name, "usb3-port")) | ||
972 | phy = devm_phy_create(dev, child_np, | ||
973 | &rockchip_usb3_phy_ops); | ||
974 | else | ||
975 | continue; | ||
976 | |||
977 | if (IS_ERR(phy)) { | ||
978 | dev_err(dev, "failed to create phy: %s\n", | ||
979 | child_np->name); | ||
980 | return PTR_ERR(phy); | ||
981 | } | ||
982 | |||
983 | phy_set_drvdata(phy, tcphy); | ||
984 | } | ||
985 | |||
986 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
987 | if (IS_ERR(phy_provider)) { | ||
988 | dev_err(dev, "Failed to register phy provider\n"); | ||
989 | return PTR_ERR(phy_provider); | ||
990 | } | ||
991 | |||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | static int rockchip_typec_phy_remove(struct platform_device *pdev) | ||
996 | { | ||
997 | pm_runtime_disable(&pdev->dev); | ||
998 | |||
999 | return 0; | ||
1000 | } | ||
1001 | |||
1002 | static const struct of_device_id rockchip_typec_phy_dt_ids[] = { | ||
1003 | { .compatible = "rockchip,rk3399-typec-phy" }, | ||
1004 | {} | ||
1005 | }; | ||
1006 | |||
1007 | MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids); | ||
1008 | |||
1009 | static struct platform_driver rockchip_typec_phy_driver = { | ||
1010 | .probe = rockchip_typec_phy_probe, | ||
1011 | .remove = rockchip_typec_phy_remove, | ||
1012 | .driver = { | ||
1013 | .name = "rockchip-typec-phy", | ||
1014 | .of_match_table = rockchip_typec_phy_dt_ids, | ||
1015 | }, | ||
1016 | }; | ||
1017 | |||
1018 | module_platform_driver(rockchip_typec_phy_driver); | ||
1019 | |||
1020 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); | ||
1021 | MODULE_AUTHOR("Kever Yang <kever.yang@rock-chips.com>"); | ||
1022 | MODULE_DESCRIPTION("Rockchip USB TYPE-C PHY driver"); | ||
1023 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index 2a7381f4fe4c..734987fa0ad7 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/reset.h> | 29 | #include <linux/reset.h> |
30 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
31 | #include <linux/mfd/syscon.h> | 31 | #include <linux/mfd/syscon.h> |
32 | #include <linux/delay.h> | ||
32 | 33 | ||
33 | static int enable_usb_uart; | 34 | static int enable_usb_uart; |
34 | 35 | ||
@@ -64,6 +65,7 @@ struct rockchip_usb_phy { | |||
64 | struct clk_hw clk480m_hw; | 65 | struct clk_hw clk480m_hw; |
65 | struct phy *phy; | 66 | struct phy *phy; |
66 | bool uart_enabled; | 67 | bool uart_enabled; |
68 | struct reset_control *reset; | ||
67 | }; | 69 | }; |
68 | 70 | ||
69 | static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, | 71 | static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, |
@@ -144,9 +146,23 @@ static int rockchip_usb_phy_power_on(struct phy *_phy) | |||
144 | return clk_prepare_enable(phy->clk480m); | 146 | return clk_prepare_enable(phy->clk480m); |
145 | } | 147 | } |
146 | 148 | ||
149 | static int rockchip_usb_phy_reset(struct phy *_phy) | ||
150 | { | ||
151 | struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); | ||
152 | |||
153 | if (phy->reset) { | ||
154 | reset_control_assert(phy->reset); | ||
155 | udelay(10); | ||
156 | reset_control_deassert(phy->reset); | ||
157 | } | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
147 | static const struct phy_ops ops = { | 162 | static const struct phy_ops ops = { |
148 | .power_on = rockchip_usb_phy_power_on, | 163 | .power_on = rockchip_usb_phy_power_on, |
149 | .power_off = rockchip_usb_phy_power_off, | 164 | .power_off = rockchip_usb_phy_power_off, |
165 | .reset = rockchip_usb_phy_reset, | ||
150 | .owner = THIS_MODULE, | 166 | .owner = THIS_MODULE, |
151 | }; | 167 | }; |
152 | 168 | ||
@@ -185,6 +201,10 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base, | |||
185 | return -EINVAL; | 201 | return -EINVAL; |
186 | } | 202 | } |
187 | 203 | ||
204 | rk_phy->reset = of_reset_control_get(child, "phy-reset"); | ||
205 | if (IS_ERR(rk_phy->reset)) | ||
206 | rk_phy->reset = NULL; | ||
207 | |||
188 | rk_phy->reg_offset = reg_offset; | 208 | rk_phy->reg_offset = reg_offset; |
189 | 209 | ||
190 | rk_phy->clk = of_clk_get_by_name(child, "phyclk"); | 210 | rk_phy->clk = of_clk_get_by_name(child, "phyclk"); |
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index 8c7eb335622e..b9342a2af7b3 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/power_supply.h> | 40 | #include <linux/power_supply.h> |
41 | #include <linux/regulator/consumer.h> | 41 | #include <linux/regulator/consumer.h> |
42 | #include <linux/reset.h> | 42 | #include <linux/reset.h> |
43 | #include <linux/spinlock.h> | ||
43 | #include <linux/usb/of.h> | 44 | #include <linux/usb/of.h> |
44 | #include <linux/workqueue.h> | 45 | #include <linux/workqueue.h> |
45 | 46 | ||
@@ -50,7 +51,7 @@ | |||
50 | #define REG_PHYCTL_A33 0x10 | 51 | #define REG_PHYCTL_A33 0x10 |
51 | #define REG_PHY_UNK_H3 0x20 | 52 | #define REG_PHY_UNK_H3 0x20 |
52 | 53 | ||
53 | #define REG_PMU_UNK_H3 0x10 | 54 | #define REG_PMU_UNK1 0x10 |
54 | 55 | ||
55 | #define PHYCTL_DATA BIT(7) | 56 | #define PHYCTL_DATA BIT(7) |
56 | 57 | ||
@@ -98,6 +99,7 @@ enum sun4i_usb_phy_type { | |||
98 | sun6i_a31_phy, | 99 | sun6i_a31_phy, |
99 | sun8i_a33_phy, | 100 | sun8i_a33_phy, |
100 | sun8i_h3_phy, | 101 | sun8i_h3_phy, |
102 | sun50i_a64_phy, | ||
101 | }; | 103 | }; |
102 | 104 | ||
103 | struct sun4i_usb_phy_cfg { | 105 | struct sun4i_usb_phy_cfg { |
@@ -106,13 +108,14 @@ struct sun4i_usb_phy_cfg { | |||
106 | u32 disc_thresh; | 108 | u32 disc_thresh; |
107 | u8 phyctl_offset; | 109 | u8 phyctl_offset; |
108 | bool dedicated_clocks; | 110 | bool dedicated_clocks; |
111 | bool enable_pmu_unk1; | ||
109 | }; | 112 | }; |
110 | 113 | ||
111 | struct sun4i_usb_phy_data { | 114 | struct sun4i_usb_phy_data { |
112 | void __iomem *base; | 115 | void __iomem *base; |
113 | const struct sun4i_usb_phy_cfg *cfg; | 116 | const struct sun4i_usb_phy_cfg *cfg; |
114 | enum usb_dr_mode dr_mode; | 117 | enum usb_dr_mode dr_mode; |
115 | struct mutex mutex; | 118 | spinlock_t reg_lock; /* guard access to phyctl reg */ |
116 | struct sun4i_usb_phy { | 119 | struct sun4i_usb_phy { |
117 | struct phy *phy; | 120 | struct phy *phy; |
118 | void __iomem *pmu; | 121 | void __iomem *pmu; |
@@ -122,7 +125,6 @@ struct sun4i_usb_phy_data { | |||
122 | bool regulator_on; | 125 | bool regulator_on; |
123 | int index; | 126 | int index; |
124 | } phys[MAX_PHYS]; | 127 | } phys[MAX_PHYS]; |
125 | int first_phy; | ||
126 | /* phy0 / otg related variables */ | 128 | /* phy0 / otg related variables */ |
127 | struct extcon_dev *extcon; | 129 | struct extcon_dev *extcon; |
128 | bool phy0_init; | 130 | bool phy0_init; |
@@ -131,6 +133,7 @@ struct sun4i_usb_phy_data { | |||
131 | struct power_supply *vbus_power_supply; | 133 | struct power_supply *vbus_power_supply; |
132 | struct notifier_block vbus_power_nb; | 134 | struct notifier_block vbus_power_nb; |
133 | bool vbus_power_nb_registered; | 135 | bool vbus_power_nb_registered; |
136 | bool force_session_end; | ||
134 | int id_det_irq; | 137 | int id_det_irq; |
135 | int vbus_det_irq; | 138 | int vbus_det_irq; |
136 | int id_det; | 139 | int id_det; |
@@ -179,12 +182,14 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, | |||
179 | struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); | 182 | struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); |
180 | u32 temp, usbc_bit = BIT(phy->index * 2); | 183 | u32 temp, usbc_bit = BIT(phy->index * 2); |
181 | void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; | 184 | void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; |
185 | unsigned long flags; | ||
182 | int i; | 186 | int i; |
183 | 187 | ||
184 | mutex_lock(&phy_data->mutex); | 188 | spin_lock_irqsave(&phy_data->reg_lock, flags); |
185 | 189 | ||
186 | if (phy_data->cfg->type == sun8i_a33_phy) { | 190 | if (phy_data->cfg->type == sun8i_a33_phy || |
187 | /* A33 needs us to set phyctl to 0 explicitly */ | 191 | phy_data->cfg->type == sun50i_a64_phy) { |
192 | /* A33 or A64 needs us to set phyctl to 0 explicitly */ | ||
188 | writel(0, phyctl); | 193 | writel(0, phyctl); |
189 | } | 194 | } |
190 | 195 | ||
@@ -218,7 +223,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, | |||
218 | 223 | ||
219 | data >>= 1; | 224 | data >>= 1; |
220 | } | 225 | } |
221 | mutex_unlock(&phy_data->mutex); | 226 | |
227 | spin_unlock_irqrestore(&phy_data->reg_lock, flags); | ||
222 | } | 228 | } |
223 | 229 | ||
224 | static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) | 230 | static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) |
@@ -258,14 +264,16 @@ static int sun4i_usb_phy_init(struct phy *_phy) | |||
258 | return ret; | 264 | return ret; |
259 | } | 265 | } |
260 | 266 | ||
267 | if (data->cfg->enable_pmu_unk1) { | ||
268 | val = readl(phy->pmu + REG_PMU_UNK1); | ||
269 | writel(val & ~2, phy->pmu + REG_PMU_UNK1); | ||
270 | } | ||
271 | |||
261 | if (data->cfg->type == sun8i_h3_phy) { | 272 | if (data->cfg->type == sun8i_h3_phy) { |
262 | if (phy->index == 0) { | 273 | if (phy->index == 0) { |
263 | val = readl(data->base + REG_PHY_UNK_H3); | 274 | val = readl(data->base + REG_PHY_UNK_H3); |
264 | writel(val & ~1, data->base + REG_PHY_UNK_H3); | 275 | writel(val & ~1, data->base + REG_PHY_UNK_H3); |
265 | } | 276 | } |
266 | |||
267 | val = readl(phy->pmu + REG_PMU_UNK_H3); | ||
268 | writel(val & ~2, phy->pmu + REG_PMU_UNK_H3); | ||
269 | } else { | 277 | } else { |
270 | /* Enable USB 45 Ohm resistor calibration */ | 278 | /* Enable USB 45 Ohm resistor calibration */ |
271 | if (phy->index == 0) | 279 | if (phy->index == 0) |
@@ -320,7 +328,10 @@ static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data) | |||
320 | { | 328 | { |
321 | switch (data->dr_mode) { | 329 | switch (data->dr_mode) { |
322 | case USB_DR_MODE_OTG: | 330 | case USB_DR_MODE_OTG: |
323 | return gpiod_get_value_cansleep(data->id_det_gpio); | 331 | if (data->id_det_gpio) |
332 | return gpiod_get_value_cansleep(data->id_det_gpio); | ||
333 | else | ||
334 | return 1; /* Fallback to peripheral mode */ | ||
324 | case USB_DR_MODE_HOST: | 335 | case USB_DR_MODE_HOST: |
325 | return 0; | 336 | return 0; |
326 | case USB_DR_MODE_PERIPHERAL: | 337 | case USB_DR_MODE_PERIPHERAL: |
@@ -382,8 +393,10 @@ static int sun4i_usb_phy_power_on(struct phy *_phy) | |||
382 | 393 | ||
383 | /* For phy0 only turn on Vbus if we don't have an ext. Vbus */ | 394 | /* For phy0 only turn on Vbus if we don't have an ext. Vbus */ |
384 | if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) && | 395 | if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) && |
385 | data->vbus_det) | 396 | data->vbus_det) { |
397 | dev_warn(&_phy->dev, "External vbus detected, not enabling our own vbus\n"); | ||
386 | return 0; | 398 | return 0; |
399 | } | ||
387 | 400 | ||
388 | ret = regulator_enable(phy->vbus); | 401 | ret = regulator_enable(phy->vbus); |
389 | if (ret) | 402 | if (ret) |
@@ -419,6 +432,35 @@ static int sun4i_usb_phy_power_off(struct phy *_phy) | |||
419 | return 0; | 432 | return 0; |
420 | } | 433 | } |
421 | 434 | ||
435 | static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode) | ||
436 | { | ||
437 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
438 | struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); | ||
439 | |||
440 | if (phy->index != 0) | ||
441 | return -EINVAL; | ||
442 | |||
443 | switch (mode) { | ||
444 | case PHY_MODE_USB_HOST: | ||
445 | data->dr_mode = USB_DR_MODE_HOST; | ||
446 | break; | ||
447 | case PHY_MODE_USB_DEVICE: | ||
448 | data->dr_mode = USB_DR_MODE_PERIPHERAL; | ||
449 | break; | ||
450 | case PHY_MODE_USB_OTG: | ||
451 | data->dr_mode = USB_DR_MODE_OTG; | ||
452 | break; | ||
453 | default: | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | |||
457 | dev_info(&_phy->dev, "Changing dr_mode to %d\n", (int)data->dr_mode); | ||
458 | data->force_session_end = true; | ||
459 | queue_delayed_work(system_wq, &data->detect, 0); | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
422 | void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) | 464 | void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) |
423 | { | 465 | { |
424 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | 466 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); |
@@ -432,6 +474,7 @@ static const struct phy_ops sun4i_usb_phy_ops = { | |||
432 | .exit = sun4i_usb_phy_exit, | 474 | .exit = sun4i_usb_phy_exit, |
433 | .power_on = sun4i_usb_phy_power_on, | 475 | .power_on = sun4i_usb_phy_power_on, |
434 | .power_off = sun4i_usb_phy_power_off, | 476 | .power_off = sun4i_usb_phy_power_off, |
477 | .set_mode = sun4i_usb_phy_set_mode, | ||
435 | .owner = THIS_MODULE, | 478 | .owner = THIS_MODULE, |
436 | }; | 479 | }; |
437 | 480 | ||
@@ -440,7 +483,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
440 | struct sun4i_usb_phy_data *data = | 483 | struct sun4i_usb_phy_data *data = |
441 | container_of(work, struct sun4i_usb_phy_data, detect.work); | 484 | container_of(work, struct sun4i_usb_phy_data, detect.work); |
442 | struct phy *phy0 = data->phys[0].phy; | 485 | struct phy *phy0 = data->phys[0].phy; |
443 | int id_det, vbus_det, id_notify = 0, vbus_notify = 0; | 486 | bool force_session_end, id_notify = false, vbus_notify = false; |
487 | int id_det, vbus_det; | ||
444 | 488 | ||
445 | if (phy0 == NULL) | 489 | if (phy0 == NULL) |
446 | return; | 490 | return; |
@@ -455,27 +499,30 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
455 | return; | 499 | return; |
456 | } | 500 | } |
457 | 501 | ||
502 | force_session_end = data->force_session_end; | ||
503 | data->force_session_end = false; | ||
504 | |||
458 | if (id_det != data->id_det) { | 505 | if (id_det != data->id_det) { |
459 | /* | 506 | /* id-change, force session end if we've no vbus detection */ |
460 | * When a host cable (id == 0) gets plugged in on systems | ||
461 | * without vbus detection report vbus low for long enough for | ||
462 | * the musb-ip to end the current device session. | ||
463 | */ | ||
464 | if (data->dr_mode == USB_DR_MODE_OTG && | 507 | if (data->dr_mode == USB_DR_MODE_OTG && |
465 | !sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) { | 508 | !sun4i_usb_phy0_have_vbus_det(data)) |
509 | force_session_end = true; | ||
510 | |||
511 | /* When entering host mode (id = 0) force end the session now */ | ||
512 | if (force_session_end && id_det == 0) { | ||
466 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); | 513 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); |
467 | msleep(200); | 514 | msleep(200); |
468 | sun4i_usb_phy0_set_vbus_detect(phy0, 1); | 515 | sun4i_usb_phy0_set_vbus_detect(phy0, 1); |
469 | } | 516 | } |
470 | sun4i_usb_phy0_set_id_detect(phy0, id_det); | 517 | sun4i_usb_phy0_set_id_detect(phy0, id_det); |
471 | data->id_det = id_det; | 518 | data->id_det = id_det; |
472 | id_notify = 1; | 519 | id_notify = true; |
473 | } | 520 | } |
474 | 521 | ||
475 | if (vbus_det != data->vbus_det) { | 522 | if (vbus_det != data->vbus_det) { |
476 | sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det); | 523 | sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det); |
477 | data->vbus_det = vbus_det; | 524 | data->vbus_det = vbus_det; |
478 | vbus_notify = 1; | 525 | vbus_notify = true; |
479 | } | 526 | } |
480 | 527 | ||
481 | mutex_unlock(&phy0->mutex); | 528 | mutex_unlock(&phy0->mutex); |
@@ -483,13 +530,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) | |||
483 | if (id_notify) { | 530 | if (id_notify) { |
484 | extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST, | 531 | extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST, |
485 | !id_det); | 532 | !id_det); |
486 | /* | 533 | /* When leaving host mode force end the session here */ |
487 | * When a host cable gets unplugged (id == 1) on systems | 534 | if (force_session_end && id_det == 1) { |
488 | * without vbus detection report vbus low for long enough to | ||
489 | * the musb-ip to end the current host session. | ||
490 | */ | ||
491 | if (data->dr_mode == USB_DR_MODE_OTG && | ||
492 | !sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) { | ||
493 | mutex_lock(&phy0->mutex); | 535 | mutex_lock(&phy0->mutex); |
494 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); | 536 | sun4i_usb_phy0_set_vbus_detect(phy0, 0); |
495 | msleep(1000); | 537 | msleep(1000); |
@@ -534,8 +576,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, | |||
534 | { | 576 | { |
535 | struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); | 577 | struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); |
536 | 578 | ||
537 | if (args->args[0] < data->first_phy || | 579 | if (args->args[0] >= data->cfg->num_phys) |
538 | args->args[0] >= data->cfg->num_phys) | ||
539 | return ERR_PTR(-ENODEV); | 580 | return ERR_PTR(-ENODEV); |
540 | 581 | ||
541 | return data->phys[args->args[0]].phy; | 582 | return data->phys[args->args[0]].phy; |
@@ -577,7 +618,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) | |||
577 | if (!data) | 618 | if (!data) |
578 | return -ENOMEM; | 619 | return -ENOMEM; |
579 | 620 | ||
580 | mutex_init(&data->mutex); | 621 | spin_lock_init(&data->reg_lock); |
581 | INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); | 622 | INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); |
582 | dev_set_drvdata(dev, data); | 623 | dev_set_drvdata(dev, data); |
583 | data->cfg = of_device_get_match_data(dev); | 624 | data->cfg = of_device_get_match_data(dev); |
@@ -610,33 +651,18 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) | |||
610 | } | 651 | } |
611 | 652 | ||
612 | data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0); | 653 | data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0); |
613 | switch (data->dr_mode) { | ||
614 | case USB_DR_MODE_OTG: | ||
615 | /* otg without id_det makes no sense, and is not supported */ | ||
616 | if (!data->id_det_gpio) { | ||
617 | dev_err(dev, "usb0_id_det missing or invalid\n"); | ||
618 | return -ENODEV; | ||
619 | } | ||
620 | /* fall through */ | ||
621 | case USB_DR_MODE_HOST: | ||
622 | case USB_DR_MODE_PERIPHERAL: | ||
623 | data->extcon = devm_extcon_dev_allocate(dev, | ||
624 | sun4i_usb_phy0_cable); | ||
625 | if (IS_ERR(data->extcon)) | ||
626 | return PTR_ERR(data->extcon); | ||
627 | 654 | ||
628 | ret = devm_extcon_dev_register(dev, data->extcon); | 655 | data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable); |
629 | if (ret) { | 656 | if (IS_ERR(data->extcon)) |
630 | dev_err(dev, "failed to register extcon: %d\n", ret); | 657 | return PTR_ERR(data->extcon); |
631 | return ret; | 658 | |
632 | } | 659 | ret = devm_extcon_dev_register(dev, data->extcon); |
633 | break; | 660 | if (ret) { |
634 | default: | 661 | dev_err(dev, "failed to register extcon: %d\n", ret); |
635 | dev_info(dev, "dr_mode unknown, not registering usb phy0\n"); | 662 | return ret; |
636 | data->first_phy = 1; | ||
637 | } | 663 | } |
638 | 664 | ||
639 | for (i = data->first_phy; i < data->cfg->num_phys; i++) { | 665 | for (i = 0; i < data->cfg->num_phys; i++) { |
640 | struct sun4i_usb_phy *phy = data->phys + i; | 666 | struct sun4i_usb_phy *phy = data->phys + i; |
641 | char name[16]; | 667 | char name[16]; |
642 | 668 | ||
@@ -737,6 +763,7 @@ static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { | |||
737 | .disc_thresh = 3, | 763 | .disc_thresh = 3, |
738 | .phyctl_offset = REG_PHYCTL_A10, | 764 | .phyctl_offset = REG_PHYCTL_A10, |
739 | .dedicated_clocks = false, | 765 | .dedicated_clocks = false, |
766 | .enable_pmu_unk1 = false, | ||
740 | }; | 767 | }; |
741 | 768 | ||
742 | static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { | 769 | static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { |
@@ -745,6 +772,7 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { | |||
745 | .disc_thresh = 2, | 772 | .disc_thresh = 2, |
746 | .phyctl_offset = REG_PHYCTL_A10, | 773 | .phyctl_offset = REG_PHYCTL_A10, |
747 | .dedicated_clocks = false, | 774 | .dedicated_clocks = false, |
775 | .enable_pmu_unk1 = false, | ||
748 | }; | 776 | }; |
749 | 777 | ||
750 | static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { | 778 | static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { |
@@ -753,6 +781,7 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { | |||
753 | .disc_thresh = 3, | 781 | .disc_thresh = 3, |
754 | .phyctl_offset = REG_PHYCTL_A10, | 782 | .phyctl_offset = REG_PHYCTL_A10, |
755 | .dedicated_clocks = true, | 783 | .dedicated_clocks = true, |
784 | .enable_pmu_unk1 = false, | ||
756 | }; | 785 | }; |
757 | 786 | ||
758 | static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { | 787 | static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { |
@@ -761,6 +790,7 @@ static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { | |||
761 | .disc_thresh = 2, | 790 | .disc_thresh = 2, |
762 | .phyctl_offset = REG_PHYCTL_A10, | 791 | .phyctl_offset = REG_PHYCTL_A10, |
763 | .dedicated_clocks = false, | 792 | .dedicated_clocks = false, |
793 | .enable_pmu_unk1 = false, | ||
764 | }; | 794 | }; |
765 | 795 | ||
766 | static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { | 796 | static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { |
@@ -769,6 +799,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { | |||
769 | .disc_thresh = 3, | 799 | .disc_thresh = 3, |
770 | .phyctl_offset = REG_PHYCTL_A10, | 800 | .phyctl_offset = REG_PHYCTL_A10, |
771 | .dedicated_clocks = true, | 801 | .dedicated_clocks = true, |
802 | .enable_pmu_unk1 = false, | ||
772 | }; | 803 | }; |
773 | 804 | ||
774 | static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { | 805 | static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { |
@@ -777,6 +808,7 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { | |||
777 | .disc_thresh = 3, | 808 | .disc_thresh = 3, |
778 | .phyctl_offset = REG_PHYCTL_A33, | 809 | .phyctl_offset = REG_PHYCTL_A33, |
779 | .dedicated_clocks = true, | 810 | .dedicated_clocks = true, |
811 | .enable_pmu_unk1 = false, | ||
780 | }; | 812 | }; |
781 | 813 | ||
782 | static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { | 814 | static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { |
@@ -784,6 +816,16 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { | |||
784 | .type = sun8i_h3_phy, | 816 | .type = sun8i_h3_phy, |
785 | .disc_thresh = 3, | 817 | .disc_thresh = 3, |
786 | .dedicated_clocks = true, | 818 | .dedicated_clocks = true, |
819 | .enable_pmu_unk1 = true, | ||
820 | }; | ||
821 | |||
822 | static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { | ||
823 | .num_phys = 2, | ||
824 | .type = sun50i_a64_phy, | ||
825 | .disc_thresh = 3, | ||
826 | .phyctl_offset = REG_PHYCTL_A33, | ||
827 | .dedicated_clocks = true, | ||
828 | .enable_pmu_unk1 = true, | ||
787 | }; | 829 | }; |
788 | 830 | ||
789 | static const struct of_device_id sun4i_usb_phy_of_match[] = { | 831 | static const struct of_device_id sun4i_usb_phy_of_match[] = { |
@@ -794,6 +836,8 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { | |||
794 | { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, | 836 | { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, |
795 | { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, | 837 | { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, |
796 | { .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg }, | 838 | { .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg }, |
839 | { .compatible = "allwinner,sun50i-a64-usb-phy", | ||
840 | .data = &sun50i_a64_cfg}, | ||
797 | { }, | 841 | { }, |
798 | }; | 842 | }; |
799 | MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); | 843 | MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); |
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index d9b10a39a2cf..87e6334eab93 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
@@ -172,6 +172,7 @@ struct twl4030_usb { | |||
172 | int irq; | 172 | int irq; |
173 | enum musb_vbus_id_status linkstat; | 173 | enum musb_vbus_id_status linkstat; |
174 | bool vbus_supplied; | 174 | bool vbus_supplied; |
175 | bool musb_mailbox_pending; | ||
175 | 176 | ||
176 | struct delayed_work id_workaround_work; | 177 | struct delayed_work id_workaround_work; |
177 | }; | 178 | }; |
@@ -439,6 +440,17 @@ static int __maybe_unused twl4030_usb_runtime_resume(struct device *dev) | |||
439 | (PHY_CLK_CTRL_CLOCKGATING_EN | | 440 | (PHY_CLK_CTRL_CLOCKGATING_EN | |
440 | PHY_CLK_CTRL_CLK32K_EN)); | 441 | PHY_CLK_CTRL_CLK32K_EN)); |
441 | 442 | ||
443 | twl4030_i2c_access(twl, 1); | ||
444 | twl4030_usb_set_mode(twl, twl->usb_mode); | ||
445 | if (twl->usb_mode == T2_USB_MODE_ULPI) | ||
446 | twl4030_i2c_access(twl, 0); | ||
447 | /* | ||
448 | * According to the TPS65950 TRM, there has to be at least 50ms | ||
449 | * delay between setting POWER_CTRL_OTG_ENAB and enabling charging | ||
450 | * so wait here so that a fully enabled phy can be expected after | ||
451 | * resume | ||
452 | */ | ||
453 | msleep(50); | ||
442 | return 0; | 454 | return 0; |
443 | } | 455 | } |
444 | 456 | ||
@@ -459,11 +471,6 @@ static int twl4030_phy_power_on(struct phy *phy) | |||
459 | 471 | ||
460 | dev_dbg(twl->dev, "%s\n", __func__); | 472 | dev_dbg(twl->dev, "%s\n", __func__); |
461 | pm_runtime_get_sync(twl->dev); | 473 | pm_runtime_get_sync(twl->dev); |
462 | twl4030_i2c_access(twl, 1); | ||
463 | twl4030_usb_set_mode(twl, twl->usb_mode); | ||
464 | if (twl->usb_mode == T2_USB_MODE_ULPI) | ||
465 | twl4030_i2c_access(twl, 0); | ||
466 | twl->linkstat = MUSB_UNKNOWN; | ||
467 | schedule_delayed_work(&twl->id_workaround_work, HZ); | 474 | schedule_delayed_work(&twl->id_workaround_work, HZ); |
468 | 475 | ||
469 | return 0; | 476 | return 0; |
@@ -569,9 +576,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
569 | pm_runtime_mark_last_busy(twl->dev); | 576 | pm_runtime_mark_last_busy(twl->dev); |
570 | pm_runtime_put_autosuspend(twl->dev); | 577 | pm_runtime_put_autosuspend(twl->dev); |
571 | } | 578 | } |
579 | twl->musb_mailbox_pending = true; | ||
580 | } | ||
581 | if (twl->musb_mailbox_pending) { | ||
572 | err = musb_mailbox(status); | 582 | err = musb_mailbox(status); |
573 | if (err) | 583 | if (!err) |
574 | twl->linkstat = MUSB_UNKNOWN; | 584 | twl->musb_mailbox_pending = false; |
575 | } | 585 | } |
576 | 586 | ||
577 | /* don't schedule during sleep - irq works right then */ | 587 | /* don't schedule during sleep - irq works right then */ |
@@ -676,6 +686,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
676 | twl->irq = platform_get_irq(pdev, 0); | 686 | twl->irq = platform_get_irq(pdev, 0); |
677 | twl->vbus_supplied = false; | 687 | twl->vbus_supplied = false; |
678 | twl->linkstat = MUSB_UNKNOWN; | 688 | twl->linkstat = MUSB_UNKNOWN; |
689 | twl->musb_mailbox_pending = false; | ||
679 | 690 | ||
680 | twl->phy.dev = twl->dev; | 691 | twl->phy.dev = twl->dev; |
681 | twl->phy.label = "twl4030"; | 692 | twl->phy.label = "twl4030"; |
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index ec83dfdbc206..873424ab0e32 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
20 | #include <linux/phy/phy.h> | 20 | #include <linux/phy/phy.h> |
21 | #include <linux/phy/tegra/xusb.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
23 | #include <linux/reset.h> | 24 | #include <linux/reset.h> |
@@ -101,7 +102,8 @@ tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) | |||
101 | return of_find_node_by_name(np, pad->soc->lanes[index].name); | 102 | return of_find_node_by_name(np, pad->soc->lanes[index].name); |
102 | } | 103 | } |
103 | 104 | ||
104 | int tegra_xusb_lane_lookup_function(struct tegra_xusb_lane *lane, | 105 | static int |
106 | tegra_xusb_lane_lookup_function(struct tegra_xusb_lane *lane, | ||
105 | const char *function) | 107 | const char *function) |
106 | { | 108 | { |
107 | unsigned int i; | 109 | unsigned int i; |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 8689dcba5201..644e978cbd3e 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -152,7 +152,8 @@ source "drivers/usb/gadget/Kconfig" | |||
152 | 152 | ||
153 | config USB_LED_TRIG | 153 | config USB_LED_TRIG |
154 | bool "USB LED Triggers" | 154 | bool "USB LED Triggers" |
155 | depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS | 155 | depends on LEDS_CLASS && LEDS_TRIGGERS |
156 | select USB_COMMON | ||
156 | help | 157 | help |
157 | This option adds LED triggers for USB host and/or gadget activity. | 158 | This option adds LED triggers for USB host and/or gadget activity. |
158 | 159 | ||
@@ -160,4 +161,25 @@ config USB_LED_TRIG | |||
160 | LEDs and you want to use them as activity indicators for USB host or | 161 | LEDs and you want to use them as activity indicators for USB host or |
161 | gadget. | 162 | gadget. |
162 | 163 | ||
164 | config USB_ULPI_BUS | ||
165 | tristate "USB ULPI PHY interface support" | ||
166 | select USB_COMMON | ||
167 | help | ||
168 | UTMI+ Low Pin Interface (ULPI) is specification for a commonly used | ||
169 | USB 2.0 PHY interface. The ULPI specification defines a standard set | ||
170 | of registers that can be used to detect the vendor and product which | ||
171 | allows ULPI to be handled as a bus. This module is the driver for that | ||
172 | bus. | ||
173 | |||
174 | The ULPI interfaces (the buses) are registered by the drivers for USB | ||
175 | controllers which support ULPI register access and have ULPI PHY | ||
176 | attached to them. The ULPI PHY drivers themselves are normal PHY | ||
177 | drivers. | ||
178 | |||
179 | ULPI PHYs provide often functions such as ADP sensing/probing (OTG | ||
180 | protocol) and USB charger detection. | ||
181 | |||
182 | To compile this driver as a module, choose M here: the module will | ||
183 | be called ulpi. | ||
184 | |||
163 | endif # USB_SUPPORT | 185 | endif # USB_SUPPORT |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 0a866e90b49c..f9fe86b6f7b5 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -1139,10 +1139,8 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1139 | 1139 | ||
1140 | /* instance init */ | 1140 | /* instance init */ |
1141 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); | 1141 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); |
1142 | if (!instance) { | 1142 | if (!instance) |
1143 | usb_dbg(usbatm_instance, "cxacru_bind: no memory for instance data\n"); | ||
1144 | return -ENOMEM; | 1143 | return -ENOMEM; |
1145 | } | ||
1146 | 1144 | ||
1147 | instance->usbatm = usbatm_instance; | 1145 | instance->usbatm = usbatm_instance; |
1148 | instance->modem_type = (struct cxacru_modem_type *) id->driver_info; | 1146 | instance->modem_type = (struct cxacru_modem_type *) id->driver_info; |
@@ -1168,13 +1166,11 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1168 | } | 1166 | } |
1169 | instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); | 1167 | instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); |
1170 | if (!instance->rcv_urb) { | 1168 | if (!instance->rcv_urb) { |
1171 | usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_urb\n"); | ||
1172 | ret = -ENOMEM; | 1169 | ret = -ENOMEM; |
1173 | goto fail; | 1170 | goto fail; |
1174 | } | 1171 | } |
1175 | instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); | 1172 | instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); |
1176 | if (!instance->snd_urb) { | 1173 | if (!instance->snd_urb) { |
1177 | usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_urb\n"); | ||
1178 | ret = -ENOMEM; | 1174 | ret = -ENOMEM; |
1179 | goto fail; | 1175 | goto fail; |
1180 | } | 1176 | } |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 0270d1312f83..5083eb5b0d5e 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -817,7 +817,6 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
817 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); | 817 | instance = kzalloc(sizeof(*instance), GFP_KERNEL); |
818 | 818 | ||
819 | if (!instance) { | 819 | if (!instance) { |
820 | usb_err(usbatm, "%s: no memory for instance data!\n", __func__); | ||
821 | ret = -ENOMEM; | 820 | ret = -ENOMEM; |
822 | goto fail_release; | 821 | goto fail_release; |
823 | } | 822 | } |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 4333dc576a12..df67815f74e6 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -2196,17 +2196,12 @@ static int uea_boot(struct uea_softc *sc) | |||
2196 | load_XILINX_firmware(sc); | 2196 | load_XILINX_firmware(sc); |
2197 | 2197 | ||
2198 | intr = kmalloc(size, GFP_KERNEL); | 2198 | intr = kmalloc(size, GFP_KERNEL); |
2199 | if (!intr) { | 2199 | if (!intr) |
2200 | uea_err(INS_TO_USBDEV(sc), | ||
2201 | "cannot allocate interrupt package\n"); | ||
2202 | goto err0; | 2200 | goto err0; |
2203 | } | ||
2204 | 2201 | ||
2205 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | 2202 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); |
2206 | if (!sc->urb_int) { | 2203 | if (!sc->urb_int) |
2207 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | ||
2208 | goto err1; | 2204 | goto err1; |
2209 | } | ||
2210 | 2205 | ||
2211 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | 2206 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, |
2212 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | 2207 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), |
@@ -2561,10 +2556,8 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
2561 | } | 2556 | } |
2562 | 2557 | ||
2563 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); | 2558 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); |
2564 | if (!sc) { | 2559 | if (!sc) |
2565 | uea_err(usb, "uea_init: not enough memory !\n"); | ||
2566 | return -ENOMEM; | 2560 | return -ENOMEM; |
2567 | } | ||
2568 | 2561 | ||
2569 | sc->usb_dev = usb; | 2562 | sc->usb_dev = usb; |
2570 | usbatm->driver_data = sc; | 2563 | usbatm->driver_data = sc; |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index db322d9ccb6e..4dec9df8764b 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -819,7 +819,6 @@ static int usbatm_atm_open(struct atm_vcc *vcc) | |||
819 | 819 | ||
820 | new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL); | 820 | new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL); |
821 | if (!new) { | 821 | if (!new) { |
822 | atm_err(instance, "%s: no memory for vcc_data!\n", __func__); | ||
823 | ret = -ENOMEM; | 822 | ret = -ENOMEM; |
824 | goto fail; | 823 | goto fail; |
825 | } | 824 | } |
@@ -1032,10 +1031,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
1032 | 1031 | ||
1033 | /* instance init */ | 1032 | /* instance init */ |
1034 | instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL); | 1033 | instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL); |
1035 | if (!instance) { | 1034 | if (!instance) |
1036 | dev_err(dev, "%s: no memory for instance data!\n", __func__); | ||
1037 | return -ENOMEM; | 1035 | return -ENOMEM; |
1038 | } | ||
1039 | 1036 | ||
1040 | /* public fields */ | 1037 | /* public fields */ |
1041 | 1038 | ||
@@ -1141,7 +1138,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
1141 | 1138 | ||
1142 | urb = usb_alloc_urb(iso_packets, GFP_KERNEL); | 1139 | urb = usb_alloc_urb(iso_packets, GFP_KERNEL); |
1143 | if (!urb) { | 1140 | if (!urb) { |
1144 | dev_err(dev, "%s: no memory for urb %d!\n", __func__, i); | ||
1145 | error = -ENOMEM; | 1141 | error = -ENOMEM; |
1146 | goto fail_unbind; | 1142 | goto fail_unbind; |
1147 | } | 1143 | } |
@@ -1151,7 +1147,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
1151 | /* zero the tx padding to avoid leaking information */ | 1147 | /* zero the tx padding to avoid leaking information */ |
1152 | buffer = kzalloc(channel->buf_size, GFP_KERNEL); | 1148 | buffer = kzalloc(channel->buf_size, GFP_KERNEL); |
1153 | if (!buffer) { | 1149 | if (!buffer) { |
1154 | dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i); | ||
1155 | error = -ENOMEM; | 1150 | error = -ENOMEM; |
1156 | goto fail_unbind; | 1151 | goto fail_unbind; |
1157 | } | 1152 | } |
@@ -1182,7 +1177,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
1182 | instance->cell_buf = kmalloc(instance->rx_channel.stride, GFP_KERNEL); | 1177 | instance->cell_buf = kmalloc(instance->rx_channel.stride, GFP_KERNEL); |
1183 | 1178 | ||
1184 | if (!instance->cell_buf) { | 1179 | if (!instance->cell_buf) { |
1185 | dev_err(dev, "%s: no memory for cell buffer!\n", __func__); | ||
1186 | error = -ENOMEM; | 1180 | error = -ENOMEM; |
1187 | goto fail_unbind; | 1181 | goto fail_unbind; |
1188 | } | 1182 | } |
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index dedc33e589f4..099179457f60 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c | |||
@@ -140,6 +140,9 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) | |||
140 | if (of_find_property(np, "disable-over-current", NULL)) | 140 | if (of_find_property(np, "disable-over-current", NULL)) |
141 | data->disable_oc = 1; | 141 | data->disable_oc = 1; |
142 | 142 | ||
143 | if (of_find_property(np, "over-current-active-high", NULL)) | ||
144 | data->oc_polarity = 1; | ||
145 | |||
143 | if (of_find_property(np, "external-vbus-divider", NULL)) | 146 | if (of_find_property(np, "external-vbus-divider", NULL)) |
144 | data->evdo = 1; | 147 | data->evdo = 1; |
145 | 148 | ||
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h index 635717e9354a..409aa5ca8dda 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.h +++ b/drivers/usb/chipidea/ci_hdrc_imx.h | |||
@@ -17,6 +17,7 @@ struct imx_usbmisc_data { | |||
17 | int index; | 17 | int index; |
18 | 18 | ||
19 | unsigned int disable_oc:1; /* over current detect disabled */ | 19 | unsigned int disable_oc:1; /* over current detect disabled */ |
20 | unsigned int oc_polarity:1; /* over current polarity if oc enabled */ | ||
20 | unsigned int evdo:1; /* set external vbus divider option */ | 21 | unsigned int evdo:1; /* set external vbus divider option */ |
21 | }; | 22 | }; |
22 | 23 | ||
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 053bac9d983c..96ae69502c86 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c | |||
@@ -81,12 +81,15 @@ static int ehci_ci_reset(struct usb_hcd *hcd) | |||
81 | { | 81 | { |
82 | struct device *dev = hcd->self.controller; | 82 | struct device *dev = hcd->self.controller; |
83 | struct ci_hdrc *ci = dev_get_drvdata(dev); | 83 | struct ci_hdrc *ci = dev_get_drvdata(dev); |
84 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
84 | int ret; | 85 | int ret; |
85 | 86 | ||
86 | ret = ehci_setup(hcd); | 87 | ret = ehci_setup(hcd); |
87 | if (ret) | 88 | if (ret) |
88 | return ret; | 89 | return ret; |
89 | 90 | ||
91 | ehci->need_io_watchdog = 0; | ||
92 | |||
90 | ci_platform_configure(ci); | 93 | ci_platform_configure(ci); |
91 | 94 | ||
92 | return ret; | 95 | return ret; |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index b93356834bb5..661f43fe0f9e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -59,7 +59,7 @@ ctrl_endpt_in_desc = { | |||
59 | */ | 59 | */ |
60 | static inline int hw_ep_bit(int num, int dir) | 60 | static inline int hw_ep_bit(int num, int dir) |
61 | { | 61 | { |
62 | return num + (dir ? 16 : 0); | 62 | return num + ((dir == TX) ? 16 : 0); |
63 | } | 63 | } |
64 | 64 | ||
65 | static inline int ep_to_bit(struct ci_hdrc *ci, int n) | 65 | static inline int ep_to_bit(struct ci_hdrc *ci, int n) |
@@ -121,9 +121,8 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) | |||
121 | */ | 121 | */ |
122 | static int hw_ep_disable(struct ci_hdrc *ci, int num, int dir) | 122 | static int hw_ep_disable(struct ci_hdrc *ci, int num, int dir) |
123 | { | 123 | { |
124 | hw_ep_flush(ci, num, dir); | ||
125 | hw_write(ci, OP_ENDPTCTRL + num, | 124 | hw_write(ci, OP_ENDPTCTRL + num, |
126 | dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0); | 125 | (dir == TX) ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0); |
127 | return 0; | 126 | return 0; |
128 | } | 127 | } |
129 | 128 | ||
@@ -139,7 +138,7 @@ static int hw_ep_enable(struct ci_hdrc *ci, int num, int dir, int type) | |||
139 | { | 138 | { |
140 | u32 mask, data; | 139 | u32 mask, data; |
141 | 140 | ||
142 | if (dir) { | 141 | if (dir == TX) { |
143 | mask = ENDPTCTRL_TXT; /* type */ | 142 | mask = ENDPTCTRL_TXT; /* type */ |
144 | data = type << __ffs(mask); | 143 | data = type << __ffs(mask); |
145 | 144 | ||
@@ -171,7 +170,7 @@ static int hw_ep_enable(struct ci_hdrc *ci, int num, int dir, int type) | |||
171 | */ | 170 | */ |
172 | static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir) | 171 | static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir) |
173 | { | 172 | { |
174 | u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | 173 | u32 mask = (dir == TX) ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; |
175 | 174 | ||
176 | return hw_read(ci, OP_ENDPTCTRL + num, mask) ? 1 : 0; | 175 | return hw_read(ci, OP_ENDPTCTRL + num, mask) ? 1 : 0; |
177 | } | 176 | } |
@@ -188,6 +187,9 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl) | |||
188 | { | 187 | { |
189 | int n = hw_ep_bit(num, dir); | 188 | int n = hw_ep_bit(num, dir); |
190 | 189 | ||
190 | /* Synchronize before ep prime */ | ||
191 | wmb(); | ||
192 | |||
191 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) | 193 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) |
192 | return -EAGAIN; | 194 | return -EAGAIN; |
193 | 195 | ||
@@ -218,8 +220,8 @@ static int hw_ep_set_halt(struct ci_hdrc *ci, int num, int dir, int value) | |||
218 | 220 | ||
219 | do { | 221 | do { |
220 | enum ci_hw_regs reg = OP_ENDPTCTRL + num; | 222 | enum ci_hw_regs reg = OP_ENDPTCTRL + num; |
221 | u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; | 223 | u32 mask_xs = (dir == TX) ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; |
222 | u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; | 224 | u32 mask_xr = (dir == TX) ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; |
223 | 225 | ||
224 | /* data toggle - reserved for EP0 but it's in ESS */ | 226 | /* data toggle - reserved for EP0 but it's in ESS */ |
225 | hw_write(ci, reg, mask_xs|mask_xr, | 227 | hw_write(ci, reg, mask_xs|mask_xr, |
@@ -348,8 +350,7 @@ static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, | |||
348 | if (node == NULL) | 350 | if (node == NULL) |
349 | return -ENOMEM; | 351 | return -ENOMEM; |
350 | 352 | ||
351 | node->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC, | 353 | node->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC, &node->dma); |
352 | &node->dma); | ||
353 | if (node->ptr == NULL) { | 354 | if (node->ptr == NULL) { |
354 | kfree(node); | 355 | kfree(node); |
355 | return -ENOMEM; | 356 | return -ENOMEM; |
@@ -506,8 +507,6 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) | |||
506 | hwep->qh.ptr->cap |= mul << __ffs(QH_MULT); | 507 | hwep->qh.ptr->cap |= mul << __ffs(QH_MULT); |
507 | } | 508 | } |
508 | 509 | ||
509 | wmb(); /* synchronize before ep prime */ | ||
510 | |||
511 | ret = hw_ep_prime(ci, hwep->num, hwep->dir, | 510 | ret = hw_ep_prime(ci, hwep->num, hwep->dir, |
512 | hwep->type == USB_ENDPOINT_XFER_CONTROL); | 511 | hwep->type == USB_ENDPOINT_XFER_CONTROL); |
513 | done: | 512 | done: |
@@ -534,9 +533,6 @@ static int reprime_dtd(struct ci_hdrc *ci, struct ci_hw_ep *hwep, | |||
534 | hwep->qh.ptr->td.token &= | 533 | hwep->qh.ptr->td.token &= |
535 | cpu_to_le32(~(TD_STATUS_HALTED | TD_STATUS_ACTIVE)); | 534 | cpu_to_le32(~(TD_STATUS_HALTED | TD_STATUS_ACTIVE)); |
536 | 535 | ||
537 | /* Synchronize before ep prime */ | ||
538 | wmb(); | ||
539 | |||
540 | return hw_ep_prime(ci, hwep->num, hwep->dir, | 536 | return hw_ep_prime(ci, hwep->num, hwep->dir, |
541 | hwep->type == USB_ENDPOINT_XFER_CONTROL); | 537 | hwep->type == USB_ENDPOINT_XFER_CONTROL); |
542 | } | 538 | } |
@@ -590,7 +586,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) | |||
590 | } | 586 | } |
591 | 587 | ||
592 | if (remaining_length) { | 588 | if (remaining_length) { |
593 | if (hwep->dir) { | 589 | if (hwep->dir == TX) { |
594 | hwreq->req.status = -EPROTO; | 590 | hwreq->req.status = -EPROTO; |
595 | break; | 591 | break; |
596 | } | 592 | } |
@@ -1051,9 +1047,9 @@ __acquires(ci->lock) | |||
1051 | if (req.wLength != 0) | 1047 | if (req.wLength != 0) |
1052 | break; | 1048 | break; |
1053 | num = le16_to_cpu(req.wIndex); | 1049 | num = le16_to_cpu(req.wIndex); |
1054 | dir = num & USB_ENDPOINT_DIR_MASK; | 1050 | dir = (num & USB_ENDPOINT_DIR_MASK) ? TX : RX; |
1055 | num &= USB_ENDPOINT_NUMBER_MASK; | 1051 | num &= USB_ENDPOINT_NUMBER_MASK; |
1056 | if (dir) /* TX */ | 1052 | if (dir == TX) |
1057 | num += ci->hw_ep_max / 2; | 1053 | num += ci->hw_ep_max / 2; |
1058 | if (!ci->ci_hw_ep[num].wedge) { | 1054 | if (!ci->ci_hw_ep[num].wedge) { |
1059 | spin_unlock(&ci->lock); | 1055 | spin_unlock(&ci->lock); |
@@ -1103,9 +1099,9 @@ __acquires(ci->lock) | |||
1103 | if (req.wLength != 0) | 1099 | if (req.wLength != 0) |
1104 | break; | 1100 | break; |
1105 | num = le16_to_cpu(req.wIndex); | 1101 | num = le16_to_cpu(req.wIndex); |
1106 | dir = num & USB_ENDPOINT_DIR_MASK; | 1102 | dir = (num & USB_ENDPOINT_DIR_MASK) ? TX : RX; |
1107 | num &= USB_ENDPOINT_NUMBER_MASK; | 1103 | num &= USB_ENDPOINT_NUMBER_MASK; |
1108 | if (dir) /* TX */ | 1104 | if (dir == TX) |
1109 | num += ci->hw_ep_max / 2; | 1105 | num += ci->hw_ep_max / 2; |
1110 | 1106 | ||
1111 | spin_unlock(&ci->lock); | 1107 | spin_unlock(&ci->lock); |
@@ -1680,12 +1676,10 @@ static int init_eps(struct ci_hdrc *ci) | |||
1680 | usb_ep_set_maxpacket_limit(&hwep->ep, (unsigned short)~0); | 1676 | usb_ep_set_maxpacket_limit(&hwep->ep, (unsigned short)~0); |
1681 | 1677 | ||
1682 | INIT_LIST_HEAD(&hwep->qh.queue); | 1678 | INIT_LIST_HEAD(&hwep->qh.queue); |
1683 | hwep->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, | 1679 | hwep->qh.ptr = dma_pool_zalloc(ci->qh_pool, GFP_KERNEL, |
1684 | &hwep->qh.dma); | 1680 | &hwep->qh.dma); |
1685 | if (hwep->qh.ptr == NULL) | 1681 | if (hwep->qh.ptr == NULL) |
1686 | retval = -ENOMEM; | 1682 | retval = -ENOMEM; |
1687 | else | ||
1688 | memset(hwep->qh.ptr, 0, sizeof(*hwep->qh.ptr)); | ||
1689 | 1683 | ||
1690 | /* | 1684 | /* |
1691 | * set up shorthands for ep0 out and in endpoints, | 1685 | * set up shorthands for ep0 out and in endpoints, |
@@ -1999,7 +1993,7 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci) | |||
1999 | if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) | 1993 | if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) |
2000 | return -ENXIO; | 1994 | return -ENXIO; |
2001 | 1995 | ||
2002 | rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL); | 1996 | rdrv = devm_kzalloc(ci->dev, sizeof(*rdrv), GFP_KERNEL); |
2003 | if (!rdrv) | 1997 | if (!rdrv) |
2004 | return -ENOMEM; | 1998 | return -ENOMEM; |
2005 | 1999 | ||
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index ab8b027e8cc8..20d02a5e418d 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c | |||
@@ -56,6 +56,7 @@ | |||
56 | 56 | ||
57 | #define MX6_BM_NON_BURST_SETTING BIT(1) | 57 | #define MX6_BM_NON_BURST_SETTING BIT(1) |
58 | #define MX6_BM_OVER_CUR_DIS BIT(7) | 58 | #define MX6_BM_OVER_CUR_DIS BIT(7) |
59 | #define MX6_BM_OVER_CUR_POLARITY BIT(8) | ||
59 | #define MX6_BM_WAKEUP_ENABLE BIT(10) | 60 | #define MX6_BM_WAKEUP_ENABLE BIT(10) |
60 | #define MX6_BM_ID_WAKEUP BIT(16) | 61 | #define MX6_BM_ID_WAKEUP BIT(16) |
61 | #define MX6_BM_VBUS_WAKEUP BIT(17) | 62 | #define MX6_BM_VBUS_WAKEUP BIT(17) |
@@ -266,11 +267,14 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) | |||
266 | 267 | ||
267 | spin_lock_irqsave(&usbmisc->lock, flags); | 268 | spin_lock_irqsave(&usbmisc->lock, flags); |
268 | 269 | ||
270 | reg = readl(usbmisc->base + data->index * 4); | ||
269 | if (data->disable_oc) { | 271 | if (data->disable_oc) { |
270 | reg = readl(usbmisc->base + data->index * 4); | 272 | reg |= MX6_BM_OVER_CUR_DIS; |
271 | writel(reg | MX6_BM_OVER_CUR_DIS, | 273 | } else if (data->oc_polarity == 1) { |
272 | usbmisc->base + data->index * 4); | 274 | /* High active */ |
275 | reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY); | ||
273 | } | 276 | } |
277 | writel(reg, usbmisc->base + data->index * 4); | ||
274 | 278 | ||
275 | /* SoC non-burst setting */ | 279 | /* SoC non-burst setting */ |
276 | reg = readl(usbmisc->base + data->index * 4); | 280 | reg = readl(usbmisc->base + data->index * 4); |
@@ -365,10 +369,14 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) | |||
365 | return -EINVAL; | 369 | return -EINVAL; |
366 | 370 | ||
367 | spin_lock_irqsave(&usbmisc->lock, flags); | 371 | spin_lock_irqsave(&usbmisc->lock, flags); |
372 | reg = readl(usbmisc->base); | ||
368 | if (data->disable_oc) { | 373 | if (data->disable_oc) { |
369 | reg = readl(usbmisc->base); | 374 | reg |= MX6_BM_OVER_CUR_DIS; |
370 | writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base); | 375 | } else if (data->oc_polarity == 1) { |
376 | /* High active */ | ||
377 | reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY); | ||
371 | } | 378 | } |
379 | writel(reg, usbmisc->base); | ||
372 | 380 | ||
373 | reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); | 381 | reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); |
374 | reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; | 382 | reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; |
@@ -492,6 +500,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { | |||
492 | .compatible = "fsl,imx6ul-usbmisc", | 500 | .compatible = "fsl,imx6ul-usbmisc", |
493 | .data = &imx6sx_usbmisc_ops, | 501 | .data = &imx6sx_usbmisc_ops, |
494 | }, | 502 | }, |
503 | { | ||
504 | .compatible = "fsl,imx7d-usbmisc", | ||
505 | .data = &imx7d_usbmisc_ops, | ||
506 | }, | ||
495 | { /* sentinel */ } | 507 | { /* sentinel */ } |
496 | }; | 508 | }; |
497 | MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); | 509 | MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0f3f62e81e5b..78f0f85bebdc 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -368,17 +368,17 @@ static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags) | |||
368 | if (!test_and_clear_bit(index, &acm->read_urbs_free)) | 368 | if (!test_and_clear_bit(index, &acm->read_urbs_free)) |
369 | return 0; | 369 | return 0; |
370 | 370 | ||
371 | dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index); | ||
372 | |||
373 | res = usb_submit_urb(acm->read_urbs[index], mem_flags); | 371 | res = usb_submit_urb(acm->read_urbs[index], mem_flags); |
374 | if (res) { | 372 | if (res) { |
375 | if (res != -EPERM) { | 373 | if (res != -EPERM) { |
376 | dev_err(&acm->data->dev, | 374 | dev_err(&acm->data->dev, |
377 | "%s - usb_submit_urb failed: %d\n", | 375 | "urb %d failed submission with %d\n", |
378 | __func__, res); | 376 | index, res); |
379 | } | 377 | } |
380 | set_bit(index, &acm->read_urbs_free); | 378 | set_bit(index, &acm->read_urbs_free); |
381 | return res; | 379 | return res; |
380 | } else { | ||
381 | dev_vdbg(&acm->data->dev, "submitted urb %d\n", index); | ||
382 | } | 382 | } |
383 | 383 | ||
384 | return 0; | 384 | return 0; |
@@ -415,8 +415,9 @@ static void acm_read_bulk_callback(struct urb *urb) | |||
415 | unsigned long flags; | 415 | unsigned long flags; |
416 | int status = urb->status; | 416 | int status = urb->status; |
417 | 417 | ||
418 | dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__, | 418 | dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n", |
419 | rb->index, urb->actual_length); | 419 | rb->index, urb->actual_length, |
420 | status); | ||
420 | 421 | ||
421 | if (!acm->dev) { | 422 | if (!acm->dev) { |
422 | set_bit(rb->index, &acm->read_urbs_free); | 423 | set_bit(rb->index, &acm->read_urbs_free); |
@@ -426,8 +427,6 @@ static void acm_read_bulk_callback(struct urb *urb) | |||
426 | 427 | ||
427 | if (status) { | 428 | if (status) { |
428 | set_bit(rb->index, &acm->read_urbs_free); | 429 | set_bit(rb->index, &acm->read_urbs_free); |
429 | dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", | ||
430 | __func__, status); | ||
431 | if ((status != -ENOENT) || (urb->actual_length == 0)) | 430 | if ((status != -ENOENT) || (urb->actual_length == 0)) |
432 | return; | 431 | return; |
433 | } | 432 | } |
@@ -462,8 +461,7 @@ static void acm_write_bulk(struct urb *urb) | |||
462 | int status = urb->status; | 461 | int status = urb->status; |
463 | 462 | ||
464 | if (status || (urb->actual_length != urb->transfer_buffer_length)) | 463 | if (status || (urb->actual_length != urb->transfer_buffer_length)) |
465 | dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n", | 464 | dev_vdbg(&acm->data->dev, "wrote len %d/%d, status %d\n", |
466 | __func__, | ||
467 | urb->actual_length, | 465 | urb->actual_length, |
468 | urb->transfer_buffer_length, | 466 | urb->transfer_buffer_length, |
469 | status); | 467 | status); |
@@ -478,8 +476,6 @@ static void acm_softint(struct work_struct *work) | |||
478 | { | 476 | { |
479 | struct acm *acm = container_of(work, struct acm, work); | 477 | struct acm *acm = container_of(work, struct acm, work); |
480 | 478 | ||
481 | dev_vdbg(&acm->data->dev, "%s\n", __func__); | ||
482 | |||
483 | tty_port_tty_wakeup(&acm->port); | 479 | tty_port_tty_wakeup(&acm->port); |
484 | } | 480 | } |
485 | 481 | ||
@@ -492,8 +488,6 @@ static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
492 | struct acm *acm; | 488 | struct acm *acm; |
493 | int retval; | 489 | int retval; |
494 | 490 | ||
495 | dev_dbg(tty->dev, "%s\n", __func__); | ||
496 | |||
497 | acm = acm_get_by_minor(tty->index); | 491 | acm = acm_get_by_minor(tty->index); |
498 | if (!acm) | 492 | if (!acm) |
499 | return -ENODEV; | 493 | return -ENODEV; |
@@ -515,8 +509,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
515 | { | 509 | { |
516 | struct acm *acm = tty->driver_data; | 510 | struct acm *acm = tty->driver_data; |
517 | 511 | ||
518 | dev_dbg(tty->dev, "%s\n", __func__); | ||
519 | |||
520 | return tty_port_open(&acm->port, tty, filp); | 512 | return tty_port_open(&acm->port, tty, filp); |
521 | } | 513 | } |
522 | 514 | ||
@@ -545,8 +537,6 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
545 | int retval = -ENODEV; | 537 | int retval = -ENODEV; |
546 | int i; | 538 | int i; |
547 | 539 | ||
548 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
549 | |||
550 | mutex_lock(&acm->mutex); | 540 | mutex_lock(&acm->mutex); |
551 | if (acm->disconnected) | 541 | if (acm->disconnected) |
552 | goto disconnected; | 542 | goto disconnected; |
@@ -607,8 +597,6 @@ static void acm_port_destruct(struct tty_port *port) | |||
607 | { | 597 | { |
608 | struct acm *acm = container_of(port, struct acm, port); | 598 | struct acm *acm = container_of(port, struct acm, port); |
609 | 599 | ||
610 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
611 | |||
612 | acm_release_minor(acm); | 600 | acm_release_minor(acm); |
613 | usb_put_intf(acm->control); | 601 | usb_put_intf(acm->control); |
614 | kfree(acm->country_codes); | 602 | kfree(acm->country_codes); |
@@ -622,8 +610,6 @@ static void acm_port_shutdown(struct tty_port *port) | |||
622 | struct acm_wb *wb; | 610 | struct acm_wb *wb; |
623 | int i; | 611 | int i; |
624 | 612 | ||
625 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
626 | |||
627 | /* | 613 | /* |
628 | * Need to grab write_lock to prevent race with resume, but no need to | 614 | * Need to grab write_lock to prevent race with resume, but no need to |
629 | * hold it due to the tty-port initialised flag. | 615 | * hold it due to the tty-port initialised flag. |
@@ -654,21 +640,21 @@ static void acm_port_shutdown(struct tty_port *port) | |||
654 | static void acm_tty_cleanup(struct tty_struct *tty) | 640 | static void acm_tty_cleanup(struct tty_struct *tty) |
655 | { | 641 | { |
656 | struct acm *acm = tty->driver_data; | 642 | struct acm *acm = tty->driver_data; |
657 | dev_dbg(&acm->control->dev, "%s\n", __func__); | 643 | |
658 | tty_port_put(&acm->port); | 644 | tty_port_put(&acm->port); |
659 | } | 645 | } |
660 | 646 | ||
661 | static void acm_tty_hangup(struct tty_struct *tty) | 647 | static void acm_tty_hangup(struct tty_struct *tty) |
662 | { | 648 | { |
663 | struct acm *acm = tty->driver_data; | 649 | struct acm *acm = tty->driver_data; |
664 | dev_dbg(&acm->control->dev, "%s\n", __func__); | 650 | |
665 | tty_port_hangup(&acm->port); | 651 | tty_port_hangup(&acm->port); |
666 | } | 652 | } |
667 | 653 | ||
668 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 654 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
669 | { | 655 | { |
670 | struct acm *acm = tty->driver_data; | 656 | struct acm *acm = tty->driver_data; |
671 | dev_dbg(&acm->control->dev, "%s\n", __func__); | 657 | |
672 | tty_port_close(&acm->port, tty, filp); | 658 | tty_port_close(&acm->port, tty, filp); |
673 | } | 659 | } |
674 | 660 | ||
@@ -684,7 +670,7 @@ static int acm_tty_write(struct tty_struct *tty, | |||
684 | if (!count) | 670 | if (!count) |
685 | return 0; | 671 | return 0; |
686 | 672 | ||
687 | dev_vdbg(&acm->data->dev, "%s - count %d\n", __func__, count); | 673 | dev_vdbg(&acm->data->dev, "%d bytes from tty layer\n", count); |
688 | 674 | ||
689 | spin_lock_irqsave(&acm->write_lock, flags); | 675 | spin_lock_irqsave(&acm->write_lock, flags); |
690 | wbn = acm_wb_alloc(acm); | 676 | wbn = acm_wb_alloc(acm); |
@@ -701,7 +687,7 @@ static int acm_tty_write(struct tty_struct *tty, | |||
701 | } | 687 | } |
702 | 688 | ||
703 | count = (count > acm->writesize) ? acm->writesize : count; | 689 | count = (count > acm->writesize) ? acm->writesize : count; |
704 | dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count); | 690 | dev_vdbg(&acm->data->dev, "writing %d bytes\n", count); |
705 | memcpy(wb->buf, buf, count); | 691 | memcpy(wb->buf, buf, count); |
706 | wb->len = count; | 692 | wb->len = count; |
707 | 693 | ||
@@ -1193,6 +1179,9 @@ static int acm_probe(struct usb_interface *intf, | |||
1193 | return -EINVAL; | 1179 | return -EINVAL; |
1194 | } | 1180 | } |
1195 | 1181 | ||
1182 | if (!intf->cur_altsetting) | ||
1183 | return -EINVAL; | ||
1184 | |||
1196 | if (!buflen) { | 1185 | if (!buflen) { |
1197 | if (intf->cur_altsetting->endpoint && | 1186 | if (intf->cur_altsetting->endpoint && |
1198 | intf->cur_altsetting->endpoint->extralen && | 1187 | intf->cur_altsetting->endpoint->extralen && |
@@ -1246,6 +1235,8 @@ static int acm_probe(struct usb_interface *intf, | |||
1246 | dev_dbg(&intf->dev, "no interfaces\n"); | 1235 | dev_dbg(&intf->dev, "no interfaces\n"); |
1247 | return -ENODEV; | 1236 | return -ENODEV; |
1248 | } | 1237 | } |
1238 | if (!data_interface->cur_altsetting || !control_interface->cur_altsetting) | ||
1239 | return -ENODEV; | ||
1249 | 1240 | ||
1250 | if (data_intf_num != call_intf_num) | 1241 | if (data_intf_num != call_intf_num) |
1251 | dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n"); | 1242 | dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n"); |
@@ -1533,8 +1524,6 @@ static void stop_data_traffic(struct acm *acm) | |||
1533 | { | 1524 | { |
1534 | int i; | 1525 | int i; |
1535 | 1526 | ||
1536 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
1537 | |||
1538 | usb_kill_urb(acm->ctrlurb); | 1527 | usb_kill_urb(acm->ctrlurb); |
1539 | for (i = 0; i < ACM_NW; i++) | 1528 | for (i = 0; i < ACM_NW; i++) |
1540 | usb_kill_urb(acm->wb[i].urb); | 1529 | usb_kill_urb(acm->wb[i].urb); |
@@ -1551,8 +1540,6 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1551 | struct tty_struct *tty; | 1540 | struct tty_struct *tty; |
1552 | int i; | 1541 | int i; |
1553 | 1542 | ||
1554 | dev_dbg(&intf->dev, "%s\n", __func__); | ||
1555 | |||
1556 | /* sibling interface is already cleaning up */ | 1543 | /* sibling interface is already cleaning up */ |
1557 | if (!acm) | 1544 | if (!acm) |
1558 | return; | 1545 | return; |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 337948c42110..0a6369510f2d 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -58,6 +58,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
58 | #define WDM_SUSPENDING 8 | 58 | #define WDM_SUSPENDING 8 |
59 | #define WDM_RESETTING 9 | 59 | #define WDM_RESETTING 9 |
60 | #define WDM_OVERFLOW 10 | 60 | #define WDM_OVERFLOW 10 |
61 | #define WDM_DRAIN_ON_OPEN 11 | ||
61 | 62 | ||
62 | #define WDM_MAX 16 | 63 | #define WDM_MAX 16 |
63 | 64 | ||
@@ -154,6 +155,9 @@ static void wdm_out_callback(struct urb *urb) | |||
154 | wake_up(&desc->wait); | 155 | wake_up(&desc->wait); |
155 | } | 156 | } |
156 | 157 | ||
158 | /* forward declaration */ | ||
159 | static int service_outstanding_interrupt(struct wdm_device *desc); | ||
160 | |||
157 | static void wdm_in_callback(struct urb *urb) | 161 | static void wdm_in_callback(struct urb *urb) |
158 | { | 162 | { |
159 | struct wdm_device *desc = urb->context; | 163 | struct wdm_device *desc = urb->context; |
@@ -167,18 +171,18 @@ static void wdm_in_callback(struct urb *urb) | |||
167 | switch (status) { | 171 | switch (status) { |
168 | case -ENOENT: | 172 | case -ENOENT: |
169 | dev_dbg(&desc->intf->dev, | 173 | dev_dbg(&desc->intf->dev, |
170 | "nonzero urb status received: -ENOENT"); | 174 | "nonzero urb status received: -ENOENT\n"); |
171 | goto skip_error; | 175 | goto skip_error; |
172 | case -ECONNRESET: | 176 | case -ECONNRESET: |
173 | dev_dbg(&desc->intf->dev, | 177 | dev_dbg(&desc->intf->dev, |
174 | "nonzero urb status received: -ECONNRESET"); | 178 | "nonzero urb status received: -ECONNRESET\n"); |
175 | goto skip_error; | 179 | goto skip_error; |
176 | case -ESHUTDOWN: | 180 | case -ESHUTDOWN: |
177 | dev_dbg(&desc->intf->dev, | 181 | dev_dbg(&desc->intf->dev, |
178 | "nonzero urb status received: -ESHUTDOWN"); | 182 | "nonzero urb status received: -ESHUTDOWN\n"); |
179 | goto skip_error; | 183 | goto skip_error; |
180 | case -EPIPE: | 184 | case -EPIPE: |
181 | dev_err(&desc->intf->dev, | 185 | dev_dbg(&desc->intf->dev, |
182 | "nonzero urb status received: -EPIPE\n"); | 186 | "nonzero urb status received: -EPIPE\n"); |
183 | break; | 187 | break; |
184 | default: | 188 | default: |
@@ -188,7 +192,13 @@ static void wdm_in_callback(struct urb *urb) | |||
188 | } | 192 | } |
189 | } | 193 | } |
190 | 194 | ||
191 | desc->rerr = status; | 195 | /* |
196 | * only set a new error if there is no previous error. | ||
197 | * Errors are only cleared during read/open | ||
198 | */ | ||
199 | if (desc->rerr == 0) | ||
200 | desc->rerr = status; | ||
201 | |||
192 | if (length + desc->length > desc->wMaxCommand) { | 202 | if (length + desc->length > desc->wMaxCommand) { |
193 | /* The buffer would overflow */ | 203 | /* The buffer would overflow */ |
194 | set_bit(WDM_OVERFLOW, &desc->flags); | 204 | set_bit(WDM_OVERFLOW, &desc->flags); |
@@ -200,10 +210,40 @@ static void wdm_in_callback(struct urb *urb) | |||
200 | desc->reslength = length; | 210 | desc->reslength = length; |
201 | } | 211 | } |
202 | } | 212 | } |
213 | |||
214 | /* | ||
215 | * Handling devices with the WDM_DRAIN_ON_OPEN flag set: | ||
216 | * If desc->resp_count is unset, then the urb was submitted | ||
217 | * without a prior notification. If the device returned any | ||
218 | * data, then this implies that it had messages queued without | ||
219 | * notifying us. Continue reading until that queue is flushed. | ||
220 | */ | ||
221 | if (!desc->resp_count) { | ||
222 | if (!length) { | ||
223 | /* do not propagate the expected -EPIPE */ | ||
224 | desc->rerr = 0; | ||
225 | goto unlock; | ||
226 | } | ||
227 | dev_dbg(&desc->intf->dev, "got %d bytes without notification\n", length); | ||
228 | set_bit(WDM_RESPONDING, &desc->flags); | ||
229 | usb_submit_urb(desc->response, GFP_ATOMIC); | ||
230 | } | ||
231 | |||
203 | skip_error: | 232 | skip_error: |
233 | set_bit(WDM_READ, &desc->flags); | ||
204 | wake_up(&desc->wait); | 234 | wake_up(&desc->wait); |
205 | 235 | ||
206 | set_bit(WDM_READ, &desc->flags); | 236 | if (desc->rerr) { |
237 | /* | ||
238 | * Since there was an error, userspace may decide to not read | ||
239 | * any data after poll'ing. | ||
240 | * We should respond to further attempts from the device to send | ||
241 | * data, so that we can get unstuck. | ||
242 | */ | ||
243 | service_outstanding_interrupt(desc); | ||
244 | } | ||
245 | |||
246 | unlock: | ||
207 | spin_unlock(&desc->iuspin); | 247 | spin_unlock(&desc->iuspin); |
208 | } | 248 | } |
209 | 249 | ||
@@ -244,18 +284,18 @@ static void wdm_int_callback(struct urb *urb) | |||
244 | switch (dr->bNotificationType) { | 284 | switch (dr->bNotificationType) { |
245 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: | 285 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: |
246 | dev_dbg(&desc->intf->dev, | 286 | dev_dbg(&desc->intf->dev, |
247 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", | 287 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d\n", |
248 | le16_to_cpu(dr->wIndex), le16_to_cpu(dr->wLength)); | 288 | le16_to_cpu(dr->wIndex), le16_to_cpu(dr->wLength)); |
249 | break; | 289 | break; |
250 | 290 | ||
251 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | 291 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: |
252 | 292 | ||
253 | dev_dbg(&desc->intf->dev, | 293 | dev_dbg(&desc->intf->dev, |
254 | "NOTIFY_NETWORK_CONNECTION %s network", | 294 | "NOTIFY_NETWORK_CONNECTION %s network\n", |
255 | dr->wValue ? "connected to" : "disconnected from"); | 295 | dr->wValue ? "connected to" : "disconnected from"); |
256 | goto exit; | 296 | goto exit; |
257 | case USB_CDC_NOTIFY_SPEED_CHANGE: | 297 | case USB_CDC_NOTIFY_SPEED_CHANGE: |
258 | dev_dbg(&desc->intf->dev, "SPEED_CHANGE received (len %u)", | 298 | dev_dbg(&desc->intf->dev, "SPEED_CHANGE received (len %u)\n", |
259 | urb->actual_length); | 299 | urb->actual_length); |
260 | goto exit; | 300 | goto exit; |
261 | default: | 301 | default: |
@@ -274,8 +314,7 @@ static void wdm_int_callback(struct urb *urb) | |||
274 | && !test_bit(WDM_DISCONNECTING, &desc->flags) | 314 | && !test_bit(WDM_DISCONNECTING, &desc->flags) |
275 | && !test_bit(WDM_SUSPENDING, &desc->flags)) { | 315 | && !test_bit(WDM_SUSPENDING, &desc->flags)) { |
276 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | 316 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); |
277 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | 317 | dev_dbg(&desc->intf->dev, "submit response URB %d\n", rv); |
278 | __func__, rv); | ||
279 | } | 318 | } |
280 | spin_unlock(&desc->iuspin); | 319 | spin_unlock(&desc->iuspin); |
281 | if (rv < 0) { | 320 | if (rv < 0) { |
@@ -417,7 +456,7 @@ static ssize_t wdm_write | |||
417 | rv = usb_translate_errors(rv); | 456 | rv = usb_translate_errors(rv); |
418 | goto out_free_mem_pm; | 457 | goto out_free_mem_pm; |
419 | } else { | 458 | } else { |
420 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", | 459 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d\n", |
421 | le16_to_cpu(req->wIndex)); | 460 | le16_to_cpu(req->wIndex)); |
422 | } | 461 | } |
423 | 462 | ||
@@ -436,17 +475,14 @@ out_free_mem: | |||
436 | } | 475 | } |
437 | 476 | ||
438 | /* | 477 | /* |
439 | * clear WDM_READ flag and possibly submit the read urb if resp_count | 478 | * Submit the read urb if resp_count is non-zero. |
440 | * is non-zero. | ||
441 | * | 479 | * |
442 | * Called with desc->iuspin locked | 480 | * Called with desc->iuspin locked |
443 | */ | 481 | */ |
444 | static int clear_wdm_read_flag(struct wdm_device *desc) | 482 | static int service_outstanding_interrupt(struct wdm_device *desc) |
445 | { | 483 | { |
446 | int rv = 0; | 484 | int rv = 0; |
447 | 485 | ||
448 | clear_bit(WDM_READ, &desc->flags); | ||
449 | |||
450 | /* submit read urb only if the device is waiting for it */ | 486 | /* submit read urb only if the device is waiting for it */ |
451 | if (!desc->resp_count || !--desc->resp_count) | 487 | if (!desc->resp_count || !--desc->resp_count) |
452 | goto out; | 488 | goto out; |
@@ -537,8 +573,9 @@ retry: | |||
537 | } | 573 | } |
538 | 574 | ||
539 | if (!desc->reslength) { /* zero length read */ | 575 | if (!desc->reslength) { /* zero length read */ |
540 | dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); | 576 | dev_dbg(&desc->intf->dev, "zero length - clearing WDM_READ\n"); |
541 | rv = clear_wdm_read_flag(desc); | 577 | clear_bit(WDM_READ, &desc->flags); |
578 | rv = service_outstanding_interrupt(desc); | ||
542 | spin_unlock_irq(&desc->iuspin); | 579 | spin_unlock_irq(&desc->iuspin); |
543 | if (rv < 0) | 580 | if (rv < 0) |
544 | goto err; | 581 | goto err; |
@@ -563,8 +600,10 @@ retry: | |||
563 | 600 | ||
564 | desc->length -= cntr; | 601 | desc->length -= cntr; |
565 | /* in case we had outstanding data */ | 602 | /* in case we had outstanding data */ |
566 | if (!desc->length) | 603 | if (!desc->length) { |
567 | clear_wdm_read_flag(desc); | 604 | clear_bit(WDM_READ, &desc->flags); |
605 | service_outstanding_interrupt(desc); | ||
606 | } | ||
568 | spin_unlock_irq(&desc->iuspin); | 607 | spin_unlock_irq(&desc->iuspin); |
569 | rv = cntr; | 608 | rv = cntr; |
570 | 609 | ||
@@ -647,6 +686,17 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
647 | dev_err(&desc->intf->dev, | 686 | dev_err(&desc->intf->dev, |
648 | "Error submitting int urb - %d\n", rv); | 687 | "Error submitting int urb - %d\n", rv); |
649 | rv = usb_translate_errors(rv); | 688 | rv = usb_translate_errors(rv); |
689 | } else if (test_bit(WDM_DRAIN_ON_OPEN, &desc->flags)) { | ||
690 | /* | ||
691 | * Some devices keep pending messages queued | ||
692 | * without resending notifications. We must | ||
693 | * flush the message queue before we can | ||
694 | * assume a one-to-one relationship between | ||
695 | * notifications and messages in the queue | ||
696 | */ | ||
697 | dev_dbg(&desc->intf->dev, "draining queued data\n"); | ||
698 | set_bit(WDM_RESPONDING, &desc->flags); | ||
699 | rv = usb_submit_urb(desc->response, GFP_KERNEL); | ||
650 | } | 700 | } |
651 | } else { | 701 | } else { |
652 | rv = 0; | 702 | rv = 0; |
@@ -673,7 +723,7 @@ static int wdm_release(struct inode *inode, struct file *file) | |||
673 | 723 | ||
674 | if (!desc->count) { | 724 | if (!desc->count) { |
675 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | 725 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { |
676 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | 726 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup\n"); |
677 | kill_urbs(desc); | 727 | kill_urbs(desc); |
678 | spin_lock_irq(&desc->iuspin); | 728 | spin_lock_irq(&desc->iuspin); |
679 | desc->resp_count = 0; | 729 | desc->resp_count = 0; |
@@ -753,7 +803,8 @@ static void wdm_rxwork(struct work_struct *work) | |||
753 | /* --- hotplug --- */ | 803 | /* --- hotplug --- */ |
754 | 804 | ||
755 | static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, | 805 | static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, |
756 | u16 bufsize, int (*manage_power)(struct usb_interface *, int)) | 806 | u16 bufsize, int (*manage_power)(struct usb_interface *, int), |
807 | bool drain_on_open) | ||
757 | { | 808 | { |
758 | int rv = -ENOMEM; | 809 | int rv = -ENOMEM; |
759 | struct wdm_device *desc; | 810 | struct wdm_device *desc; |
@@ -840,6 +891,68 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor | |||
840 | 891 | ||
841 | desc->manage_power = manage_power; | 892 | desc->manage_power = manage_power; |
842 | 893 | ||
894 | /* | ||
895 | * "drain_on_open" enables a hack to work around a firmware | ||
896 | * issue observed on network functions, in particular MBIM | ||
897 | * functions. | ||
898 | * | ||
899 | * Quoting section 7 of the CDC-WMC r1.1 specification: | ||
900 | * | ||
901 | * "The firmware shall interpret GetEncapsulatedResponse as a | ||
902 | * request to read response bytes. The firmware shall send | ||
903 | * the next wLength bytes from the response. The firmware | ||
904 | * shall allow the host to retrieve data using any number of | ||
905 | * GetEncapsulatedResponse requests. The firmware shall | ||
906 | * return a zero- length reply if there are no data bytes | ||
907 | * available. | ||
908 | * | ||
909 | * The firmware shall send ResponseAvailable notifications | ||
910 | * periodically, using any appropriate algorithm, to inform | ||
911 | * the host that there is data available in the reply | ||
912 | * buffer. The firmware is allowed to send ResponseAvailable | ||
913 | * notifications even if there is no data available, but | ||
914 | * this will obviously reduce overall performance." | ||
915 | * | ||
916 | * These requirements, although they make equally sense, are | ||
917 | * often not implemented by network functions. Some firmwares | ||
918 | * will queue data indefinitely, without ever resending a | ||
919 | * notification. The result is that the driver and firmware | ||
920 | * loses "syncronization" if the driver ever fails to respond | ||
921 | * to a single notification, something which easily can happen | ||
922 | * on release(). When this happens, the driver will appear to | ||
923 | * never receive notifications for the most current data. Each | ||
924 | * notification will only cause a single read, which returns | ||
925 | * the oldest data in the firmware's queue. | ||
926 | * | ||
927 | * The "drain_on_open" hack resolves the situation by draining | ||
928 | * data from the firmware until none is returned, without a | ||
929 | * prior notification. | ||
930 | * | ||
931 | * This will inevitably race with the firmware, risking that | ||
932 | * we read data from the device before handling the associated | ||
933 | * notification. To make things worse, some of the devices | ||
934 | * needing the hack do not implement the "return zero if no | ||
935 | * data is available" requirement either. Instead they return | ||
936 | * an error on the subsequent read in this case. This means | ||
937 | * that "winning" the race can cause an unexpected EIO to | ||
938 | * userspace. | ||
939 | * | ||
940 | * "winning" the race is more likely on resume() than on | ||
941 | * open(), and the unexpected error is more harmful in the | ||
942 | * middle of an open session. The hack is therefore only | ||
943 | * applied on open(), and not on resume() where it logically | ||
944 | * would be equally necessary. So we define open() as the only | ||
945 | * driver <-> device "syncronization point". Should we happen | ||
946 | * to lose a notification after open(), then syncronization | ||
947 | * will be lost until release() | ||
948 | * | ||
949 | * The hack should not be enabled for CDC WDM devices | ||
950 | * conforming to the CDC-WMC r1.1 specification. This is | ||
951 | * ensured by setting drain_on_open to false in wdm_probe(). | ||
952 | */ | ||
953 | if (drain_on_open) | ||
954 | set_bit(WDM_DRAIN_ON_OPEN, &desc->flags); | ||
955 | |||
843 | spin_lock(&wdm_device_list_lock); | 956 | spin_lock(&wdm_device_list_lock); |
844 | list_add(&desc->device_list, &wdm_device_list); | 957 | list_add(&desc->device_list, &wdm_device_list); |
845 | spin_unlock(&wdm_device_list_lock); | 958 | spin_unlock(&wdm_device_list_lock); |
@@ -893,7 +1006,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
893 | goto err; | 1006 | goto err; |
894 | ep = &iface->endpoint[0].desc; | 1007 | ep = &iface->endpoint[0].desc; |
895 | 1008 | ||
896 | rv = wdm_create(intf, ep, maxcom, &wdm_manage_power); | 1009 | rv = wdm_create(intf, ep, maxcom, &wdm_manage_power, false); |
897 | 1010 | ||
898 | err: | 1011 | err: |
899 | return rv; | 1012 | return rv; |
@@ -925,7 +1038,7 @@ struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf, | |||
925 | { | 1038 | { |
926 | int rv = -EINVAL; | 1039 | int rv = -EINVAL; |
927 | 1040 | ||
928 | rv = wdm_create(intf, ep, bufsize, manage_power); | 1041 | rv = wdm_create(intf, ep, bufsize, manage_power, true); |
929 | if (rv < 0) | 1042 | if (rv < 0) |
930 | goto err; | 1043 | goto err; |
931 | 1044 | ||
@@ -967,7 +1080,7 @@ static void wdm_disconnect(struct usb_interface *intf) | |||
967 | if (!desc->count) | 1080 | if (!desc->count) |
968 | cleanup(desc); | 1081 | cleanup(desc); |
969 | else | 1082 | else |
970 | dev_dbg(&intf->dev, "%s: %d open files - postponing cleanup\n", __func__, desc->count); | 1083 | dev_dbg(&intf->dev, "%d open files - postponing cleanup\n", desc->count); |
971 | mutex_unlock(&wdm_mutex); | 1084 | mutex_unlock(&wdm_mutex); |
972 | } | 1085 | } |
973 | 1086 | ||
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 917a55c4480d..a6c1fae7d52a 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -141,6 +141,7 @@ static void usbtmc_delete(struct kref *kref) | |||
141 | struct usbtmc_device_data *data = to_usbtmc_data(kref); | 141 | struct usbtmc_device_data *data = to_usbtmc_data(kref); |
142 | 142 | ||
143 | usb_put_dev(data->usb_dev); | 143 | usb_put_dev(data->usb_dev); |
144 | kfree(data); | ||
144 | } | 145 | } |
145 | 146 | ||
146 | static int usbtmc_open(struct inode *inode, struct file *filp) | 147 | static int usbtmc_open(struct inode *inode, struct file *filp) |
@@ -1379,7 +1380,7 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1379 | 1380 | ||
1380 | dev_dbg(&intf->dev, "%s called\n", __func__); | 1381 | dev_dbg(&intf->dev, "%s called\n", __func__); |
1381 | 1382 | ||
1382 | data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); | 1383 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
1383 | if (!data) | 1384 | if (!data) |
1384 | return -ENOMEM; | 1385 | return -ENOMEM; |
1385 | 1386 | ||
@@ -1467,10 +1468,8 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1467 | if (data->iin_ep_present) { | 1468 | if (data->iin_ep_present) { |
1468 | /* allocate int urb */ | 1469 | /* allocate int urb */ |
1469 | data->iin_urb = usb_alloc_urb(0, GFP_KERNEL); | 1470 | data->iin_urb = usb_alloc_urb(0, GFP_KERNEL); |
1470 | if (!data->iin_urb) { | 1471 | if (!data->iin_urb) |
1471 | dev_err(&intf->dev, "Failed to allocate int urb\n"); | ||
1472 | goto error_register; | 1472 | goto error_register; |
1473 | } | ||
1474 | 1473 | ||
1475 | /* will reference data in int urb */ | 1474 | /* will reference data in int urb */ |
1476 | kref_get(&data->kref); | 1475 | kref_get(&data->kref); |
@@ -1478,10 +1477,8 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1478 | /* allocate buffer for interrupt in */ | 1477 | /* allocate buffer for interrupt in */ |
1479 | data->iin_buffer = kmalloc(data->iin_wMaxPacketSize, | 1478 | data->iin_buffer = kmalloc(data->iin_wMaxPacketSize, |
1480 | GFP_KERNEL); | 1479 | GFP_KERNEL); |
1481 | if (!data->iin_buffer) { | 1480 | if (!data->iin_buffer) |
1482 | dev_err(&intf->dev, "Failed to allocate int buf\n"); | ||
1483 | goto error_register; | 1481 | goto error_register; |
1484 | } | ||
1485 | 1482 | ||
1486 | /* fill interrupt urb */ | 1483 | /* fill interrupt urb */ |
1487 | usb_fill_int_urb(data->iin_urb, data->usb_dev, | 1484 | usb_fill_int_urb(data->iin_urb, data->usb_dev, |
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 01c0c0477a9e..8b317702d761 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c | |||
@@ -21,13 +21,13 @@ | |||
21 | 21 | ||
22 | int ulpi_read(struct ulpi *ulpi, u8 addr) | 22 | int ulpi_read(struct ulpi *ulpi, u8 addr) |
23 | { | 23 | { |
24 | return ulpi->ops->read(ulpi->ops, addr); | 24 | return ulpi->ops->read(ulpi->dev.parent, addr); |
25 | } | 25 | } |
26 | EXPORT_SYMBOL_GPL(ulpi_read); | 26 | EXPORT_SYMBOL_GPL(ulpi_read); |
27 | 27 | ||
28 | int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val) | 28 | int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val) |
29 | { | 29 | { |
30 | return ulpi->ops->write(ulpi->ops, addr, val); | 30 | return ulpi->ops->write(ulpi->dev.parent, addr, val); |
31 | } | 31 | } |
32 | EXPORT_SYMBOL_GPL(ulpi_write); | 32 | EXPORT_SYMBOL_GPL(ulpi_write); |
33 | 33 | ||
@@ -127,16 +127,17 @@ static struct device_type ulpi_dev_type = { | |||
127 | * | 127 | * |
128 | * Registers a driver with the ULPI bus. | 128 | * Registers a driver with the ULPI bus. |
129 | */ | 129 | */ |
130 | int ulpi_register_driver(struct ulpi_driver *drv) | 130 | int __ulpi_register_driver(struct ulpi_driver *drv, struct module *module) |
131 | { | 131 | { |
132 | if (!drv->probe) | 132 | if (!drv->probe) |
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | 134 | ||
135 | drv->driver.owner = module; | ||
135 | drv->driver.bus = &ulpi_bus; | 136 | drv->driver.bus = &ulpi_bus; |
136 | 137 | ||
137 | return driver_register(&drv->driver); | 138 | return driver_register(&drv->driver); |
138 | } | 139 | } |
139 | EXPORT_SYMBOL_GPL(ulpi_register_driver); | 140 | EXPORT_SYMBOL_GPL(__ulpi_register_driver); |
140 | 141 | ||
141 | /** | 142 | /** |
142 | * ulpi_unregister_driver - unregister a driver with the ULPI bus | 143 | * ulpi_unregister_driver - unregister a driver with the ULPI bus |
@@ -156,6 +157,8 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) | |||
156 | { | 157 | { |
157 | int ret; | 158 | int ret; |
158 | 159 | ||
160 | ulpi->dev.parent = dev; /* needed early for ops */ | ||
161 | |||
159 | /* Test the interface */ | 162 | /* Test the interface */ |
160 | ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); | 163 | ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); |
161 | if (ret < 0) | 164 | if (ret < 0) |
@@ -174,7 +177,6 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) | |||
174 | ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW); | 177 | ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW); |
175 | ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8; | 178 | ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8; |
176 | 179 | ||
177 | ulpi->dev.parent = dev; | ||
178 | ulpi->dev.bus = &ulpi_bus; | 180 | ulpi->dev.bus = &ulpi_bus; |
179 | ulpi->dev.type = &ulpi_dev_type; | 181 | ulpi->dev.type = &ulpi_dev_type; |
180 | dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev)); | 182 | dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev)); |
@@ -201,7 +203,8 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) | |||
201 | * Allocates and registers a ULPI device and an interface for it. Called from | 203 | * Allocates and registers a ULPI device and an interface for it. Called from |
202 | * the USB controller that provides the ULPI interface. | 204 | * the USB controller that provides the ULPI interface. |
203 | */ | 205 | */ |
204 | struct ulpi *ulpi_register_interface(struct device *dev, struct ulpi_ops *ops) | 206 | struct ulpi *ulpi_register_interface(struct device *dev, |
207 | const struct ulpi_ops *ops) | ||
205 | { | 208 | { |
206 | struct ulpi *ulpi; | 209 | struct ulpi *ulpi; |
207 | int ret; | 210 | int ret; |
@@ -211,7 +214,6 @@ struct ulpi *ulpi_register_interface(struct device *dev, struct ulpi_ops *ops) | |||
211 | return ERR_PTR(-ENOMEM); | 214 | return ERR_PTR(-ENOMEM); |
212 | 215 | ||
213 | ulpi->ops = ops; | 216 | ulpi->ops = ops; |
214 | ops->dev = dev; | ||
215 | 217 | ||
216 | ret = ulpi_register(dev, ulpi); | 218 | ret = ulpi_register(dev, ulpi); |
217 | if (ret) { | 219 | if (ret) { |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index dd280108758f..0e5a889742b3 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -83,23 +83,10 @@ config USB_OTG_FSM | |||
83 | Implements OTG Finite State Machine as specified in On-The-Go | 83 | Implements OTG Finite State Machine as specified in On-The-Go |
84 | and Embedded Host Supplement to the USB Revision 2.0 Specification. | 84 | and Embedded Host Supplement to the USB Revision 2.0 Specification. |
85 | 85 | ||
86 | config USB_ULPI_BUS | 86 | config USB_LEDS_TRIGGER_USBPORT |
87 | tristate "USB ULPI PHY interface support" | 87 | tristate "USB port LED trigger" |
88 | depends on USB_SUPPORT | 88 | depends on USB && LEDS_TRIGGERS |
89 | help | 89 | help |
90 | UTMI+ Low Pin Interface (ULPI) is specification for a commonly used | 90 | This driver allows LEDs to be controlled by USB events. Enabling this |
91 | USB 2.0 PHY interface. The ULPI specification defines a standard set | 91 | trigger allows specifying list of USB ports that should turn on LED |
92 | of registers that can be used to detect the vendor and product which | 92 | when some USB device gets connected. |
93 | allows ULPI to be handled as a bus. This module is the driver for that | ||
94 | bus. | ||
95 | |||
96 | The ULPI interfaces (the buses) are registered by the drivers for USB | ||
97 | controllers which support ULPI register access and have ULPI PHY | ||
98 | attached to them. The ULPI PHY drivers themselves are normal PHY | ||
99 | drivers. | ||
100 | |||
101 | ULPI PHYs provide often functions such as ADP sensing/probing (OTG | ||
102 | protocol) and USB charger detection. | ||
103 | |||
104 | To compile this driver as a module, choose M here: the module will | ||
105 | be called ulpi. | ||
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 9780877010b4..b99b871c4b9d 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -5,9 +5,12 @@ | |||
5 | usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o | 5 | usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o |
6 | usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o | 6 | usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o |
7 | usbcore-y += devio.o notify.o generic.o quirks.o devices.o | 7 | usbcore-y += devio.o notify.o generic.o quirks.o devices.o |
8 | usbcore-y += port.o of.o | 8 | usbcore-y += port.o |
9 | 9 | ||
10 | usbcore-$(CONFIG_OF) += of.o | ||
10 | usbcore-$(CONFIG_PCI) += hcd-pci.o | 11 | usbcore-$(CONFIG_PCI) += hcd-pci.o |
11 | usbcore-$(CONFIG_ACPI) += usb-acpi.o | 12 | usbcore-$(CONFIG_ACPI) += usb-acpi.o |
12 | 13 | ||
13 | obj-$(CONFIG_USB) += usbcore.o | 14 | obj-$(CONFIG_USB) += usbcore.o |
15 | |||
16 | obj-$(CONFIG_USB_LEDS_TRIGGER_USBPORT) += ledtrig-usbport.o | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d2e3f655c26f..479e223f9cff 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/usb.h> | 46 | #include <linux/usb.h> |
47 | #include <linux/usb/hcd.h> | 47 | #include <linux/usb/hcd.h> |
48 | #include <linux/usb/phy.h> | 48 | #include <linux/usb/phy.h> |
49 | #include <linux/usb/otg.h> | ||
49 | 50 | ||
50 | #include "usb.h" | 51 | #include "usb.h" |
51 | 52 | ||
@@ -2517,10 +2518,8 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, | |||
2517 | struct usb_hcd *hcd; | 2518 | struct usb_hcd *hcd; |
2518 | 2519 | ||
2519 | hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); | 2520 | hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); |
2520 | if (!hcd) { | 2521 | if (!hcd) |
2521 | dev_dbg (dev, "hcd alloc failed\n"); | ||
2522 | return NULL; | 2522 | return NULL; |
2523 | } | ||
2524 | if (primary_hcd == NULL) { | 2523 | if (primary_hcd == NULL) { |
2525 | hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex), | 2524 | hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex), |
2526 | GFP_KERNEL); | 2525 | GFP_KERNEL); |
@@ -3033,7 +3032,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); | |||
3033 | 3032 | ||
3034 | /*-------------------------------------------------------------------------*/ | 3033 | /*-------------------------------------------------------------------------*/ |
3035 | 3034 | ||
3036 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) | 3035 | #if IS_ENABLED(CONFIG_USB_MON) |
3037 | 3036 | ||
3038 | const struct usb_mon_operations *mon_ops; | 3037 | const struct usb_mon_operations *mon_ops; |
3039 | 3038 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1d5fc32d06d0..cbb146736f57 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1823,10 +1823,8 @@ descriptor_error: | |||
1823 | dev_info(&intf->dev, "USB hub found\n"); | 1823 | dev_info(&intf->dev, "USB hub found\n"); |
1824 | 1824 | ||
1825 | hub = kzalloc(sizeof(*hub), GFP_KERNEL); | 1825 | hub = kzalloc(sizeof(*hub), GFP_KERNEL); |
1826 | if (!hub) { | 1826 | if (!hub) |
1827 | dev_dbg(&intf->dev, "couldn't kmalloc hub struct\n"); | ||
1828 | return -ENOMEM; | 1827 | return -ENOMEM; |
1829 | } | ||
1830 | 1828 | ||
1831 | kref_init(&hub->kref); | 1829 | kref_init(&hub->kref); |
1832 | hub->intfdev = &intf->dev; | 1830 | hub->intfdev = &intf->dev; |
@@ -3106,7 +3104,7 @@ static int usb_disable_remote_wakeup(struct usb_device *udev) | |||
3106 | USB_CTRL_SET_TIMEOUT); | 3104 | USB_CTRL_SET_TIMEOUT); |
3107 | else | 3105 | else |
3108 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3106 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
3109 | USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, | 3107 | USB_REQ_SET_FEATURE, USB_RECIP_INTERFACE, |
3110 | USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, | 3108 | USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, |
3111 | USB_CTRL_SET_TIMEOUT); | 3109 | USB_CTRL_SET_TIMEOUT); |
3112 | } | 3110 | } |
@@ -5337,11 +5335,10 @@ static int descriptors_changed(struct usb_device *udev, | |||
5337 | } | 5335 | } |
5338 | 5336 | ||
5339 | buf = kmalloc(len, GFP_NOIO); | 5337 | buf = kmalloc(len, GFP_NOIO); |
5340 | if (buf == NULL) { | 5338 | if (!buf) |
5341 | dev_err(&udev->dev, "no mem to re-read configs after reset\n"); | ||
5342 | /* assume the worst */ | 5339 | /* assume the worst */ |
5343 | return 1; | 5340 | return 1; |
5344 | } | 5341 | |
5345 | for (index = 0; index < udev->descriptor.bNumConfigurations; index++) { | 5342 | for (index = 0; index < udev->descriptor.bNumConfigurations; index++) { |
5346 | old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); | 5343 | old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); |
5347 | length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf, | 5344 | length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf, |
diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c new file mode 100644 index 000000000000..3ed5162677ad --- /dev/null +++ b/drivers/usb/core/ledtrig-usbport.c | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | * USB port LED trigger | ||
3 | * | ||
4 | * Copyright (C) 2016 Rafał Miłecki <rafal@milecki.pl> | ||
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 | #include <linux/device.h> | ||
12 | #include <linux/leds.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/usb.h> | ||
16 | |||
17 | struct usbport_trig_data { | ||
18 | struct led_classdev *led_cdev; | ||
19 | struct list_head ports; | ||
20 | struct notifier_block nb; | ||
21 | int count; /* Amount of connected matching devices */ | ||
22 | }; | ||
23 | |||
24 | struct usbport_trig_port { | ||
25 | struct usbport_trig_data *data; | ||
26 | struct usb_device *hub; | ||
27 | int portnum; | ||
28 | char *port_name; | ||
29 | bool observed; | ||
30 | struct device_attribute attr; | ||
31 | struct list_head list; | ||
32 | }; | ||
33 | |||
34 | /*************************************** | ||
35 | * Helpers | ||
36 | ***************************************/ | ||
37 | |||
38 | /** | ||
39 | * usbport_trig_usb_dev_observed - Check if dev is connected to observed port | ||
40 | */ | ||
41 | static bool usbport_trig_usb_dev_observed(struct usbport_trig_data *usbport_data, | ||
42 | struct usb_device *usb_dev) | ||
43 | { | ||
44 | struct usbport_trig_port *port; | ||
45 | |||
46 | if (!usb_dev->parent) | ||
47 | return false; | ||
48 | |||
49 | list_for_each_entry(port, &usbport_data->ports, list) { | ||
50 | if (usb_dev->parent == port->hub && | ||
51 | usb_dev->portnum == port->portnum) | ||
52 | return port->observed; | ||
53 | } | ||
54 | |||
55 | return false; | ||
56 | } | ||
57 | |||
58 | static int usbport_trig_usb_dev_check(struct usb_device *usb_dev, void *data) | ||
59 | { | ||
60 | struct usbport_trig_data *usbport_data = data; | ||
61 | |||
62 | if (usbport_trig_usb_dev_observed(usbport_data, usb_dev)) | ||
63 | usbport_data->count++; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * usbport_trig_update_count - Recalculate amount of connected matching devices | ||
70 | */ | ||
71 | static void usbport_trig_update_count(struct usbport_trig_data *usbport_data) | ||
72 | { | ||
73 | struct led_classdev *led_cdev = usbport_data->led_cdev; | ||
74 | |||
75 | usbport_data->count = 0; | ||
76 | usb_for_each_dev(usbport_data, usbport_trig_usb_dev_check); | ||
77 | led_cdev->brightness_set(led_cdev, | ||
78 | usbport_data->count ? LED_FULL : LED_OFF); | ||
79 | } | ||
80 | |||
81 | /*************************************** | ||
82 | * Device attr | ||
83 | ***************************************/ | ||
84 | |||
85 | static ssize_t usbport_trig_port_show(struct device *dev, | ||
86 | struct device_attribute *attr, char *buf) | ||
87 | { | ||
88 | struct usbport_trig_port *port = container_of(attr, | ||
89 | struct usbport_trig_port, | ||
90 | attr); | ||
91 | |||
92 | return sprintf(buf, "%d\n", port->observed) + 1; | ||
93 | } | ||
94 | |||
95 | static ssize_t usbport_trig_port_store(struct device *dev, | ||
96 | struct device_attribute *attr, | ||
97 | const char *buf, size_t size) | ||
98 | { | ||
99 | struct usbport_trig_port *port = container_of(attr, | ||
100 | struct usbport_trig_port, | ||
101 | attr); | ||
102 | |||
103 | if (!strcmp(buf, "0") || !strcmp(buf, "0\n")) | ||
104 | port->observed = 0; | ||
105 | else if (!strcmp(buf, "1") || !strcmp(buf, "1\n")) | ||
106 | port->observed = 1; | ||
107 | else | ||
108 | return -EINVAL; | ||
109 | |||
110 | usbport_trig_update_count(port->data); | ||
111 | |||
112 | return size; | ||
113 | } | ||
114 | |||
115 | static struct attribute *ports_attrs[] = { | ||
116 | NULL, | ||
117 | }; | ||
118 | static const struct attribute_group ports_group = { | ||
119 | .name = "ports", | ||
120 | .attrs = ports_attrs, | ||
121 | }; | ||
122 | |||
123 | /*************************************** | ||
124 | * Adding & removing ports | ||
125 | ***************************************/ | ||
126 | |||
127 | static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, | ||
128 | struct usb_device *usb_dev, | ||
129 | const char *hub_name, int portnum) | ||
130 | { | ||
131 | struct led_classdev *led_cdev = usbport_data->led_cdev; | ||
132 | struct usbport_trig_port *port; | ||
133 | size_t len; | ||
134 | int err; | ||
135 | |||
136 | port = kzalloc(sizeof(*port), GFP_KERNEL); | ||
137 | if (!port) { | ||
138 | err = -ENOMEM; | ||
139 | goto err_out; | ||
140 | } | ||
141 | |||
142 | port->data = usbport_data; | ||
143 | port->hub = usb_dev; | ||
144 | port->portnum = portnum; | ||
145 | |||
146 | len = strlen(hub_name) + 8; | ||
147 | port->port_name = kzalloc(len, GFP_KERNEL); | ||
148 | if (!port->port_name) { | ||
149 | err = -ENOMEM; | ||
150 | goto err_free_port; | ||
151 | } | ||
152 | snprintf(port->port_name, len, "%s-port%d", hub_name, portnum); | ||
153 | |||
154 | port->attr.attr.name = port->port_name; | ||
155 | port->attr.attr.mode = S_IRUSR | S_IWUSR; | ||
156 | port->attr.show = usbport_trig_port_show; | ||
157 | port->attr.store = usbport_trig_port_store; | ||
158 | |||
159 | err = sysfs_add_file_to_group(&led_cdev->dev->kobj, &port->attr.attr, | ||
160 | ports_group.name); | ||
161 | if (err) | ||
162 | goto err_free_port_name; | ||
163 | |||
164 | list_add_tail(&port->list, &usbport_data->ports); | ||
165 | |||
166 | return 0; | ||
167 | |||
168 | err_free_port_name: | ||
169 | kfree(port->port_name); | ||
170 | err_free_port: | ||
171 | kfree(port); | ||
172 | err_out: | ||
173 | return err; | ||
174 | } | ||
175 | |||
176 | static int usbport_trig_add_usb_dev_ports(struct usb_device *usb_dev, | ||
177 | void *data) | ||
178 | { | ||
179 | struct usbport_trig_data *usbport_data = data; | ||
180 | int i; | ||
181 | |||
182 | for (i = 1; i <= usb_dev->maxchild; i++) | ||
183 | usbport_trig_add_port(usbport_data, usb_dev, | ||
184 | dev_name(&usb_dev->dev), i); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void usbport_trig_remove_port(struct usbport_trig_data *usbport_data, | ||
190 | struct usbport_trig_port *port) | ||
191 | { | ||
192 | struct led_classdev *led_cdev = usbport_data->led_cdev; | ||
193 | |||
194 | list_del(&port->list); | ||
195 | sysfs_remove_file_from_group(&led_cdev->dev->kobj, &port->attr.attr, | ||
196 | ports_group.name); | ||
197 | kfree(port->port_name); | ||
198 | kfree(port); | ||
199 | } | ||
200 | |||
201 | static void usbport_trig_remove_usb_dev_ports(struct usbport_trig_data *usbport_data, | ||
202 | struct usb_device *usb_dev) | ||
203 | { | ||
204 | struct usbport_trig_port *port, *tmp; | ||
205 | |||
206 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { | ||
207 | if (port->hub == usb_dev) | ||
208 | usbport_trig_remove_port(usbport_data, port); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /*************************************** | ||
213 | * Init, exit, etc. | ||
214 | ***************************************/ | ||
215 | |||
216 | static int usbport_trig_notify(struct notifier_block *nb, unsigned long action, | ||
217 | void *data) | ||
218 | { | ||
219 | struct usbport_trig_data *usbport_data = | ||
220 | container_of(nb, struct usbport_trig_data, nb); | ||
221 | struct led_classdev *led_cdev = usbport_data->led_cdev; | ||
222 | struct usb_device *usb_dev = data; | ||
223 | bool observed; | ||
224 | |||
225 | observed = usbport_trig_usb_dev_observed(usbport_data, usb_dev); | ||
226 | |||
227 | switch (action) { | ||
228 | case USB_DEVICE_ADD: | ||
229 | usbport_trig_add_usb_dev_ports(usb_dev, usbport_data); | ||
230 | if (observed && usbport_data->count++ == 0) | ||
231 | led_cdev->brightness_set(led_cdev, LED_FULL); | ||
232 | return NOTIFY_OK; | ||
233 | case USB_DEVICE_REMOVE: | ||
234 | usbport_trig_remove_usb_dev_ports(usbport_data, usb_dev); | ||
235 | if (observed && --usbport_data->count == 0) | ||
236 | led_cdev->brightness_set(led_cdev, LED_OFF); | ||
237 | return NOTIFY_OK; | ||
238 | } | ||
239 | |||
240 | return NOTIFY_DONE; | ||
241 | } | ||
242 | |||
243 | static void usbport_trig_activate(struct led_classdev *led_cdev) | ||
244 | { | ||
245 | struct usbport_trig_data *usbport_data; | ||
246 | int err; | ||
247 | |||
248 | usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); | ||
249 | if (!usbport_data) | ||
250 | return; | ||
251 | usbport_data->led_cdev = led_cdev; | ||
252 | |||
253 | /* List of ports */ | ||
254 | INIT_LIST_HEAD(&usbport_data->ports); | ||
255 | err = sysfs_create_group(&led_cdev->dev->kobj, &ports_group); | ||
256 | if (err) | ||
257 | goto err_free; | ||
258 | usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); | ||
259 | |||
260 | /* Notifications */ | ||
261 | usbport_data->nb.notifier_call = usbport_trig_notify, | ||
262 | led_cdev->trigger_data = usbport_data; | ||
263 | usb_register_notify(&usbport_data->nb); | ||
264 | |||
265 | led_cdev->activated = true; | ||
266 | return; | ||
267 | |||
268 | err_free: | ||
269 | kfree(usbport_data); | ||
270 | } | ||
271 | |||
272 | static void usbport_trig_deactivate(struct led_classdev *led_cdev) | ||
273 | { | ||
274 | struct usbport_trig_data *usbport_data = led_cdev->trigger_data; | ||
275 | struct usbport_trig_port *port, *tmp; | ||
276 | |||
277 | if (!led_cdev->activated) | ||
278 | return; | ||
279 | |||
280 | list_for_each_entry_safe(port, tmp, &usbport_data->ports, list) { | ||
281 | usbport_trig_remove_port(usbport_data, port); | ||
282 | } | ||
283 | |||
284 | usb_unregister_notify(&usbport_data->nb); | ||
285 | |||
286 | sysfs_remove_group(&led_cdev->dev->kobj, &ports_group); | ||
287 | |||
288 | kfree(usbport_data); | ||
289 | |||
290 | led_cdev->activated = false; | ||
291 | } | ||
292 | |||
293 | static struct led_trigger usbport_led_trigger = { | ||
294 | .name = "usbport", | ||
295 | .activate = usbport_trig_activate, | ||
296 | .deactivate = usbport_trig_deactivate, | ||
297 | }; | ||
298 | |||
299 | static int __init usbport_trig_init(void) | ||
300 | { | ||
301 | return led_trigger_register(&usbport_led_trigger); | ||
302 | } | ||
303 | |||
304 | static void __exit usbport_trig_exit(void) | ||
305 | { | ||
306 | led_trigger_unregister(&usbport_led_trigger); | ||
307 | } | ||
308 | |||
309 | module_init(usbport_trig_init); | ||
310 | module_exit(usbport_trig_exit); | ||
311 | |||
312 | MODULE_AUTHOR("Rafał Miłecki <rafal@milecki.pl>"); | ||
313 | MODULE_DESCRIPTION("USB port trigger"); | ||
314 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 0406a59f0551..3a4707746157 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1760,17 +1760,14 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1760 | nintf = cp->desc.bNumInterfaces; | 1760 | nintf = cp->desc.bNumInterfaces; |
1761 | new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), | 1761 | new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), |
1762 | GFP_NOIO); | 1762 | GFP_NOIO); |
1763 | if (!new_interfaces) { | 1763 | if (!new_interfaces) |
1764 | dev_err(&dev->dev, "Out of memory\n"); | ||
1765 | return -ENOMEM; | 1764 | return -ENOMEM; |
1766 | } | ||
1767 | 1765 | ||
1768 | for (; n < nintf; ++n) { | 1766 | for (; n < nintf; ++n) { |
1769 | new_interfaces[n] = kzalloc( | 1767 | new_interfaces[n] = kzalloc( |
1770 | sizeof(struct usb_interface), | 1768 | sizeof(struct usb_interface), |
1771 | GFP_NOIO); | 1769 | GFP_NOIO); |
1772 | if (!new_interfaces[n]) { | 1770 | if (!new_interfaces[n]) { |
1773 | dev_err(&dev->dev, "Out of memory\n"); | ||
1774 | ret = -ENOMEM; | 1771 | ret = -ENOMEM; |
1775 | free_interfaces: | 1772 | free_interfaces: |
1776 | while (--n >= 0) | 1773 | while (--n >= 0) |
@@ -1862,7 +1859,12 @@ free_interfaces: | |||
1862 | intf->dev.bus = &usb_bus_type; | 1859 | intf->dev.bus = &usb_bus_type; |
1863 | intf->dev.type = &usb_if_device_type; | 1860 | intf->dev.type = &usb_if_device_type; |
1864 | intf->dev.groups = usb_interface_groups; | 1861 | intf->dev.groups = usb_interface_groups; |
1862 | /* | ||
1863 | * Please refer to usb_alloc_dev() to see why we set | ||
1864 | * dma_mask and dma_pfn_offset. | ||
1865 | */ | ||
1865 | intf->dev.dma_mask = dev->dev.dma_mask; | 1866 | intf->dev.dma_mask = dev->dev.dma_mask; |
1867 | intf->dev.dma_pfn_offset = dev->dev.dma_pfn_offset; | ||
1866 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1868 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
1867 | intf->minor = -1; | 1869 | intf->minor = -1; |
1868 | device_initialize(&intf->dev); | 1870 | device_initialize(&intf->dev); |
diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c index 2289700c31d6..3de4f8873984 100644 --- a/drivers/usb/core/of.c +++ b/drivers/usb/core/of.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/usb/of.h> | ||
21 | 22 | ||
22 | /** | 23 | /** |
23 | * usb_of_get_child_node - Find the device node match port number | 24 | * usb_of_get_child_node - Find the device node match port number |
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h index a95b0c989c21..085049d37d7a 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h | |||
@@ -38,7 +38,7 @@ static struct usb_device_id whitelist_table[] = { | |||
38 | { USB_DEVICE(0x0525, 0xa4a2), }, | 38 | { USB_DEVICE(0x0525, 0xa4a2), }, |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #if defined(CONFIG_USB_TEST) || defined(CONFIG_USB_TEST_MODULE) | 41 | #if IS_ENABLED(CONFIG_USB_TEST) |
42 | /* gadget zero, for testing */ | 42 | /* gadget zero, for testing */ |
43 | { USB_DEVICE(0x0525, 0xa4a0), }, | 43 | { USB_DEVICE(0x0525, 0xa4a0), }, |
44 | #endif | 44 | #endif |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c601e25b609f..a9039696476e 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -68,10 +68,8 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) | |||
68 | urb = kmalloc(sizeof(struct urb) + | 68 | urb = kmalloc(sizeof(struct urb) + |
69 | iso_packets * sizeof(struct usb_iso_packet_descriptor), | 69 | iso_packets * sizeof(struct usb_iso_packet_descriptor), |
70 | mem_flags); | 70 | mem_flags); |
71 | if (!urb) { | 71 | if (!urb) |
72 | printk(KERN_ERR "alloc_urb: kmalloc failed\n"); | ||
73 | return NULL; | 72 | return NULL; |
74 | } | ||
75 | usb_init_urb(urb); | 73 | usb_init_urb(urb); |
76 | return urb; | 74 | return urb; |
77 | } | 75 | } |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 5e80697ef952..592151461017 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -440,7 +440,18 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
440 | dev->dev.bus = &usb_bus_type; | 440 | dev->dev.bus = &usb_bus_type; |
441 | dev->dev.type = &usb_device_type; | 441 | dev->dev.type = &usb_device_type; |
442 | dev->dev.groups = usb_device_groups; | 442 | dev->dev.groups = usb_device_groups; |
443 | /* | ||
444 | * Fake a dma_mask/offset for the USB device: | ||
445 | * We cannot really use the dma-mapping API (dma_alloc_* and | ||
446 | * dma_map_*) for USB devices but instead need to use | ||
447 | * usb_alloc_coherent and pass data in 'urb's, but some subsystems | ||
448 | * manually look into the mask/offset pair to determine whether | ||
449 | * they need bounce buffers. | ||
450 | * Note: calling dma_set_mask() on a USB device would set the | ||
451 | * mask for the entire HCD, so don't do that. | ||
452 | */ | ||
443 | dev->dev.dma_mask = bus->controller->dma_mask; | 453 | dev->dev.dma_mask = bus->controller->dma_mask; |
454 | dev->dev.dma_pfn_offset = bus->controller->dma_pfn_offset; | ||
444 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 455 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
445 | dev->state = USB_STATE_ATTACHED; | 456 | dev->state = USB_STATE_ATTACHED; |
446 | dev->lpm_disable_count = 1; | 457 | dev->lpm_disable_count = 1; |
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 4135a5ff67ca..fa9b26b91507 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -238,6 +238,77 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg) | |||
238 | return ret; | 238 | return ret; |
239 | } | 239 | } |
240 | 240 | ||
241 | /** | ||
242 | * dwc2_wait_for_mode() - Waits for the controller mode. | ||
243 | * @hsotg: Programming view of the DWC_otg controller. | ||
244 | * @host_mode: If true, waits for host mode, otherwise device mode. | ||
245 | */ | ||
246 | static void dwc2_wait_for_mode(struct dwc2_hsotg *hsotg, | ||
247 | bool host_mode) | ||
248 | { | ||
249 | ktime_t start; | ||
250 | ktime_t end; | ||
251 | unsigned int timeout = 110; | ||
252 | |||
253 | dev_vdbg(hsotg->dev, "Waiting for %s mode\n", | ||
254 | host_mode ? "host" : "device"); | ||
255 | |||
256 | start = ktime_get(); | ||
257 | |||
258 | while (1) { | ||
259 | s64 ms; | ||
260 | |||
261 | if (dwc2_is_host_mode(hsotg) == host_mode) { | ||
262 | dev_vdbg(hsotg->dev, "%s mode set\n", | ||
263 | host_mode ? "Host" : "Device"); | ||
264 | break; | ||
265 | } | ||
266 | |||
267 | end = ktime_get(); | ||
268 | ms = ktime_to_ms(ktime_sub(end, start)); | ||
269 | |||
270 | if (ms >= (s64)timeout) { | ||
271 | dev_warn(hsotg->dev, "%s: Couldn't set %s mode\n", | ||
272 | __func__, host_mode ? "host" : "device"); | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | usleep_range(1000, 2000); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * dwc2_iddig_filter_enabled() - Returns true if the IDDIG debounce | ||
282 | * filter is enabled. | ||
283 | */ | ||
284 | static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg) | ||
285 | { | ||
286 | u32 gsnpsid; | ||
287 | u32 ghwcfg4; | ||
288 | |||
289 | if (!dwc2_hw_is_otg(hsotg)) | ||
290 | return false; | ||
291 | |||
292 | /* Check if core configuration includes the IDDIG filter. */ | ||
293 | ghwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4); | ||
294 | if (!(ghwcfg4 & GHWCFG4_IDDIG_FILT_EN)) | ||
295 | return false; | ||
296 | |||
297 | /* | ||
298 | * Check if the IDDIG debounce filter is bypassed. Available | ||
299 | * in core version >= 3.10a. | ||
300 | */ | ||
301 | gsnpsid = dwc2_readl(hsotg->regs + GSNPSID); | ||
302 | if (gsnpsid >= DWC2_CORE_REV_3_10a) { | ||
303 | u32 gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); | ||
304 | |||
305 | if (gotgctl & GOTGCTL_DBNCE_FLTR_BYPASS) | ||
306 | return false; | ||
307 | } | ||
308 | |||
309 | return true; | ||
310 | } | ||
311 | |||
241 | /* | 312 | /* |
242 | * Do core a soft reset of the core. Be careful with this because it | 313 | * Do core a soft reset of the core. Be careful with this because it |
243 | * resets all the internal state machines of the core. | 314 | * resets all the internal state machines of the core. |
@@ -246,9 +317,30 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) | |||
246 | { | 317 | { |
247 | u32 greset; | 318 | u32 greset; |
248 | int count = 0; | 319 | int count = 0; |
320 | bool wait_for_host_mode = false; | ||
249 | 321 | ||
250 | dev_vdbg(hsotg->dev, "%s()\n", __func__); | 322 | dev_vdbg(hsotg->dev, "%s()\n", __func__); |
251 | 323 | ||
324 | /* | ||
325 | * If the current mode is host, either due to the force mode | ||
326 | * bit being set (which persists after core reset) or the | ||
327 | * connector id pin, a core soft reset will temporarily reset | ||
328 | * the mode to device. A delay from the IDDIG debounce filter | ||
329 | * will occur before going back to host mode. | ||
330 | * | ||
331 | * Determine whether we will go back into host mode after a | ||
332 | * reset and account for this delay after the reset. | ||
333 | */ | ||
334 | if (dwc2_iddig_filter_enabled(hsotg)) { | ||
335 | u32 gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); | ||
336 | u32 gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
337 | |||
338 | if (!(gotgctl & GOTGCTL_CONID_B) || | ||
339 | (gusbcfg & GUSBCFG_FORCEHOSTMODE)) { | ||
340 | wait_for_host_mode = true; | ||
341 | } | ||
342 | } | ||
343 | |||
252 | /* Core Soft Reset */ | 344 | /* Core Soft Reset */ |
253 | greset = dwc2_readl(hsotg->regs + GRSTCTL); | 345 | greset = dwc2_readl(hsotg->regs + GRSTCTL); |
254 | greset |= GRSTCTL_CSFTRST; | 346 | greset |= GRSTCTL_CSFTRST; |
@@ -277,6 +369,9 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) | |||
277 | } | 369 | } |
278 | } while (!(greset & GRSTCTL_AHBIDLE)); | 370 | } while (!(greset & GRSTCTL_AHBIDLE)); |
279 | 371 | ||
372 | if (wait_for_host_mode) | ||
373 | dwc2_wait_for_mode(hsotg, true); | ||
374 | |||
280 | return 0; | 375 | return 0; |
281 | } | 376 | } |
282 | 377 | ||
@@ -300,9 +395,9 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg) | |||
300 | * Checks are done in this function to determine whether doing a force | 395 | * Checks are done in this function to determine whether doing a force |
301 | * would be valid or not. | 396 | * would be valid or not. |
302 | * | 397 | * |
303 | * If a force is done, it requires a 25ms delay to take effect. | 398 | * If a force is done, it requires a IDDIG debounce filter delay if |
304 | * | 399 | * the filter is configured and enabled. We poll the current mode of |
305 | * Returns true if the mode was forced. | 400 | * the controller to account for this delay. |
306 | */ | 401 | */ |
307 | static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) | 402 | static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) |
308 | { | 403 | { |
@@ -337,12 +432,18 @@ static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) | |||
337 | gusbcfg |= set; | 432 | gusbcfg |= set; |
338 | dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); | 433 | dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); |
339 | 434 | ||
340 | msleep(25); | 435 | dwc2_wait_for_mode(hsotg, host); |
341 | return true; | 436 | return true; |
342 | } | 437 | } |
343 | 438 | ||
344 | /* | 439 | /** |
345 | * Clears the force mode bits. | 440 | * dwc2_clear_force_mode() - Clears the force mode bits. |
441 | * | ||
442 | * After clearing the bits, wait up to 100 ms to account for any | ||
443 | * potential IDDIG filter delay. We can't know if we expect this delay | ||
444 | * or not because the value of the connector ID status is affected by | ||
445 | * the force mode. We only need to call this once during probe if | ||
446 | * dr_mode == OTG. | ||
346 | */ | 447 | */ |
347 | static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) | 448 | static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) |
348 | { | 449 | { |
@@ -353,11 +454,8 @@ static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg) | |||
353 | gusbcfg &= ~GUSBCFG_FORCEDEVMODE; | 454 | gusbcfg &= ~GUSBCFG_FORCEDEVMODE; |
354 | dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); | 455 | dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); |
355 | 456 | ||
356 | /* | 457 | if (dwc2_iddig_filter_enabled(hsotg)) |
357 | * NOTE: This long sleep is _very_ important, otherwise the core will | 458 | usleep_range(100000, 110000); |
358 | * not stay in host mode after a connector ID change! | ||
359 | */ | ||
360 | msleep(25); | ||
361 | } | 459 | } |
362 | 460 | ||
363 | /* | 461 | /* |
@@ -380,12 +478,6 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg) | |||
380 | __func__, hsotg->dr_mode); | 478 | __func__, hsotg->dr_mode); |
381 | break; | 479 | break; |
382 | } | 480 | } |
383 | |||
384 | /* | ||
385 | * NOTE: This is required for some rockchip soc based | ||
386 | * platforms. | ||
387 | */ | ||
388 | msleep(50); | ||
389 | } | 481 | } |
390 | 482 | ||
391 | /* | 483 | /* |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d64551243789..aad4107ef927 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
@@ -259,13 +259,6 @@ enum dwc2_lx_state { | |||
259 | DWC2_L3, /* Off state */ | 259 | DWC2_L3, /* Off state */ |
260 | }; | 260 | }; |
261 | 261 | ||
262 | /* | ||
263 | * Gadget periodic tx fifo sizes as used by legacy driver | ||
264 | * EP0 is not included | ||
265 | */ | ||
266 | #define DWC2_G_P_LEGACY_TX_FIFO_SIZE {256, 256, 256, 256, 768, 768, 768, \ | ||
267 | 768, 0, 0, 0, 0, 0, 0, 0} | ||
268 | |||
269 | /* Gadget ep0 states */ | 262 | /* Gadget ep0 states */ |
270 | enum dwc2_ep0_state { | 263 | enum dwc2_ep0_state { |
271 | DWC2_EP0_SETUP, | 264 | DWC2_EP0_SETUP, |
@@ -890,6 +883,7 @@ struct dwc2_hsotg { | |||
890 | #define DWC2_CORE_REV_2_92a 0x4f54292a | 883 | #define DWC2_CORE_REV_2_92a 0x4f54292a |
891 | #define DWC2_CORE_REV_2_94a 0x4f54294a | 884 | #define DWC2_CORE_REV_2_94a 0x4f54294a |
892 | #define DWC2_CORE_REV_3_00a 0x4f54300a | 885 | #define DWC2_CORE_REV_3_00a 0x4f54300a |
886 | #define DWC2_CORE_REV_3_10a 0x4f54310a | ||
893 | 887 | ||
894 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | 888 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) |
895 | union dwc2_hcd_internal_flags { | 889 | union dwc2_hcd_internal_flags { |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index af46adfae41c..4cd6403a7566 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -186,9 +186,10 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, | |||
186 | */ | 186 | */ |
187 | static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | 187 | static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) |
188 | { | 188 | { |
189 | unsigned int ep; | 189 | unsigned int fifo; |
190 | unsigned int addr; | 190 | unsigned int addr; |
191 | int timeout; | 191 | int timeout; |
192 | u32 dptxfsizn; | ||
192 | u32 val; | 193 | u32 val; |
193 | 194 | ||
194 | /* Reset fifo map if not correctly cleared during previous session */ | 195 | /* Reset fifo map if not correctly cleared during previous session */ |
@@ -216,16 +217,16 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) | |||
216 | * them to endpoints dynamically according to maxpacket size value of | 217 | * them to endpoints dynamically according to maxpacket size value of |
217 | * given endpoint. | 218 | * given endpoint. |
218 | */ | 219 | */ |
219 | for (ep = 1; ep < MAX_EPS_CHANNELS; ep++) { | 220 | for (fifo = 1; fifo < MAX_EPS_CHANNELS; fifo++) { |
220 | if (!hsotg->g_tx_fifo_sz[ep]) | 221 | dptxfsizn = dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)); |
221 | continue; | 222 | |
222 | val = addr; | 223 | val = (dptxfsizn & FIFOSIZE_DEPTH_MASK) | addr; |
223 | val |= hsotg->g_tx_fifo_sz[ep] << FIFOSIZE_DEPTH_SHIFT; | 224 | addr += dptxfsizn >> FIFOSIZE_DEPTH_SHIFT; |
224 | WARN_ONCE(addr + hsotg->g_tx_fifo_sz[ep] > hsotg->fifo_mem, | 225 | |
225 | "insufficient fifo memory"); | 226 | if (addr > hsotg->fifo_mem) |
226 | addr += hsotg->g_tx_fifo_sz[ep]; | 227 | break; |
227 | 228 | ||
228 | dwc2_writel(val, hsotg->regs + DPTXFSIZN(ep)); | 229 | dwc2_writel(val, hsotg->regs + DPTXFSIZN(fifo)); |
229 | } | 230 | } |
230 | 231 | ||
231 | /* | 232 | /* |
@@ -388,7 +389,8 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, | |||
388 | return -ENOSPC; | 389 | return -ENOSPC; |
389 | } | 390 | } |
390 | } else if (hsotg->dedicated_fifos && hs_ep->index != 0) { | 391 | } else if (hsotg->dedicated_fifos && hs_ep->index != 0) { |
391 | can_write = dwc2_readl(hsotg->regs + DTXFSTS(hs_ep->index)); | 392 | can_write = dwc2_readl(hsotg->regs + |
393 | DTXFSTS(hs_ep->fifo_index)); | ||
392 | 394 | ||
393 | can_write &= 0xffff; | 395 | can_write &= 0xffff; |
394 | can_write *= 4; | 396 | can_write *= 4; |
@@ -2432,7 +2434,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, | |||
2432 | 2434 | ||
2433 | if (!hsotg->dedicated_fifos) | 2435 | if (!hsotg->dedicated_fifos) |
2434 | return; | 2436 | return; |
2435 | size = (dwc2_readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; | 2437 | size = (dwc2_readl(hsotg->regs + DTXFSTS(ep->fifo_index)) & 0xffff) * 4; |
2436 | if (size < ep->fifo_size) | 2438 | if (size < ep->fifo_size) |
2437 | dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); | 2439 | dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); |
2438 | } | 2440 | } |
@@ -3041,22 +3043,11 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, | |||
3041 | break; | 3043 | break; |
3042 | } | 3044 | } |
3043 | 3045 | ||
3044 | /* If fifo is already allocated for this ep */ | ||
3045 | if (hs_ep->fifo_index) { | ||
3046 | size = hs_ep->ep.maxpacket * hs_ep->mc; | ||
3047 | /* If bigger fifo is required deallocate current one */ | ||
3048 | if (size > hs_ep->fifo_size) { | ||
3049 | hsotg->fifo_map &= ~(1 << hs_ep->fifo_index); | ||
3050 | hs_ep->fifo_index = 0; | ||
3051 | hs_ep->fifo_size = 0; | ||
3052 | } | ||
3053 | } | ||
3054 | |||
3055 | /* | 3046 | /* |
3056 | * if the hardware has dedicated fifos, we must give each IN EP | 3047 | * if the hardware has dedicated fifos, we must give each IN EP |
3057 | * a unique tx-fifo even if it is non-periodic. | 3048 | * a unique tx-fifo even if it is non-periodic. |
3058 | */ | 3049 | */ |
3059 | if (dir_in && hsotg->dedicated_fifos && !hs_ep->fifo_index) { | 3050 | if (dir_in && hsotg->dedicated_fifos) { |
3060 | u32 fifo_index = 0; | 3051 | u32 fifo_index = 0; |
3061 | u32 fifo_size = UINT_MAX; | 3052 | u32 fifo_size = UINT_MAX; |
3062 | size = hs_ep->ep.maxpacket*hs_ep->mc; | 3053 | size = hs_ep->ep.maxpacket*hs_ep->mc; |
@@ -3129,10 +3120,6 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep) | |||
3129 | 3120 | ||
3130 | spin_lock_irqsave(&hsotg->lock, flags); | 3121 | spin_lock_irqsave(&hsotg->lock, flags); |
3131 | 3122 | ||
3132 | hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); | ||
3133 | hs_ep->fifo_index = 0; | ||
3134 | hs_ep->fifo_size = 0; | ||
3135 | |||
3136 | ctrl = dwc2_readl(hsotg->regs + epctrl_reg); | 3123 | ctrl = dwc2_readl(hsotg->regs + epctrl_reg); |
3137 | ctrl &= ~DXEPCTL_EPENA; | 3124 | ctrl &= ~DXEPCTL_EPENA; |
3138 | ctrl &= ~DXEPCTL_USBACTEP; | 3125 | ctrl &= ~DXEPCTL_USBACTEP; |
@@ -3147,6 +3134,10 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep) | |||
3147 | /* terminate all requests with shutdown */ | 3134 | /* terminate all requests with shutdown */ |
3148 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN); | 3135 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN); |
3149 | 3136 | ||
3137 | hsotg->fifo_map &= ~(1 << hs_ep->fifo_index); | ||
3138 | hs_ep->fifo_index = 0; | ||
3139 | hs_ep->fifo_size = 0; | ||
3140 | |||
3150 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3141 | spin_unlock_irqrestore(&hsotg->lock, flags); |
3151 | return 0; | 3142 | return 0; |
3152 | } | 3143 | } |
@@ -3475,8 +3466,11 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, | |||
3475 | otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget); | 3466 | otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget); |
3476 | 3467 | ||
3477 | spin_lock_irqsave(&hsotg->lock, flags); | 3468 | spin_lock_irqsave(&hsotg->lock, flags); |
3478 | dwc2_hsotg_init(hsotg); | 3469 | if (dwc2_hw_is_device(hsotg)) { |
3479 | dwc2_hsotg_core_init_disconnected(hsotg, false); | 3470 | dwc2_hsotg_init(hsotg); |
3471 | dwc2_hsotg_core_init_disconnected(hsotg, false); | ||
3472 | } | ||
3473 | |||
3480 | hsotg->enabled = 0; | 3474 | hsotg->enabled = 0; |
3481 | spin_unlock_irqrestore(&hsotg->lock, flags); | 3475 | spin_unlock_irqrestore(&hsotg->lock, flags); |
3482 | 3476 | ||
@@ -3813,36 +3807,10 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg) | |||
3813 | static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) | 3807 | static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) |
3814 | { | 3808 | { |
3815 | struct device_node *np = hsotg->dev->of_node; | 3809 | struct device_node *np = hsotg->dev->of_node; |
3816 | u32 len = 0; | ||
3817 | u32 i = 0; | ||
3818 | 3810 | ||
3819 | /* Enable dma if requested in device tree */ | 3811 | /* Enable dma if requested in device tree */ |
3820 | hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma"); | 3812 | hsotg->g_using_dma = of_property_read_bool(np, "g-use-dma"); |
3821 | 3813 | ||
3822 | /* | ||
3823 | * Register TX periodic fifo size per endpoint. | ||
3824 | * EP0 is excluded since it has no fifo configuration. | ||
3825 | */ | ||
3826 | if (!of_find_property(np, "g-tx-fifo-size", &len)) | ||
3827 | goto rx_fifo; | ||
3828 | |||
3829 | len /= sizeof(u32); | ||
3830 | |||
3831 | /* Read tx fifo sizes other than ep0 */ | ||
3832 | if (of_property_read_u32_array(np, "g-tx-fifo-size", | ||
3833 | &hsotg->g_tx_fifo_sz[1], len)) | ||
3834 | goto rx_fifo; | ||
3835 | |||
3836 | /* Add ep0 */ | ||
3837 | len++; | ||
3838 | |||
3839 | /* Make remaining TX fifos unavailable */ | ||
3840 | if (len < MAX_EPS_CHANNELS) { | ||
3841 | for (i = len; i < MAX_EPS_CHANNELS; i++) | ||
3842 | hsotg->g_tx_fifo_sz[i] = 0; | ||
3843 | } | ||
3844 | |||
3845 | rx_fifo: | ||
3846 | /* Register RX fifo size */ | 3814 | /* Register RX fifo size */ |
3847 | of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz); | 3815 | of_property_read_u32(np, "g-rx-fifo-size", &hsotg->g_rx_fifo_sz); |
3848 | 3816 | ||
@@ -3864,13 +3832,10 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3864 | struct device *dev = hsotg->dev; | 3832 | struct device *dev = hsotg->dev; |
3865 | int epnum; | 3833 | int epnum; |
3866 | int ret; | 3834 | int ret; |
3867 | int i; | ||
3868 | u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE; | ||
3869 | 3835 | ||
3870 | /* Initialize to legacy fifo configuration values */ | 3836 | /* Initialize to legacy fifo configuration values */ |
3871 | hsotg->g_rx_fifo_sz = 2048; | 3837 | hsotg->g_rx_fifo_sz = 2048; |
3872 | hsotg->g_np_g_tx_fifo_sz = 1024; | 3838 | hsotg->g_np_g_tx_fifo_sz = 1024; |
3873 | memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo)); | ||
3874 | /* Device tree specific probe */ | 3839 | /* Device tree specific probe */ |
3875 | dwc2_hsotg_of_probe(hsotg); | 3840 | dwc2_hsotg_of_probe(hsotg); |
3876 | 3841 | ||
@@ -3888,9 +3853,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3888 | dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", | 3853 | dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", |
3889 | hsotg->g_np_g_tx_fifo_sz); | 3854 | hsotg->g_np_g_tx_fifo_sz); |
3890 | dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz); | 3855 | dev_dbg(dev, "RXFIFO size: %d\n", hsotg->g_rx_fifo_sz); |
3891 | for (i = 0; i < MAX_EPS_CHANNELS; i++) | ||
3892 | dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i, | ||
3893 | hsotg->g_tx_fifo_sz[i]); | ||
3894 | 3856 | ||
3895 | hsotg->gadget.max_speed = USB_SPEED_HIGH; | 3857 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
3896 | hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; | 3858 | hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; |
@@ -3908,17 +3870,13 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3908 | 3870 | ||
3909 | hsotg->ctrl_buff = devm_kzalloc(hsotg->dev, | 3871 | hsotg->ctrl_buff = devm_kzalloc(hsotg->dev, |
3910 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); | 3872 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); |
3911 | if (!hsotg->ctrl_buff) { | 3873 | if (!hsotg->ctrl_buff) |
3912 | dev_err(dev, "failed to allocate ctrl request buff\n"); | ||
3913 | return -ENOMEM; | 3874 | return -ENOMEM; |
3914 | } | ||
3915 | 3875 | ||
3916 | hsotg->ep0_buff = devm_kzalloc(hsotg->dev, | 3876 | hsotg->ep0_buff = devm_kzalloc(hsotg->dev, |
3917 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); | 3877 | DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); |
3918 | if (!hsotg->ep0_buff) { | 3878 | if (!hsotg->ep0_buff) |
3919 | dev_err(dev, "failed to allocate ctrl reply buff\n"); | ||
3920 | return -ENOMEM; | 3879 | return -ENOMEM; |
3921 | } | ||
3922 | 3880 | ||
3923 | ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED, | 3881 | ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED, |
3924 | dev_name(hsotg->dev), hsotg); | 3882 | dev_name(hsotg->dev), hsotg); |
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 2df3d04d26f5..df5a06578005 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -5040,7 +5040,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) | |||
5040 | 5040 | ||
5041 | /* Create new workqueue and init work */ | 5041 | /* Create new workqueue and init work */ |
5042 | retval = -ENOMEM; | 5042 | retval = -ENOMEM; |
5043 | hsotg->wq_otg = create_singlethread_workqueue("dwc2"); | 5043 | hsotg->wq_otg = alloc_ordered_workqueue("dwc2", 0); |
5044 | if (!hsotg->wq_otg) { | 5044 | if (!hsotg->wq_otg) { |
5045 | dev_err(hsotg->dev, "Failed to create workqueue\n"); | 5045 | dev_err(hsotg->dev, "Failed to create workqueue\n"); |
5046 | goto error2; | 5046 | goto error2; |
diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index efc3bcde2822..91058441e62a 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h | |||
@@ -48,6 +48,7 @@ | |||
48 | #define GOTGCTL_ASESVLD (1 << 18) | 48 | #define GOTGCTL_ASESVLD (1 << 18) |
49 | #define GOTGCTL_DBNC_SHORT (1 << 17) | 49 | #define GOTGCTL_DBNC_SHORT (1 << 17) |
50 | #define GOTGCTL_CONID_B (1 << 16) | 50 | #define GOTGCTL_CONID_B (1 << 16) |
51 | #define GOTGCTL_DBNCE_FLTR_BYPASS (1 << 15) | ||
51 | #define GOTGCTL_DEVHNPEN (1 << 11) | 52 | #define GOTGCTL_DEVHNPEN (1 << 11) |
52 | #define GOTGCTL_HSTSETHNPEN (1 << 10) | 53 | #define GOTGCTL_HSTSETHNPEN (1 << 10) |
53 | #define GOTGCTL_HNPREQ (1 << 9) | 54 | #define GOTGCTL_HNPREQ (1 << 9) |
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index a64ce1c94d6d..b97cde76914d 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config USB_DWC3 | 1 | config USB_DWC3 |
2 | tristate "DesignWare USB3 DRD Core Support" | 2 | tristate "DesignWare USB3 DRD Core Support" |
3 | depends on (USB || USB_GADGET) && HAS_DMA | 3 | depends on (USB || USB_GADGET) && HAS_DMA |
4 | select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD | 4 | select USB_XHCI_PLATFORM if USB_XHCI_HCD |
5 | help | 5 | help |
6 | Say Y or M here if your system has a Dual Role SuperSpeed | 6 | Say Y or M here if your system has a Dual Role SuperSpeed |
7 | USB controller based on the DesignWare USB3 IP Core. | 7 | USB controller based on the DesignWare USB3 IP Core. |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 35d092456bec..7287a763cd0c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -49,6 +49,57 @@ | |||
49 | 49 | ||
50 | #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ | 50 | #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ |
51 | 51 | ||
52 | /** | ||
53 | * dwc3_get_dr_mode - Validates and sets dr_mode | ||
54 | * @dwc: pointer to our context structure | ||
55 | */ | ||
56 | static int dwc3_get_dr_mode(struct dwc3 *dwc) | ||
57 | { | ||
58 | enum usb_dr_mode mode; | ||
59 | struct device *dev = dwc->dev; | ||
60 | unsigned int hw_mode; | ||
61 | |||
62 | if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) | ||
63 | dwc->dr_mode = USB_DR_MODE_OTG; | ||
64 | |||
65 | mode = dwc->dr_mode; | ||
66 | hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); | ||
67 | |||
68 | switch (hw_mode) { | ||
69 | case DWC3_GHWPARAMS0_MODE_GADGET: | ||
70 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) { | ||
71 | dev_err(dev, | ||
72 | "Controller does not support host mode.\n"); | ||
73 | return -EINVAL; | ||
74 | } | ||
75 | mode = USB_DR_MODE_PERIPHERAL; | ||
76 | break; | ||
77 | case DWC3_GHWPARAMS0_MODE_HOST: | ||
78 | if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) { | ||
79 | dev_err(dev, | ||
80 | "Controller does not support device mode.\n"); | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | mode = USB_DR_MODE_HOST; | ||
84 | break; | ||
85 | default: | ||
86 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) | ||
87 | mode = USB_DR_MODE_HOST; | ||
88 | else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) | ||
89 | mode = USB_DR_MODE_PERIPHERAL; | ||
90 | } | ||
91 | |||
92 | if (mode != dwc->dr_mode) { | ||
93 | dev_warn(dev, | ||
94 | "Configuration mismatch. dr_mode forced to %s\n", | ||
95 | mode == USB_DR_MODE_HOST ? "host" : "gadget"); | ||
96 | |||
97 | dwc->dr_mode = mode; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
52 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode) | 103 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode) |
53 | { | 104 | { |
54 | u32 reg; | 105 | u32 reg; |
@@ -448,6 +499,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
448 | if (dwc->dis_u3_susphy_quirk) | 499 | if (dwc->dis_u3_susphy_quirk) |
449 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; | 500 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; |
450 | 501 | ||
502 | if (dwc->dis_del_phy_power_chg_quirk) | ||
503 | reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE; | ||
504 | |||
451 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | 505 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); |
452 | 506 | ||
453 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 507 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
@@ -485,6 +539,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
485 | break; | 539 | break; |
486 | } | 540 | } |
487 | 541 | ||
542 | switch (dwc->hsphy_mode) { | ||
543 | case USBPHY_INTERFACE_MODE_UTMI: | ||
544 | reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK | | ||
545 | DWC3_GUSB2PHYCFG_USBTRDTIM_MASK); | ||
546 | reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) | | ||
547 | DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT); | ||
548 | break; | ||
549 | case USBPHY_INTERFACE_MODE_UTMIW: | ||
550 | reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK | | ||
551 | DWC3_GUSB2PHYCFG_USBTRDTIM_MASK); | ||
552 | reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) | | ||
553 | DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT); | ||
554 | break; | ||
555 | default: | ||
556 | break; | ||
557 | } | ||
558 | |||
488 | /* | 559 | /* |
489 | * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to | 560 | * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to |
490 | * '0' during coreConsultant configuration. So default value will | 561 | * '0' during coreConsultant configuration. So default value will |
@@ -500,6 +571,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc) | |||
500 | if (dwc->dis_enblslpm_quirk) | 571 | if (dwc->dis_enblslpm_quirk) |
501 | reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; | 572 | reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; |
502 | 573 | ||
574 | if (dwc->dis_u2_freeclk_exists_quirk) | ||
575 | reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS; | ||
576 | |||
503 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | 577 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
504 | 578 | ||
505 | return 0; | 579 | return 0; |
@@ -666,6 +740,32 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
666 | goto err4; | 740 | goto err4; |
667 | } | 741 | } |
668 | 742 | ||
743 | switch (dwc->dr_mode) { | ||
744 | case USB_DR_MODE_PERIPHERAL: | ||
745 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); | ||
746 | break; | ||
747 | case USB_DR_MODE_HOST: | ||
748 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); | ||
749 | break; | ||
750 | case USB_DR_MODE_OTG: | ||
751 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); | ||
752 | break; | ||
753 | default: | ||
754 | dev_warn(dwc->dev, "Unsupported mode %d\n", dwc->dr_mode); | ||
755 | break; | ||
756 | } | ||
757 | |||
758 | /* | ||
759 | * ENDXFER polling is available on version 3.10a and later of | ||
760 | * the DWC_usb3 controller. It is NOT available in the | ||
761 | * DWC_usb31 controller. | ||
762 | */ | ||
763 | if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { | ||
764 | reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); | ||
765 | reg |= DWC3_GUCTL2_RST_ACTBITLATER; | ||
766 | dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); | ||
767 | } | ||
768 | |||
669 | return 0; | 769 | return 0; |
670 | 770 | ||
671 | err4: | 771 | err4: |
@@ -763,7 +863,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) | |||
763 | 863 | ||
764 | switch (dwc->dr_mode) { | 864 | switch (dwc->dr_mode) { |
765 | case USB_DR_MODE_PERIPHERAL: | 865 | case USB_DR_MODE_PERIPHERAL: |
766 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); | ||
767 | ret = dwc3_gadget_init(dwc); | 866 | ret = dwc3_gadget_init(dwc); |
768 | if (ret) { | 867 | if (ret) { |
769 | if (ret != -EPROBE_DEFER) | 868 | if (ret != -EPROBE_DEFER) |
@@ -772,7 +871,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) | |||
772 | } | 871 | } |
773 | break; | 872 | break; |
774 | case USB_DR_MODE_HOST: | 873 | case USB_DR_MODE_HOST: |
775 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); | ||
776 | ret = dwc3_host_init(dwc); | 874 | ret = dwc3_host_init(dwc); |
777 | if (ret) { | 875 | if (ret) { |
778 | if (ret != -EPROBE_DEFER) | 876 | if (ret != -EPROBE_DEFER) |
@@ -781,7 +879,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) | |||
781 | } | 879 | } |
782 | break; | 880 | break; |
783 | case USB_DR_MODE_OTG: | 881 | case USB_DR_MODE_OTG: |
784 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); | ||
785 | ret = dwc3_host_init(dwc); | 882 | ret = dwc3_host_init(dwc); |
786 | if (ret) { | 883 | if (ret) { |
787 | if (ret != -EPROBE_DEFER) | 884 | if (ret != -EPROBE_DEFER) |
@@ -888,6 +985,7 @@ static int dwc3_probe(struct platform_device *pdev) | |||
888 | 985 | ||
889 | dwc->maximum_speed = usb_get_maximum_speed(dev); | 986 | dwc->maximum_speed = usb_get_maximum_speed(dev); |
890 | dwc->dr_mode = usb_get_dr_mode(dev); | 987 | dwc->dr_mode = usb_get_dr_mode(dev); |
988 | dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); | ||
891 | 989 | ||
892 | dwc->has_lpm_erratum = device_property_read_bool(dev, | 990 | dwc->has_lpm_erratum = device_property_read_bool(dev, |
893 | "snps,has-lpm-erratum"); | 991 | "snps,has-lpm-erratum"); |
@@ -924,6 +1022,10 @@ static int dwc3_probe(struct platform_device *pdev) | |||
924 | "snps,dis_enblslpm_quirk"); | 1022 | "snps,dis_enblslpm_quirk"); |
925 | dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, | 1023 | dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, |
926 | "snps,dis_rxdet_inp3_quirk"); | 1024 | "snps,dis_rxdet_inp3_quirk"); |
1025 | dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev, | ||
1026 | "snps,dis-u2-freeclk-exists-quirk"); | ||
1027 | dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, | ||
1028 | "snps,dis-del-phy-power-chg-quirk"); | ||
927 | 1029 | ||
928 | dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, | 1030 | dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, |
929 | "snps,tx_de_emphasis_quirk"); | 1031 | "snps,tx_de_emphasis_quirk"); |
@@ -972,17 +1074,9 @@ static int dwc3_probe(struct platform_device *pdev) | |||
972 | goto err2; | 1074 | goto err2; |
973 | } | 1075 | } |
974 | 1076 | ||
975 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST) && | 1077 | ret = dwc3_get_dr_mode(dwc); |
976 | (dwc->dr_mode == USB_DR_MODE_OTG || | 1078 | if (ret) |
977 | dwc->dr_mode == USB_DR_MODE_UNKNOWN)) | 1079 | goto err3; |
978 | dwc->dr_mode = USB_DR_MODE_HOST; | ||
979 | else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET) && | ||
980 | (dwc->dr_mode == USB_DR_MODE_OTG || | ||
981 | dwc->dr_mode == USB_DR_MODE_UNKNOWN)) | ||
982 | dwc->dr_mode = USB_DR_MODE_PERIPHERAL; | ||
983 | |||
984 | if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) | ||
985 | dwc->dr_mode = USB_DR_MODE_OTG; | ||
986 | 1080 | ||
987 | ret = dwc3_alloc_scratch_buffers(dwc); | 1081 | ret = dwc3_alloc_scratch_buffers(dwc); |
988 | if (ret) | 1082 | if (ret) |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 45d6de5107c7..6b60e42626a2 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -109,6 +109,7 @@ | |||
109 | #define DWC3_GPRTBIMAP_HS1 0xc184 | 109 | #define DWC3_GPRTBIMAP_HS1 0xc184 |
110 | #define DWC3_GPRTBIMAP_FS0 0xc188 | 110 | #define DWC3_GPRTBIMAP_FS0 0xc188 |
111 | #define DWC3_GPRTBIMAP_FS1 0xc18c | 111 | #define DWC3_GPRTBIMAP_FS1 0xc18c |
112 | #define DWC3_GUCTL2 0xc19c | ||
112 | 113 | ||
113 | #define DWC3_VER_NUMBER 0xc1a0 | 114 | #define DWC3_VER_NUMBER 0xc1a0 |
114 | #define DWC3_VER_TYPE 0xc1a4 | 115 | #define DWC3_VER_TYPE 0xc1a4 |
@@ -199,9 +200,18 @@ | |||
199 | 200 | ||
200 | /* Global USB2 PHY Configuration Register */ | 201 | /* Global USB2 PHY Configuration Register */ |
201 | #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) | 202 | #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) |
203 | #define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30) | ||
202 | #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) | 204 | #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) |
203 | #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4) | 205 | #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4) |
204 | #define DWC3_GUSB2PHYCFG_ENBLSLPM (1 << 8) | 206 | #define DWC3_GUSB2PHYCFG_ENBLSLPM (1 << 8) |
207 | #define DWC3_GUSB2PHYCFG_PHYIF(n) (n << 3) | ||
208 | #define DWC3_GUSB2PHYCFG_PHYIF_MASK DWC3_GUSB2PHYCFG_PHYIF(1) | ||
209 | #define DWC3_GUSB2PHYCFG_USBTRDTIM(n) (n << 10) | ||
210 | #define DWC3_GUSB2PHYCFG_USBTRDTIM_MASK DWC3_GUSB2PHYCFG_USBTRDTIM(0xf) | ||
211 | #define USBTRDTIM_UTMI_8_BIT 9 | ||
212 | #define USBTRDTIM_UTMI_16_BIT 5 | ||
213 | #define UTMI_PHYIF_16_BIT 1 | ||
214 | #define UTMI_PHYIF_8_BIT 0 | ||
205 | 215 | ||
206 | /* Global USB2 PHY Vendor Control Register */ | 216 | /* Global USB2 PHY Vendor Control Register */ |
207 | #define DWC3_GUSB2PHYACC_NEWREGREQ (1 << 25) | 217 | #define DWC3_GUSB2PHYACC_NEWREGREQ (1 << 25) |
@@ -235,7 +245,10 @@ | |||
235 | #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) | 245 | #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) |
236 | 246 | ||
237 | /* Global HWPARAMS0 Register */ | 247 | /* Global HWPARAMS0 Register */ |
238 | #define DWC3_GHWPARAMS0_USB3_MODE(n) ((n) & 0x3) | 248 | #define DWC3_GHWPARAMS0_MODE(n) ((n) & 0x3) |
249 | #define DWC3_GHWPARAMS0_MODE_GADGET 0 | ||
250 | #define DWC3_GHWPARAMS0_MODE_HOST 1 | ||
251 | #define DWC3_GHWPARAMS0_MODE_DRD 2 | ||
239 | #define DWC3_GHWPARAMS0_MBUS_TYPE(n) (((n) >> 3) & 0x7) | 252 | #define DWC3_GHWPARAMS0_MBUS_TYPE(n) (((n) >> 3) & 0x7) |
240 | #define DWC3_GHWPARAMS0_SBUS_TYPE(n) (((n) >> 6) & 0x3) | 253 | #define DWC3_GHWPARAMS0_SBUS_TYPE(n) (((n) >> 6) & 0x3) |
241 | #define DWC3_GHWPARAMS0_MDWIDTH(n) (((n) >> 8) & 0xff) | 254 | #define DWC3_GHWPARAMS0_MDWIDTH(n) (((n) >> 8) & 0xff) |
@@ -279,6 +292,9 @@ | |||
279 | #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) | 292 | #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) |
280 | #define DWC3_GFLADJ_30MHZ_MASK 0x3f | 293 | #define DWC3_GFLADJ_30MHZ_MASK 0x3f |
281 | 294 | ||
295 | /* Global User Control Register 2 */ | ||
296 | #define DWC3_GUCTL2_RST_ACTBITLATER (1 << 14) | ||
297 | |||
282 | /* Device Configuration Register */ | 298 | /* Device Configuration Register */ |
283 | #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) | 299 | #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) |
284 | #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) | 300 | #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) |
@@ -685,6 +701,8 @@ struct dwc3_hwparams { | |||
685 | * @request: struct usb_request to be transferred | 701 | * @request: struct usb_request to be transferred |
686 | * @list: a list_head used for request queueing | 702 | * @list: a list_head used for request queueing |
687 | * @dep: struct dwc3_ep owning this request | 703 | * @dep: struct dwc3_ep owning this request |
704 | * @sg: pointer to first incomplete sg | ||
705 | * @num_pending_sgs: counter to pending sgs | ||
688 | * @first_trb_index: index to first trb used by this request | 706 | * @first_trb_index: index to first trb used by this request |
689 | * @epnum: endpoint number to which this request refers | 707 | * @epnum: endpoint number to which this request refers |
690 | * @trb: pointer to struct dwc3_trb | 708 | * @trb: pointer to struct dwc3_trb |
@@ -697,7 +715,9 @@ struct dwc3_request { | |||
697 | struct usb_request request; | 715 | struct usb_request request; |
698 | struct list_head list; | 716 | struct list_head list; |
699 | struct dwc3_ep *dep; | 717 | struct dwc3_ep *dep; |
718 | struct scatterlist *sg; | ||
700 | 719 | ||
720 | unsigned num_pending_sgs; | ||
701 | u8 first_trb_index; | 721 | u8 first_trb_index; |
702 | u8 epnum; | 722 | u8 epnum; |
703 | struct dwc3_trb *trb; | 723 | struct dwc3_trb *trb; |
@@ -743,6 +763,9 @@ struct dwc3_scratchpad_array { | |||
743 | * @maximum_speed: maximum speed requested (mainly for testing purposes) | 763 | * @maximum_speed: maximum speed requested (mainly for testing purposes) |
744 | * @revision: revision register contents | 764 | * @revision: revision register contents |
745 | * @dr_mode: requested mode of operation | 765 | * @dr_mode: requested mode of operation |
766 | * @hsphy_mode: UTMI phy mode, one of following: | ||
767 | * - USBPHY_INTERFACE_MODE_UTMI | ||
768 | * - USBPHY_INTERFACE_MODE_UTMIW | ||
746 | * @usb2_phy: pointer to USB2 PHY | 769 | * @usb2_phy: pointer to USB2 PHY |
747 | * @usb3_phy: pointer to USB3 PHY | 770 | * @usb3_phy: pointer to USB3 PHY |
748 | * @usb2_generic_phy: pointer to USB2 PHY | 771 | * @usb2_generic_phy: pointer to USB2 PHY |
@@ -799,6 +822,11 @@ struct dwc3_scratchpad_array { | |||
799 | * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy | 822 | * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy |
800 | * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG, | 823 | * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG, |
801 | * disabling the suspend signal to the PHY. | 824 | * disabling the suspend signal to the PHY. |
825 | * @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists | ||
826 | * in GUSB2PHYCFG, specify that USB2 PHY doesn't | ||
827 | * provide a free-running PHY clock. | ||
828 | * @dis_del_phy_power_chg_quirk: set if we disable delay phy power | ||
829 | * change quirk. | ||
802 | * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk | 830 | * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk |
803 | * @tx_de_emphasis: Tx de-emphasis value | 831 | * @tx_de_emphasis: Tx de-emphasis value |
804 | * 0 - -6dB de-emphasis | 832 | * 0 - -6dB de-emphasis |
@@ -845,6 +873,7 @@ struct dwc3 { | |||
845 | size_t regs_size; | 873 | size_t regs_size; |
846 | 874 | ||
847 | enum usb_dr_mode dr_mode; | 875 | enum usb_dr_mode dr_mode; |
876 | enum usb_phy_interface hsphy_mode; | ||
848 | 877 | ||
849 | u32 fladj; | 878 | u32 fladj; |
850 | u32 irq_gadget; | 879 | u32 irq_gadget; |
@@ -880,6 +909,8 @@ struct dwc3 { | |||
880 | #define DWC3_REVISION_260A 0x5533260a | 909 | #define DWC3_REVISION_260A 0x5533260a |
881 | #define DWC3_REVISION_270A 0x5533270a | 910 | #define DWC3_REVISION_270A 0x5533270a |
882 | #define DWC3_REVISION_280A 0x5533280a | 911 | #define DWC3_REVISION_280A 0x5533280a |
912 | #define DWC3_REVISION_300A 0x5533300a | ||
913 | #define DWC3_REVISION_310A 0x5533310a | ||
883 | 914 | ||
884 | /* | 915 | /* |
885 | * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really | 916 | * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really |
@@ -942,6 +973,8 @@ struct dwc3 { | |||
942 | unsigned dis_u2_susphy_quirk:1; | 973 | unsigned dis_u2_susphy_quirk:1; |
943 | unsigned dis_enblslpm_quirk:1; | 974 | unsigned dis_enblslpm_quirk:1; |
944 | unsigned dis_rxdet_inp3_quirk:1; | 975 | unsigned dis_rxdet_inp3_quirk:1; |
976 | unsigned dis_u2_freeclk_exists_quirk:1; | ||
977 | unsigned dis_del_phy_power_chg_quirk:1; | ||
945 | 978 | ||
946 | unsigned tx_de_emphasis_quirk:1; | 979 | unsigned tx_de_emphasis_quirk:1; |
947 | unsigned tx_de_emphasis:2; | 980 | unsigned tx_de_emphasis:2; |
diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e56d59b19a0e..fe414e7a9c78 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c | |||
@@ -36,36 +36,25 @@ struct dwc3_of_simple { | |||
36 | int num_clocks; | 36 | int num_clocks; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static int dwc3_of_simple_probe(struct platform_device *pdev) | 39 | static int dwc3_of_simple_clk_init(struct dwc3_of_simple *simple, int count) |
40 | { | 40 | { |
41 | struct dwc3_of_simple *simple; | 41 | struct device *dev = simple->dev; |
42 | struct device *dev = &pdev->dev; | ||
43 | struct device_node *np = dev->of_node; | 42 | struct device_node *np = dev->of_node; |
44 | |||
45 | unsigned int count; | ||
46 | int ret; | ||
47 | int i; | 43 | int i; |
48 | 44 | ||
49 | simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL); | 45 | simple->num_clocks = count; |
50 | if (!simple) | ||
51 | return -ENOMEM; | ||
52 | 46 | ||
53 | count = of_clk_get_parent_count(np); | ||
54 | if (!count) | 47 | if (!count) |
55 | return -ENOENT; | 48 | return 0; |
56 | |||
57 | simple->num_clocks = count; | ||
58 | 49 | ||
59 | simple->clks = devm_kcalloc(dev, simple->num_clocks, | 50 | simple->clks = devm_kcalloc(dev, simple->num_clocks, |
60 | sizeof(struct clk *), GFP_KERNEL); | 51 | sizeof(struct clk *), GFP_KERNEL); |
61 | if (!simple->clks) | 52 | if (!simple->clks) |
62 | return -ENOMEM; | 53 | return -ENOMEM; |
63 | 54 | ||
64 | platform_set_drvdata(pdev, simple); | ||
65 | simple->dev = dev; | ||
66 | |||
67 | for (i = 0; i < simple->num_clocks; i++) { | 55 | for (i = 0; i < simple->num_clocks; i++) { |
68 | struct clk *clk; | 56 | struct clk *clk; |
57 | int ret; | ||
69 | 58 | ||
70 | clk = of_clk_get(np, i); | 59 | clk = of_clk_get(np, i); |
71 | if (IS_ERR(clk)) { | 60 | if (IS_ERR(clk)) { |
@@ -88,6 +77,29 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) | |||
88 | simple->clks[i] = clk; | 77 | simple->clks[i] = clk; |
89 | } | 78 | } |
90 | 79 | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int dwc3_of_simple_probe(struct platform_device *pdev) | ||
84 | { | ||
85 | struct dwc3_of_simple *simple; | ||
86 | struct device *dev = &pdev->dev; | ||
87 | struct device_node *np = dev->of_node; | ||
88 | |||
89 | int ret; | ||
90 | int i; | ||
91 | |||
92 | simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL); | ||
93 | if (!simple) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | platform_set_drvdata(pdev, simple); | ||
97 | simple->dev = dev; | ||
98 | |||
99 | ret = dwc3_of_simple_clk_init(simple, of_clk_get_parent_count(np)); | ||
100 | if (ret) | ||
101 | return ret; | ||
102 | |||
91 | ret = of_platform_populate(np, NULL, NULL, dev); | 103 | ret = of_platform_populate(np, NULL, NULL, dev); |
92 | if (ret) { | 104 | if (ret) { |
93 | for (i = 0; i < simple->num_clocks; i++) { | 105 | for (i = 0; i < simple->num_clocks; i++) { |
@@ -112,7 +124,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev) | |||
112 | int i; | 124 | int i; |
113 | 125 | ||
114 | for (i = 0; i < simple->num_clocks; i++) { | 126 | for (i = 0; i < simple->num_clocks; i++) { |
115 | clk_unprepare(simple->clks[i]); | 127 | clk_disable_unprepare(simple->clks[i]); |
116 | clk_put(simple->clks[i]); | 128 | clk_put(simple->clks[i]); |
117 | } | 129 | } |
118 | 130 | ||
@@ -162,7 +174,9 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { | |||
162 | 174 | ||
163 | static const struct of_device_id of_dwc3_simple_match[] = { | 175 | static const struct of_device_id of_dwc3_simple_match[] = { |
164 | { .compatible = "qcom,dwc3" }, | 176 | { .compatible = "qcom,dwc3" }, |
177 | { .compatible = "rockchip,rk3399-dwc3" }, | ||
165 | { .compatible = "xlnx,zynqmp-dwc3" }, | 178 | { .compatible = "xlnx,zynqmp-dwc3" }, |
179 | { .compatible = "cavium,octeon-7130-usb-uctl" }, | ||
166 | { /* Sentinel */ } | 180 | { /* Sentinel */ } |
167 | }; | 181 | }; |
168 | MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); | 182 | MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 122e64df2f4d..07cc8929f271 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -174,15 +174,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
174 | int status) | 174 | int status) |
175 | { | 175 | { |
176 | struct dwc3 *dwc = dep->dwc; | 176 | struct dwc3 *dwc = dep->dwc; |
177 | int i; | ||
178 | 177 | ||
179 | if (req->started) { | 178 | req->started = false; |
180 | i = 0; | ||
181 | do { | ||
182 | dwc3_ep_inc_deq(dep); | ||
183 | } while(++i < req->request.num_mapped_sgs); | ||
184 | req->started = false; | ||
185 | } | ||
186 | list_del(&req->list); | 179 | list_del(&req->list); |
187 | req->trb = NULL; | 180 | req->trb = NULL; |
188 | 181 | ||
@@ -348,7 +341,8 @@ static int dwc3_send_clear_stall_ep_cmd(struct dwc3_ep *dep) | |||
348 | * IN transfers due to a mishandled error condition. Synopsys | 341 | * IN transfers due to a mishandled error condition. Synopsys |
349 | * STAR 9000614252. | 342 | * STAR 9000614252. |
350 | */ | 343 | */ |
351 | if (dep->direction && (dwc->revision >= DWC3_REVISION_260A)) | 344 | if (dep->direction && (dwc->revision >= DWC3_REVISION_260A) && |
345 | (dwc->gadget.speed >= USB_SPEED_SUPER)) | ||
352 | cmd |= DWC3_DEPCMD_CLEARPENDIN; | 346 | cmd |= DWC3_DEPCMD_CLEARPENDIN; |
353 | 347 | ||
354 | memset(¶ms, 0, sizeof(params)); | 348 | memset(¶ms, 0, sizeof(params)); |
@@ -490,7 +484,8 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
490 | params.param0 |= DWC3_DEPCFG_ACTION_INIT; | 484 | params.param0 |= DWC3_DEPCFG_ACTION_INIT; |
491 | } | 485 | } |
492 | 486 | ||
493 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN; | 487 | if (usb_endpoint_xfer_control(desc)) |
488 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN; | ||
494 | 489 | ||
495 | if (dep->number <= 1 || usb_endpoint_xfer_isoc(desc)) | 490 | if (dep->number <= 1 || usb_endpoint_xfer_isoc(desc)) |
496 | params.param1 |= DWC3_DEPCFG_XFER_NOT_READY_EN; | 491 | params.param1 |= DWC3_DEPCFG_XFER_NOT_READY_EN; |
@@ -764,6 +759,8 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, | |||
764 | kfree(req); | 759 | kfree(req); |
765 | } | 760 | } |
766 | 761 | ||
762 | static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep); | ||
763 | |||
767 | /** | 764 | /** |
768 | * dwc3_prepare_one_trb - setup one TRB from one request | 765 | * dwc3_prepare_one_trb - setup one TRB from one request |
769 | * @dep: endpoint for which this request is prepared | 766 | * @dep: endpoint for which this request is prepared |
@@ -771,15 +768,13 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, | |||
771 | */ | 768 | */ |
772 | static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | 769 | static void dwc3_prepare_one_trb(struct dwc3_ep *dep, |
773 | struct dwc3_request *req, dma_addr_t dma, | 770 | struct dwc3_request *req, dma_addr_t dma, |
774 | unsigned length, unsigned last, unsigned chain, unsigned node) | 771 | unsigned length, unsigned chain, unsigned node) |
775 | { | 772 | { |
776 | struct dwc3_trb *trb; | 773 | struct dwc3_trb *trb; |
777 | 774 | ||
778 | dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s", | 775 | dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s", |
779 | dep->name, req, (unsigned long long) dma, | 776 | dep->name, req, (unsigned long long) dma, |
780 | length, last ? " last" : "", | 777 | length, chain ? " chain" : ""); |
781 | chain ? " chain" : ""); | ||
782 | |||
783 | 778 | ||
784 | trb = &dep->trb_pool[dep->trb_enqueue]; | 779 | trb = &dep->trb_pool[dep->trb_enqueue]; |
785 | 780 | ||
@@ -826,12 +821,10 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
826 | /* always enable Continue on Short Packet */ | 821 | /* always enable Continue on Short Packet */ |
827 | trb->ctrl |= DWC3_TRB_CTRL_CSP; | 822 | trb->ctrl |= DWC3_TRB_CTRL_CSP; |
828 | 823 | ||
829 | if (!req->request.no_interrupt && !chain) | 824 | if ((!req->request.no_interrupt && !chain) || |
825 | (dwc3_calc_trbs_left(dep) == 0)) | ||
830 | trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; | 826 | trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; |
831 | 827 | ||
832 | if (last && !usb_endpoint_xfer_isoc(dep->endpoint.desc)) | ||
833 | trb->ctrl |= DWC3_TRB_CTRL_LST; | ||
834 | |||
835 | if (chain) | 828 | if (chain) |
836 | trb->ctrl |= DWC3_TRB_CTRL_CHN; | 829 | trb->ctrl |= DWC3_TRB_CTRL_CHN; |
837 | 830 | ||
@@ -856,12 +849,12 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
856 | */ | 849 | */ |
857 | static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) | 850 | static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) |
858 | { | 851 | { |
859 | if (!index) | 852 | u8 tmp = index; |
860 | index = DWC3_TRB_NUM - 2; | ||
861 | else | ||
862 | index = dep->trb_enqueue - 1; | ||
863 | 853 | ||
864 | return &dep->trb_pool[index]; | 854 | if (!tmp) |
855 | tmp = DWC3_TRB_NUM - 1; | ||
856 | |||
857 | return &dep->trb_pool[tmp - 1]; | ||
865 | } | 858 | } |
866 | 859 | ||
867 | static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) | 860 | static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) |
@@ -894,65 +887,42 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) | |||
894 | } | 887 | } |
895 | 888 | ||
896 | static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, | 889 | static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, |
897 | struct dwc3_request *req, unsigned int trbs_left, | 890 | struct dwc3_request *req) |
898 | unsigned int more_coming) | ||
899 | { | 891 | { |
900 | struct usb_request *request = &req->request; | 892 | struct scatterlist *sg = req->sg; |
901 | struct scatterlist *sg = request->sg; | ||
902 | struct scatterlist *s; | 893 | struct scatterlist *s; |
903 | unsigned int last = false; | ||
904 | unsigned int length; | 894 | unsigned int length; |
905 | dma_addr_t dma; | 895 | dma_addr_t dma; |
906 | int i; | 896 | int i; |
907 | 897 | ||
908 | for_each_sg(sg, s, request->num_mapped_sgs, i) { | 898 | for_each_sg(sg, s, req->num_pending_sgs, i) { |
909 | unsigned chain = true; | 899 | unsigned chain = true; |
910 | 900 | ||
911 | length = sg_dma_len(s); | 901 | length = sg_dma_len(s); |
912 | dma = sg_dma_address(s); | 902 | dma = sg_dma_address(s); |
913 | 903 | ||
914 | if (sg_is_last(s)) { | 904 | if (sg_is_last(s)) |
915 | if (usb_endpoint_xfer_int(dep->endpoint.desc) || | ||
916 | !more_coming) | ||
917 | last = true; | ||
918 | |||
919 | chain = false; | ||
920 | } | ||
921 | |||
922 | if (!trbs_left--) | ||
923 | last = true; | ||
924 | |||
925 | if (last) | ||
926 | chain = false; | 905 | chain = false; |
927 | 906 | ||
928 | dwc3_prepare_one_trb(dep, req, dma, length, | 907 | dwc3_prepare_one_trb(dep, req, dma, length, |
929 | last, chain, i); | 908 | chain, i); |
930 | 909 | ||
931 | if (last) | 910 | if (!dwc3_calc_trbs_left(dep)) |
932 | break; | 911 | break; |
933 | } | 912 | } |
934 | } | 913 | } |
935 | 914 | ||
936 | static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | 915 | static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, |
937 | struct dwc3_request *req, unsigned int trbs_left, | 916 | struct dwc3_request *req) |
938 | unsigned int more_coming) | ||
939 | { | 917 | { |
940 | unsigned int last = false; | ||
941 | unsigned int length; | 918 | unsigned int length; |
942 | dma_addr_t dma; | 919 | dma_addr_t dma; |
943 | 920 | ||
944 | dma = req->request.dma; | 921 | dma = req->request.dma; |
945 | length = req->request.length; | 922 | length = req->request.length; |
946 | 923 | ||
947 | if (!trbs_left) | ||
948 | last = true; | ||
949 | |||
950 | /* Is this the last request? */ | ||
951 | if (usb_endpoint_xfer_int(dep->endpoint.desc) || !more_coming) | ||
952 | last = true; | ||
953 | |||
954 | dwc3_prepare_one_trb(dep, req, dma, length, | 924 | dwc3_prepare_one_trb(dep, req, dma, length, |
955 | last, false, 0); | 925 | false, 0); |
956 | } | 926 | } |
957 | 927 | ||
958 | /* | 928 | /* |
@@ -966,26 +936,19 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, | |||
966 | static void dwc3_prepare_trbs(struct dwc3_ep *dep) | 936 | static void dwc3_prepare_trbs(struct dwc3_ep *dep) |
967 | { | 937 | { |
968 | struct dwc3_request *req, *n; | 938 | struct dwc3_request *req, *n; |
969 | unsigned int more_coming; | ||
970 | u32 trbs_left; | ||
971 | 939 | ||
972 | BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); | 940 | BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); |
973 | 941 | ||
974 | trbs_left = dwc3_calc_trbs_left(dep); | 942 | if (!dwc3_calc_trbs_left(dep)) |
975 | if (!trbs_left) | ||
976 | return; | 943 | return; |
977 | 944 | ||
978 | more_coming = dep->allocated_requests - dep->queued_requests; | ||
979 | |||
980 | list_for_each_entry_safe(req, n, &dep->pending_list, list) { | 945 | list_for_each_entry_safe(req, n, &dep->pending_list, list) { |
981 | if (req->request.num_mapped_sgs > 0) | 946 | if (req->num_pending_sgs > 0) |
982 | dwc3_prepare_one_trb_sg(dep, req, trbs_left--, | 947 | dwc3_prepare_one_trb_sg(dep, req); |
983 | more_coming); | ||
984 | else | 948 | else |
985 | dwc3_prepare_one_trb_linear(dep, req, trbs_left--, | 949 | dwc3_prepare_one_trb_linear(dep, req); |
986 | more_coming); | ||
987 | 950 | ||
988 | if (!trbs_left) | 951 | if (!dwc3_calc_trbs_left(dep)) |
989 | return; | 952 | return; |
990 | } | 953 | } |
991 | } | 954 | } |
@@ -1101,93 +1064,29 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1101 | 1064 | ||
1102 | trace_dwc3_ep_queue(req); | 1065 | trace_dwc3_ep_queue(req); |
1103 | 1066 | ||
1104 | /* | ||
1105 | * We only add to our list of requests now and | ||
1106 | * start consuming the list once we get XferNotReady | ||
1107 | * IRQ. | ||
1108 | * | ||
1109 | * That way, we avoid doing anything that we don't need | ||
1110 | * to do now and defer it until the point we receive a | ||
1111 | * particular token from the Host side. | ||
1112 | * | ||
1113 | * This will also avoid Host cancelling URBs due to too | ||
1114 | * many NAKs. | ||
1115 | */ | ||
1116 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, | 1067 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
1117 | dep->direction); | 1068 | dep->direction); |
1118 | if (ret) | 1069 | if (ret) |
1119 | return ret; | 1070 | return ret; |
1120 | 1071 | ||
1121 | list_add_tail(&req->list, &dep->pending_list); | 1072 | req->sg = req->request.sg; |
1122 | 1073 | req->num_pending_sgs = req->request.num_mapped_sgs; | |
1123 | /* | ||
1124 | * If there are no pending requests and the endpoint isn't already | ||
1125 | * busy, we will just start the request straight away. | ||
1126 | * | ||
1127 | * This will save one IRQ (XFER_NOT_READY) and possibly make it a | ||
1128 | * little bit faster. | ||
1129 | */ | ||
1130 | if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
1131 | !usb_endpoint_xfer_int(dep->endpoint.desc)) { | ||
1132 | ret = __dwc3_gadget_kick_transfer(dep, 0); | ||
1133 | goto out; | ||
1134 | } | ||
1135 | |||
1136 | /* | ||
1137 | * There are a few special cases: | ||
1138 | * | ||
1139 | * 1. XferNotReady with empty list of requests. We need to kick the | ||
1140 | * transfer here in that situation, otherwise we will be NAKing | ||
1141 | * forever. If we get XferNotReady before gadget driver has a | ||
1142 | * chance to queue a request, we will ACK the IRQ but won't be | ||
1143 | * able to receive the data until the next request is queued. | ||
1144 | * The following code is handling exactly that. | ||
1145 | * | ||
1146 | */ | ||
1147 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | ||
1148 | /* | ||
1149 | * If xfernotready is already elapsed and it is a case | ||
1150 | * of isoc transfer, then issue END TRANSFER, so that | ||
1151 | * you can receive xfernotready again and can have | ||
1152 | * notion of current microframe. | ||
1153 | */ | ||
1154 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1155 | if (list_empty(&dep->started_list)) { | ||
1156 | dwc3_stop_active_transfer(dwc, dep->number, true); | ||
1157 | dep->flags = DWC3_EP_ENABLED; | ||
1158 | } | ||
1159 | return 0; | ||
1160 | } | ||
1161 | |||
1162 | ret = __dwc3_gadget_kick_transfer(dep, 0); | ||
1163 | if (!ret) | ||
1164 | dep->flags &= ~DWC3_EP_PENDING_REQUEST; | ||
1165 | 1074 | ||
1166 | goto out; | 1075 | list_add_tail(&req->list, &dep->pending_list); |
1167 | } | ||
1168 | 1076 | ||
1169 | /* | ||
1170 | * 2. XferInProgress on Isoc EP with an active transfer. We need to | ||
1171 | * kick the transfer here after queuing a request, otherwise the | ||
1172 | * core may not see the modified TRB(s). | ||
1173 | */ | ||
1174 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | 1077 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && |
1175 | (dep->flags & DWC3_EP_BUSY) && | 1078 | dep->flags & DWC3_EP_PENDING_REQUEST) { |
1176 | !(dep->flags & DWC3_EP_MISSED_ISOC)) { | 1079 | if (list_empty(&dep->started_list)) { |
1177 | WARN_ON_ONCE(!dep->resource_index); | 1080 | dwc3_stop_active_transfer(dwc, dep->number, true); |
1178 | ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index); | 1081 | dep->flags = DWC3_EP_ENABLED; |
1179 | goto out; | 1082 | } |
1083 | return 0; | ||
1180 | } | 1084 | } |
1181 | 1085 | ||
1182 | /* | 1086 | if (!dwc3_calc_trbs_left(dep)) |
1183 | * 4. Stream Capable Bulk Endpoints. We need to start the transfer | 1087 | return 0; |
1184 | * right away, otherwise host will not know we have streams to be | ||
1185 | * handled. | ||
1186 | */ | ||
1187 | if (dep->stream_capable) | ||
1188 | ret = __dwc3_gadget_kick_transfer(dep, 0); | ||
1189 | 1088 | ||
1190 | out: | 1089 | ret = __dwc3_gadget_kick_transfer(dep, 0); |
1191 | if (ret && ret != -EBUSY) | 1090 | if (ret && ret != -EBUSY) |
1192 | dwc3_trace(trace_dwc3_gadget, | 1091 | dwc3_trace(trace_dwc3_gadget, |
1193 | "%s: failed to kick transfers", | 1092 | "%s: failed to kick transfers", |
@@ -1963,6 +1862,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1963 | unsigned int trb_status; | 1862 | unsigned int trb_status; |
1964 | 1863 | ||
1965 | dep->queued_requests--; | 1864 | dep->queued_requests--; |
1865 | dwc3_ep_inc_deq(dep); | ||
1966 | trace_dwc3_complete_trb(dep, trb); | 1866 | trace_dwc3_complete_trb(dep, trb); |
1967 | 1867 | ||
1968 | /* | 1868 | /* |
@@ -1982,6 +1882,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1982 | return 1; | 1882 | return 1; |
1983 | 1883 | ||
1984 | count = trb->size & DWC3_TRB_SIZE_MASK; | 1884 | count = trb->size & DWC3_TRB_SIZE_MASK; |
1885 | req->request.actual += count; | ||
1985 | 1886 | ||
1986 | if (dep->direction) { | 1887 | if (dep->direction) { |
1987 | if (count) { | 1888 | if (count) { |
@@ -2021,48 +1922,51 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
2021 | 1922 | ||
2022 | if (s_pkt && !chain) | 1923 | if (s_pkt && !chain) |
2023 | return 1; | 1924 | return 1; |
2024 | if ((event->status & DEPEVT_STATUS_LST) && | 1925 | |
2025 | (trb->ctrl & (DWC3_TRB_CTRL_LST | | ||
2026 | DWC3_TRB_CTRL_HWO))) | ||
2027 | return 1; | ||
2028 | if ((event->status & DEPEVT_STATUS_IOC) && | 1926 | if ((event->status & DEPEVT_STATUS_IOC) && |
2029 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 1927 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) |
2030 | return 1; | 1928 | return 1; |
1929 | |||
2031 | return 0; | 1930 | return 0; |
2032 | } | 1931 | } |
2033 | 1932 | ||
2034 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | 1933 | static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, |
2035 | const struct dwc3_event_depevt *event, int status) | 1934 | const struct dwc3_event_depevt *event, int status) |
2036 | { | 1935 | { |
2037 | struct dwc3_request *req; | 1936 | struct dwc3_request *req, *n; |
2038 | struct dwc3_trb *trb; | 1937 | struct dwc3_trb *trb; |
2039 | unsigned int slot; | 1938 | bool ioc = false; |
2040 | unsigned int i; | ||
2041 | int count = 0; | ||
2042 | int ret; | 1939 | int ret; |
2043 | 1940 | ||
2044 | do { | 1941 | list_for_each_entry_safe(req, n, &dep->started_list, list) { |
1942 | unsigned length; | ||
1943 | unsigned actual; | ||
2045 | int chain; | 1944 | int chain; |
2046 | 1945 | ||
2047 | req = next_request(&dep->started_list); | 1946 | length = req->request.length; |
2048 | if (WARN_ON_ONCE(!req)) | 1947 | chain = req->num_pending_sgs > 0; |
2049 | return 1; | 1948 | if (chain) { |
2050 | 1949 | struct scatterlist *sg = req->sg; | |
2051 | chain = req->request.num_mapped_sgs > 0; | 1950 | struct scatterlist *s; |
2052 | i = 0; | 1951 | unsigned int pending = req->num_pending_sgs; |
2053 | do { | 1952 | unsigned int i; |
2054 | slot = req->first_trb_index + i; | ||
2055 | if (slot == DWC3_TRB_NUM - 1) | ||
2056 | slot++; | ||
2057 | slot %= DWC3_TRB_NUM; | ||
2058 | trb = &dep->trb_pool[slot]; | ||
2059 | count += trb->size & DWC3_TRB_SIZE_MASK; | ||
2060 | 1953 | ||
1954 | for_each_sg(sg, s, pending, i) { | ||
1955 | trb = &dep->trb_pool[dep->trb_dequeue]; | ||
1956 | |||
1957 | req->sg = sg_next(s); | ||
1958 | req->num_pending_sgs--; | ||
1959 | |||
1960 | ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, | ||
1961 | event, status, chain); | ||
1962 | if (ret) | ||
1963 | break; | ||
1964 | } | ||
1965 | } else { | ||
1966 | trb = &dep->trb_pool[dep->trb_dequeue]; | ||
2061 | ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, | 1967 | ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, |
2062 | event, status, chain); | 1968 | event, status, chain); |
2063 | if (ret) | 1969 | } |
2064 | break; | ||
2065 | } while (++i < req->request.num_mapped_sgs); | ||
2066 | 1970 | ||
2067 | /* | 1971 | /* |
2068 | * We assume here we will always receive the entire data block | 1972 | * We assume here we will always receive the entire data block |
@@ -2071,12 +1975,21 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
2071 | * should receive and we simply bounce the request back to the | 1975 | * should receive and we simply bounce the request back to the |
2072 | * gadget driver for further processing. | 1976 | * gadget driver for further processing. |
2073 | */ | 1977 | */ |
2074 | req->request.actual += req->request.length - count; | 1978 | actual = length - req->request.actual; |
1979 | req->request.actual = actual; | ||
1980 | |||
1981 | if (ret && chain && (actual < length) && req->num_pending_sgs) | ||
1982 | return __dwc3_gadget_kick_transfer(dep, 0); | ||
1983 | |||
2075 | dwc3_gadget_giveback(dep, req, status); | 1984 | dwc3_gadget_giveback(dep, req, status); |
2076 | 1985 | ||
2077 | if (ret) | 1986 | if (ret) { |
1987 | if ((event->status & DEPEVT_STATUS_IOC) && | ||
1988 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | ||
1989 | ioc = true; | ||
2078 | break; | 1990 | break; |
2079 | } while (1); | 1991 | } |
1992 | } | ||
2080 | 1993 | ||
2081 | /* | 1994 | /* |
2082 | * Our endpoint might get disabled by another thread during | 1995 | * Our endpoint might get disabled by another thread during |
@@ -2103,10 +2016,9 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
2103 | return 1; | 2016 | return 1; |
2104 | } | 2017 | } |
2105 | 2018 | ||
2106 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) | 2019 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && ioc) |
2107 | if ((event->status & DEPEVT_STATUS_IOC) && | 2020 | return 0; |
2108 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 2021 | |
2109 | return 0; | ||
2110 | return 1; | 2022 | return 1; |
2111 | } | 2023 | } |
2112 | 2024 | ||
@@ -2322,6 +2234,18 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) | |||
2322 | * | 2234 | * |
2323 | * - Issue EndTransfer WITH CMDIOC bit set | 2235 | * - Issue EndTransfer WITH CMDIOC bit set |
2324 | * - Wait 100us | 2236 | * - Wait 100us |
2237 | * | ||
2238 | * As of IP version 3.10a of the DWC_usb3 IP, the controller | ||
2239 | * supports a mode to work around the above limitation. The | ||
2240 | * software can poll the CMDACT bit in the DEPCMD register | ||
2241 | * after issuing a EndTransfer command. This mode is enabled | ||
2242 | * by writing GUCTL2[14]. This polling is already done in the | ||
2243 | * dwc3_send_gadget_ep_cmd() function so if the mode is | ||
2244 | * enabled, the EndTransfer command will have completed upon | ||
2245 | * returning from this function and we don't need to delay for | ||
2246 | * 100us. | ||
2247 | * | ||
2248 | * This mode is NOT available on the DWC_usb31 IP. | ||
2325 | */ | 2249 | */ |
2326 | 2250 | ||
2327 | cmd = DWC3_DEPCMD_ENDTRANSFER; | 2251 | cmd = DWC3_DEPCMD_ENDTRANSFER; |
@@ -2333,7 +2257,9 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) | |||
2333 | WARN_ON_ONCE(ret); | 2257 | WARN_ON_ONCE(ret); |
2334 | dep->resource_index = 0; | 2258 | dep->resource_index = 0; |
2335 | dep->flags &= ~DWC3_EP_BUSY; | 2259 | dep->flags &= ~DWC3_EP_BUSY; |
2336 | udelay(100); | 2260 | |
2261 | if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) | ||
2262 | udelay(100); | ||
2337 | } | 2263 | } |
2338 | 2264 | ||
2339 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) | 2265 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) |
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c index ec004c6d76f2..bd86f84f3790 100644 --- a/drivers/usb/dwc3/ulpi.c +++ b/drivers/usb/dwc3/ulpi.c | |||
@@ -35,9 +35,9 @@ static int dwc3_ulpi_busyloop(struct dwc3 *dwc) | |||
35 | return -ETIMEDOUT; | 35 | return -ETIMEDOUT; |
36 | } | 36 | } |
37 | 37 | ||
38 | static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr) | 38 | static int dwc3_ulpi_read(struct device *dev, u8 addr) |
39 | { | 39 | { |
40 | struct dwc3 *dwc = dev_get_drvdata(ops->dev); | 40 | struct dwc3 *dwc = dev_get_drvdata(dev); |
41 | u32 reg; | 41 | u32 reg; |
42 | int ret; | 42 | int ret; |
43 | 43 | ||
@@ -53,9 +53,9 @@ static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr) | |||
53 | return DWC3_GUSB2PHYACC_DATA(reg); | 53 | return DWC3_GUSB2PHYACC_DATA(reg); |
54 | } | 54 | } |
55 | 55 | ||
56 | static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val) | 56 | static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val) |
57 | { | 57 | { |
58 | struct dwc3 *dwc = dev_get_drvdata(ops->dev); | 58 | struct dwc3 *dwc = dev_get_drvdata(dev); |
59 | u32 reg; | 59 | u32 reg; |
60 | 60 | ||
61 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | 61 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
@@ -65,7 +65,7 @@ static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val) | |||
65 | return dwc3_ulpi_busyloop(dwc); | 65 | return dwc3_ulpi_busyloop(dwc); |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct ulpi_ops dwc3_ulpi_ops = { | 68 | static const struct ulpi_ops dwc3_ulpi_ops = { |
69 | .read = dwc3_ulpi_read, | 69 | .read = dwc3_ulpi_read, |
70 | .write = dwc3_ulpi_write, | 70 | .write = dwc3_ulpi_write, |
71 | }; | 71 | }; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3c3f31ceece7..8ad203296079 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -209,25 +209,6 @@ config USB_F_PRINTER | |||
209 | config USB_F_TCM | 209 | config USB_F_TCM |
210 | tristate | 210 | tristate |
211 | 211 | ||
212 | choice | ||
213 | tristate "USB Gadget Drivers" | ||
214 | default USB_ETH | ||
215 | help | ||
216 | A Linux "Gadget Driver" talks to the USB Peripheral Controller | ||
217 | driver through the abstract "gadget" API. Some other operating | ||
218 | systems call these "client" drivers, of which "class drivers" | ||
219 | are a subset (implementing a USB device class specification). | ||
220 | A gadget driver implements one or more USB functions using | ||
221 | the peripheral hardware. | ||
222 | |||
223 | Gadget drivers are hardware-neutral, or "platform independent", | ||
224 | except that they sometimes must understand quirks or limitations | ||
225 | of the particular controllers they work with. For example, when | ||
226 | a controller doesn't support alternate configurations or provide | ||
227 | enough of the right types of endpoints, the gadget driver might | ||
228 | not be able work with that controller, or might need to implement | ||
229 | a less common variant of a device class protocol. | ||
230 | |||
231 | # this first set of drivers all depend on bulk-capable hardware. | 212 | # this first set of drivers all depend on bulk-capable hardware. |
232 | 213 | ||
233 | config USB_CONFIGFS | 214 | config USB_CONFIGFS |
@@ -439,6 +420,7 @@ config USB_CONFIGFS_F_HID | |||
439 | config USB_CONFIGFS_F_UVC | 420 | config USB_CONFIGFS_F_UVC |
440 | bool "USB Webcam function" | 421 | bool "USB Webcam function" |
441 | depends on USB_CONFIGFS | 422 | depends on USB_CONFIGFS |
423 | depends on VIDEO_V4L2 | ||
442 | depends on VIDEO_DEV | 424 | depends on VIDEO_DEV |
443 | select VIDEOBUF2_VMALLOC | 425 | select VIDEOBUF2_VMALLOC |
444 | select USB_F_UVC | 426 | select USB_F_UVC |
@@ -475,6 +457,25 @@ config USB_CONFIGFS_F_TCM | |||
475 | Both protocols can work on USB2.0 and USB3.0. | 457 | Both protocols can work on USB2.0 and USB3.0. |
476 | UAS utilizes the USB 3.0 feature called streams support. | 458 | UAS utilizes the USB 3.0 feature called streams support. |
477 | 459 | ||
460 | choice | ||
461 | tristate "USB Gadget Drivers" | ||
462 | default USB_ETH | ||
463 | help | ||
464 | A Linux "Gadget Driver" talks to the USB Peripheral Controller | ||
465 | driver through the abstract "gadget" API. Some other operating | ||
466 | systems call these "client" drivers, of which "class drivers" | ||
467 | are a subset (implementing a USB device class specification). | ||
468 | A gadget driver implements one or more USB functions using | ||
469 | the peripheral hardware. | ||
470 | |||
471 | Gadget drivers are hardware-neutral, or "platform independent", | ||
472 | except that they sometimes must understand quirks or limitations | ||
473 | of the particular controllers they work with. For example, when | ||
474 | a controller doesn't support alternate configurations or provide | ||
475 | enough of the right types of endpoints, the gadget driver might | ||
476 | not be able work with that controller, or might need to implement | ||
477 | a less common variant of a device class protocol. | ||
478 | |||
478 | source "drivers/usb/gadget/legacy/Kconfig" | 479 | source "drivers/usb/gadget/legacy/Kconfig" |
479 | 480 | ||
480 | endchoice | 481 | endchoice |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5ebe6af7976e..32176f779861 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1893,17 +1893,21 @@ unknown: | |||
1893 | /* functions always handle their interfaces and endpoints... | 1893 | /* functions always handle their interfaces and endpoints... |
1894 | * punt other recipients (other, WUSB, ...) to the current | 1894 | * punt other recipients (other, WUSB, ...) to the current |
1895 | * configuration code. | 1895 | * configuration code. |
1896 | * | ||
1897 | * REVISIT it could make sense to let the composite device | ||
1898 | * take such requests too, if that's ever needed: to work | ||
1899 | * in config 0, etc. | ||
1900 | */ | 1896 | */ |
1901 | if (cdev->config) { | 1897 | if (cdev->config) { |
1902 | list_for_each_entry(f, &cdev->config->functions, list) | 1898 | list_for_each_entry(f, &cdev->config->functions, list) |
1903 | if (f->req_match && f->req_match(f, ctrl)) | 1899 | if (f->req_match && |
1900 | f->req_match(f, ctrl, false)) | ||
1904 | goto try_fun_setup; | 1901 | goto try_fun_setup; |
1905 | f = NULL; | 1902 | } else { |
1903 | struct usb_configuration *c; | ||
1904 | list_for_each_entry(c, &cdev->configs, list) | ||
1905 | list_for_each_entry(f, &c->functions, list) | ||
1906 | if (f->req_match && | ||
1907 | f->req_match(f, ctrl, true)) | ||
1908 | goto try_fun_setup; | ||
1906 | } | 1909 | } |
1910 | f = NULL; | ||
1907 | 1911 | ||
1908 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 1912 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
1909 | case USB_RECIP_INTERFACE: | 1913 | case USB_RECIP_INTERFACE: |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index f9237fe2be05..3984787f8e97 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
@@ -1211,8 +1211,9 @@ static void purge_configs_funcs(struct gadget_info *gi) | |||
1211 | 1211 | ||
1212 | list_move_tail(&f->list, &cfg->func_list); | 1212 | list_move_tail(&f->list, &cfg->func_list); |
1213 | if (f->unbind) { | 1213 | if (f->unbind) { |
1214 | dev_err(&gi->cdev.gadget->dev, "unbind function" | 1214 | dev_dbg(&gi->cdev.gadget->dev, |
1215 | " '%s'/%p\n", f->name, f); | 1215 | "unbind function '%s'/%p\n", |
1216 | f->name, f); | ||
1216 | f->unbind(c, f); | 1217 | f->unbind(c, f); |
1217 | } | 1218 | } |
1218 | } | 1219 | } |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 5c8429f23a89..0aeed85bb5cb 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -98,6 +98,9 @@ static int ffs_func_set_alt(struct usb_function *, unsigned, unsigned); | |||
98 | static void ffs_func_disable(struct usb_function *); | 98 | static void ffs_func_disable(struct usb_function *); |
99 | static int ffs_func_setup(struct usb_function *, | 99 | static int ffs_func_setup(struct usb_function *, |
100 | const struct usb_ctrlrequest *); | 100 | const struct usb_ctrlrequest *); |
101 | static bool ffs_func_req_match(struct usb_function *, | ||
102 | const struct usb_ctrlrequest *, | ||
103 | bool config0); | ||
101 | static void ffs_func_suspend(struct usb_function *); | 104 | static void ffs_func_suspend(struct usb_function *); |
102 | static void ffs_func_resume(struct usb_function *); | 105 | static void ffs_func_resume(struct usb_function *); |
103 | 106 | ||
@@ -2243,7 +2246,9 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, | |||
2243 | FUNCTIONFS_HAS_SS_DESC | | 2246 | FUNCTIONFS_HAS_SS_DESC | |
2244 | FUNCTIONFS_HAS_MS_OS_DESC | | 2247 | FUNCTIONFS_HAS_MS_OS_DESC | |
2245 | FUNCTIONFS_VIRTUAL_ADDR | | 2248 | FUNCTIONFS_VIRTUAL_ADDR | |
2246 | FUNCTIONFS_EVENTFD)) { | 2249 | FUNCTIONFS_EVENTFD | |
2250 | FUNCTIONFS_ALL_CTRL_RECIP | | ||
2251 | FUNCTIONFS_CONFIG0_SETUP)) { | ||
2247 | ret = -ENOSYS; | 2252 | ret = -ENOSYS; |
2248 | goto error; | 2253 | goto error; |
2249 | } | 2254 | } |
@@ -3094,8 +3099,9 @@ static int ffs_func_setup(struct usb_function *f, | |||
3094 | * handle them. All other either handled by composite or | 3099 | * handle them. All other either handled by composite or |
3095 | * passed to usb_configuration->setup() (if one is set). No | 3100 | * passed to usb_configuration->setup() (if one is set). No |
3096 | * matter, we will handle requests directed to endpoint here | 3101 | * matter, we will handle requests directed to endpoint here |
3097 | * as well (as it's straightforward) but what to do with any | 3102 | * as well (as it's straightforward). Other request recipient |
3098 | * other request? | 3103 | * types are only handled when the user flag FUNCTIONFS_ALL_CTRL_RECIP |
3104 | * is being used. | ||
3099 | */ | 3105 | */ |
3100 | if (ffs->state != FFS_ACTIVE) | 3106 | if (ffs->state != FFS_ACTIVE) |
3101 | return -ENODEV; | 3107 | return -ENODEV; |
@@ -3116,7 +3122,10 @@ static int ffs_func_setup(struct usb_function *f, | |||
3116 | break; | 3122 | break; |
3117 | 3123 | ||
3118 | default: | 3124 | default: |
3119 | return -EOPNOTSUPP; | 3125 | if (func->ffs->user_flags & FUNCTIONFS_ALL_CTRL_RECIP) |
3126 | ret = le16_to_cpu(creq->wIndex); | ||
3127 | else | ||
3128 | return -EOPNOTSUPP; | ||
3120 | } | 3129 | } |
3121 | 3130 | ||
3122 | spin_lock_irqsave(&ffs->ev.waitq.lock, flags); | 3131 | spin_lock_irqsave(&ffs->ev.waitq.lock, flags); |
@@ -3128,6 +3137,28 @@ static int ffs_func_setup(struct usb_function *f, | |||
3128 | return 0; | 3137 | return 0; |
3129 | } | 3138 | } |
3130 | 3139 | ||
3140 | static bool ffs_func_req_match(struct usb_function *f, | ||
3141 | const struct usb_ctrlrequest *creq, | ||
3142 | bool config0) | ||
3143 | { | ||
3144 | struct ffs_function *func = ffs_func_from_usb(f); | ||
3145 | |||
3146 | if (config0 && !(func->ffs->user_flags & FUNCTIONFS_CONFIG0_SETUP)) | ||
3147 | return false; | ||
3148 | |||
3149 | switch (creq->bRequestType & USB_RECIP_MASK) { | ||
3150 | case USB_RECIP_INTERFACE: | ||
3151 | return ffs_func_revmap_intf(func, | ||
3152 | le16_to_cpu(creq->wIndex) >= 0); | ||
3153 | case USB_RECIP_ENDPOINT: | ||
3154 | return ffs_func_revmap_ep(func, | ||
3155 | le16_to_cpu(creq->wIndex) >= 0); | ||
3156 | default: | ||
3157 | return (bool) (func->ffs->user_flags & | ||
3158 | FUNCTIONFS_ALL_CTRL_RECIP); | ||
3159 | } | ||
3160 | } | ||
3161 | |||
3131 | static void ffs_func_suspend(struct usb_function *f) | 3162 | static void ffs_func_suspend(struct usb_function *f) |
3132 | { | 3163 | { |
3133 | ENTER(); | 3164 | ENTER(); |
@@ -3378,6 +3409,7 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi) | |||
3378 | func->function.set_alt = ffs_func_set_alt; | 3409 | func->function.set_alt = ffs_func_set_alt; |
3379 | func->function.disable = ffs_func_disable; | 3410 | func->function.disable = ffs_func_disable; |
3380 | func->function.setup = ffs_func_setup; | 3411 | func->function.setup = ffs_func_setup; |
3412 | func->function.req_match = ffs_func_req_match; | ||
3381 | func->function.suspend = ffs_func_suspend; | 3413 | func->function.suspend = ffs_func_suspend; |
3382 | func->function.resume = ffs_func_resume; | 3414 | func->function.resume = ffs_func_resume; |
3383 | func->function.free_func = ffs_free; | 3415 | func->function.free_func = ffs_free; |
@@ -3470,6 +3502,11 @@ static void _ffs_free_dev(struct ffs_dev *dev) | |||
3470 | list_del(&dev->entry); | 3502 | list_del(&dev->entry); |
3471 | if (dev->name_allocated) | 3503 | if (dev->name_allocated) |
3472 | kfree(dev->name); | 3504 | kfree(dev->name); |
3505 | |||
3506 | /* Clear the private_data pointer to stop incorrect dev access */ | ||
3507 | if (dev->ffs_data) | ||
3508 | dev->ffs_data->private_data = NULL; | ||
3509 | |||
3473 | kfree(dev); | 3510 | kfree(dev); |
3474 | if (list_empty(&ffs_devices)) | 3511 | if (list_empty(&ffs_devices)) |
3475 | functionfs_cleanup(); | 3512 | functionfs_cleanup(); |
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 51980c50546d..e2966f87c860 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -365,7 +365,7 @@ static int f_hidg_open(struct inode *inode, struct file *fd) | |||
365 | static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, | 365 | static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, |
366 | unsigned length) | 366 | unsigned length) |
367 | { | 367 | { |
368 | return alloc_ep_req(ep, length, length); | 368 | return alloc_ep_req(ep, length); |
369 | } | 369 | } |
370 | 370 | ||
371 | static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) | 371 | static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -617,14 +617,10 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
617 | 617 | ||
618 | /* preallocate request and buffer */ | 618 | /* preallocate request and buffer */ |
619 | status = -ENOMEM; | 619 | status = -ENOMEM; |
620 | hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); | 620 | hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length); |
621 | if (!hidg->req) | 621 | if (!hidg->req) |
622 | goto fail; | 622 | goto fail; |
623 | 623 | ||
624 | hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); | ||
625 | if (!hidg->req->buf) | ||
626 | goto fail; | ||
627 | |||
628 | /* set descriptor dynamic values */ | 624 | /* set descriptor dynamic values */ |
629 | hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; | 625 | hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; |
630 | hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; | 626 | hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; |
@@ -677,11 +673,8 @@ fail_free_descs: | |||
677 | usb_free_all_descriptors(f); | 673 | usb_free_all_descriptors(f); |
678 | fail: | 674 | fail: |
679 | ERROR(f->config->cdev, "hidg_bind FAILED\n"); | 675 | ERROR(f->config->cdev, "hidg_bind FAILED\n"); |
680 | if (hidg->req != NULL) { | 676 | if (hidg->req != NULL) |
681 | kfree(hidg->req->buf); | 677 | free_ep_req(hidg->in_ep, hidg->req); |
682 | if (hidg->in_ep != NULL) | ||
683 | usb_ep_free_request(hidg->in_ep, hidg->req); | ||
684 | } | ||
685 | 678 | ||
686 | return status; | 679 | return status; |
687 | } | 680 | } |
@@ -809,11 +802,21 @@ end: | |||
809 | 802 | ||
810 | CONFIGFS_ATTR(f_hid_opts_, report_desc); | 803 | CONFIGFS_ATTR(f_hid_opts_, report_desc); |
811 | 804 | ||
805 | static ssize_t f_hid_opts_dev_show(struct config_item *item, char *page) | ||
806 | { | ||
807 | struct f_hid_opts *opts = to_f_hid_opts(item); | ||
808 | |||
809 | return sprintf(page, "%d:%d\n", major, opts->minor); | ||
810 | } | ||
811 | |||
812 | CONFIGFS_ATTR_RO(f_hid_opts_, dev); | ||
813 | |||
812 | static struct configfs_attribute *hid_attrs[] = { | 814 | static struct configfs_attribute *hid_attrs[] = { |
813 | &f_hid_opts_attr_subclass, | 815 | &f_hid_opts_attr_subclass, |
814 | &f_hid_opts_attr_protocol, | 816 | &f_hid_opts_attr_protocol, |
815 | &f_hid_opts_attr_report_length, | 817 | &f_hid_opts_attr_report_length, |
816 | &f_hid_opts_attr_report_desc, | 818 | &f_hid_opts_attr_report_desc, |
819 | &f_hid_opts_attr_dev, | ||
817 | NULL, | 820 | NULL, |
818 | }; | 821 | }; |
819 | 822 | ||
@@ -910,8 +913,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
910 | 913 | ||
911 | /* disable/free request and end point */ | 914 | /* disable/free request and end point */ |
912 | usb_ep_disable(hidg->in_ep); | 915 | usb_ep_disable(hidg->in_ep); |
913 | kfree(hidg->req->buf); | 916 | free_ep_req(hidg->in_ep, hidg->req); |
914 | usb_ep_free_request(hidg->in_ep, hidg->req); | ||
915 | 917 | ||
916 | usb_free_all_descriptors(f); | 918 | usb_free_all_descriptors(f); |
917 | } | 919 | } |
diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 3a9f8f9c77bd..e70093835e14 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c | |||
@@ -308,9 +308,7 @@ static void disable_loopback(struct f_loopback *loop) | |||
308 | 308 | ||
309 | static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) | 309 | static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) |
310 | { | 310 | { |
311 | struct f_loopback *loop = ep->driver_data; | 311 | return alloc_ep_req(ep, len); |
312 | |||
313 | return alloc_ep_req(ep, len, loop->buflen); | ||
314 | } | 312 | } |
315 | 313 | ||
316 | static int alloc_requests(struct usb_composite_dev *cdev, | 314 | static int alloc_requests(struct usb_composite_dev *cdev, |
@@ -333,7 +331,7 @@ static int alloc_requests(struct usb_composite_dev *cdev, | |||
333 | if (!in_req) | 331 | if (!in_req) |
334 | goto fail; | 332 | goto fail; |
335 | 333 | ||
336 | out_req = lb_alloc_ep_req(loop->out_ep, 0); | 334 | out_req = lb_alloc_ep_req(loop->out_ep, loop->buflen); |
337 | if (!out_req) | 335 | if (!out_req) |
338 | goto fail_in; | 336 | goto fail_in; |
339 | 337 | ||
@@ -593,13 +591,9 @@ DECLARE_USB_FUNCTION(Loopback, loopback_alloc_instance, loopback_alloc); | |||
593 | 591 | ||
594 | int __init lb_modinit(void) | 592 | int __init lb_modinit(void) |
595 | { | 593 | { |
596 | int ret; | 594 | return usb_function_register(&Loopbackusb_func); |
597 | |||
598 | ret = usb_function_register(&Loopbackusb_func); | ||
599 | if (ret) | ||
600 | return ret; | ||
601 | return ret; | ||
602 | } | 595 | } |
596 | |||
603 | void __exit lb_modexit(void) | 597 | void __exit lb_modexit(void) |
604 | { | 598 | { |
605 | usb_function_unregister(&Loopbackusb_func); | 599 | usb_function_unregister(&Loopbackusb_func); |
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 2505117e88e8..8f3659b65f53 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
@@ -311,11 +311,7 @@ struct fsg_common { | |||
311 | /* Gadget's private data. */ | 311 | /* Gadget's private data. */ |
312 | void *private_data; | 312 | void *private_data; |
313 | 313 | ||
314 | /* | 314 | char inquiry_string[INQUIRY_STRING_LEN]; |
315 | * Vendor (8 chars), product (16 chars), release (4 | ||
316 | * hexadecimal digits) and NUL byte | ||
317 | */ | ||
318 | char inquiry_string[8 + 16 + 4 + 1]; | ||
319 | 315 | ||
320 | struct kref ref; | 316 | struct kref ref; |
321 | }; | 317 | }; |
@@ -1107,7 +1103,12 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) | |||
1107 | buf[5] = 0; /* No special options */ | 1103 | buf[5] = 0; /* No special options */ |
1108 | buf[6] = 0; | 1104 | buf[6] = 0; |
1109 | buf[7] = 0; | 1105 | buf[7] = 0; |
1110 | memcpy(buf + 8, common->inquiry_string, sizeof common->inquiry_string); | 1106 | if (curlun->inquiry_string[0]) |
1107 | memcpy(buf + 8, curlun->inquiry_string, | ||
1108 | sizeof(curlun->inquiry_string)); | ||
1109 | else | ||
1110 | memcpy(buf + 8, common->inquiry_string, | ||
1111 | sizeof(common->inquiry_string)); | ||
1111 | return 36; | 1112 | return 36; |
1112 | } | 1113 | } |
1113 | 1114 | ||
@@ -3209,12 +3210,27 @@ static ssize_t fsg_lun_opts_nofua_store(struct config_item *item, | |||
3209 | 3210 | ||
3210 | CONFIGFS_ATTR(fsg_lun_opts_, nofua); | 3211 | CONFIGFS_ATTR(fsg_lun_opts_, nofua); |
3211 | 3212 | ||
3213 | static ssize_t fsg_lun_opts_inquiry_string_show(struct config_item *item, | ||
3214 | char *page) | ||
3215 | { | ||
3216 | return fsg_show_inquiry_string(to_fsg_lun_opts(item)->lun, page); | ||
3217 | } | ||
3218 | |||
3219 | static ssize_t fsg_lun_opts_inquiry_string_store(struct config_item *item, | ||
3220 | const char *page, size_t len) | ||
3221 | { | ||
3222 | return fsg_store_inquiry_string(to_fsg_lun_opts(item)->lun, page, len); | ||
3223 | } | ||
3224 | |||
3225 | CONFIGFS_ATTR(fsg_lun_opts_, inquiry_string); | ||
3226 | |||
3212 | static struct configfs_attribute *fsg_lun_attrs[] = { | 3227 | static struct configfs_attribute *fsg_lun_attrs[] = { |
3213 | &fsg_lun_opts_attr_file, | 3228 | &fsg_lun_opts_attr_file, |
3214 | &fsg_lun_opts_attr_ro, | 3229 | &fsg_lun_opts_attr_ro, |
3215 | &fsg_lun_opts_attr_removable, | 3230 | &fsg_lun_opts_attr_removable, |
3216 | &fsg_lun_opts_attr_cdrom, | 3231 | &fsg_lun_opts_attr_cdrom, |
3217 | &fsg_lun_opts_attr_nofua, | 3232 | &fsg_lun_opts_attr_nofua, |
3233 | &fsg_lun_opts_attr_inquiry_string, | ||
3218 | NULL, | 3234 | NULL, |
3219 | }; | 3235 | }; |
3220 | 3236 | ||
diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index b6a9918eaefb..d3902313b8ac 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h | |||
@@ -100,6 +100,7 @@ struct fsg_lun_config { | |||
100 | char removable; | 100 | char removable; |
101 | char cdrom; | 101 | char cdrom; |
102 | char nofua; | 102 | char nofua; |
103 | char inquiry_string[INQUIRY_STRING_LEN]; | ||
103 | }; | 104 | }; |
104 | 105 | ||
105 | struct fsg_config { | 106 | struct fsg_config { |
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 58fc199a18ec..a5719f271bf0 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
@@ -51,6 +51,19 @@ static const char f_midi_longname[] = "MIDI Gadget"; | |||
51 | */ | 51 | */ |
52 | #define MAX_PORTS 16 | 52 | #define MAX_PORTS 16 |
53 | 53 | ||
54 | /* MIDI message states */ | ||
55 | enum { | ||
56 | STATE_INITIAL = 0, /* pseudo state */ | ||
57 | STATE_1PARAM, | ||
58 | STATE_2PARAM_1, | ||
59 | STATE_2PARAM_2, | ||
60 | STATE_SYSEX_0, | ||
61 | STATE_SYSEX_1, | ||
62 | STATE_SYSEX_2, | ||
63 | STATE_REAL_TIME, | ||
64 | STATE_FINISHED, /* pseudo state */ | ||
65 | }; | ||
66 | |||
54 | /* | 67 | /* |
55 | * This is a gadget, and the IN/OUT naming is from the host's perspective. | 68 | * This is a gadget, and the IN/OUT naming is from the host's perspective. |
56 | * USB -> OUT endpoint -> rawmidi | 69 | * USB -> OUT endpoint -> rawmidi |
@@ -61,13 +74,6 @@ struct gmidi_in_port { | |||
61 | int active; | 74 | int active; |
62 | uint8_t cable; | 75 | uint8_t cable; |
63 | uint8_t state; | 76 | uint8_t state; |
64 | #define STATE_UNKNOWN 0 | ||
65 | #define STATE_1PARAM 1 | ||
66 | #define STATE_2PARAM_1 2 | ||
67 | #define STATE_2PARAM_2 3 | ||
68 | #define STATE_SYSEX_0 4 | ||
69 | #define STATE_SYSEX_1 5 | ||
70 | #define STATE_SYSEX_2 6 | ||
71 | uint8_t data[2]; | 77 | uint8_t data[2]; |
72 | }; | 78 | }; |
73 | 79 | ||
@@ -205,7 +211,7 @@ static struct usb_gadget_strings *midi_strings[] = { | |||
205 | static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, | 211 | static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, |
206 | unsigned length) | 212 | unsigned length) |
207 | { | 213 | { |
208 | return alloc_ep_req(ep, length, length); | 214 | return alloc_ep_req(ep, length); |
209 | } | 215 | } |
210 | 216 | ||
211 | static const uint8_t f_midi_cin_length[] = { | 217 | static const uint8_t f_midi_cin_length[] = { |
@@ -299,6 +305,19 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req) | |||
299 | } | 305 | } |
300 | } | 306 | } |
301 | 307 | ||
308 | static void f_midi_drop_out_substreams(struct f_midi *midi) | ||
309 | { | ||
310 | unsigned int i; | ||
311 | |||
312 | for (i = 0; i < midi->in_ports; i++) { | ||
313 | struct gmidi_in_port *port = midi->in_ports_array + i; | ||
314 | struct snd_rawmidi_substream *substream = port->substream; | ||
315 | |||
316 | if (port->active && substream) | ||
317 | snd_rawmidi_drop_output(substream); | ||
318 | } | ||
319 | } | ||
320 | |||
302 | static int f_midi_start_ep(struct f_midi *midi, | 321 | static int f_midi_start_ep(struct f_midi *midi, |
303 | struct usb_function *f, | 322 | struct usb_function *f, |
304 | struct usb_ep *ep) | 323 | struct usb_ep *ep) |
@@ -360,9 +379,8 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
360 | /* allocate a bunch of read buffers and queue them all at once. */ | 379 | /* allocate a bunch of read buffers and queue them all at once. */ |
361 | for (i = 0; i < midi->qlen && err == 0; i++) { | 380 | for (i = 0; i < midi->qlen && err == 0; i++) { |
362 | struct usb_request *req = | 381 | struct usb_request *req = |
363 | midi_alloc_ep_req(midi->out_ep, | 382 | midi_alloc_ep_req(midi->out_ep, midi->buflen); |
364 | max_t(unsigned, midi->buflen, | 383 | |
365 | bulk_out_desc.wMaxPacketSize)); | ||
366 | if (req == NULL) | 384 | if (req == NULL) |
367 | return -ENOMEM; | 385 | return -ENOMEM; |
368 | 386 | ||
@@ -397,6 +415,8 @@ static void f_midi_disable(struct usb_function *f) | |||
397 | /* release IN requests */ | 415 | /* release IN requests */ |
398 | while (kfifo_get(&midi->in_req_fifo, &req)) | 416 | while (kfifo_get(&midi->in_req_fifo, &req)) |
399 | free_ep_req(midi->in_ep, req); | 417 | free_ep_req(midi->in_ep, req); |
418 | |||
419 | f_midi_drop_out_substreams(midi); | ||
400 | } | 420 | } |
401 | 421 | ||
402 | static int f_midi_snd_free(struct snd_device *device) | 422 | static int f_midi_snd_free(struct snd_device *device) |
@@ -404,130 +424,166 @@ static int f_midi_snd_free(struct snd_device *device) | |||
404 | return 0; | 424 | return 0; |
405 | } | 425 | } |
406 | 426 | ||
407 | static void f_midi_transmit_packet(struct usb_request *req, uint8_t p0, | ||
408 | uint8_t p1, uint8_t p2, uint8_t p3) | ||
409 | { | ||
410 | unsigned length = req->length; | ||
411 | u8 *buf = (u8 *)req->buf + length; | ||
412 | |||
413 | buf[0] = p0; | ||
414 | buf[1] = p1; | ||
415 | buf[2] = p2; | ||
416 | buf[3] = p3; | ||
417 | req->length = length + 4; | ||
418 | } | ||
419 | |||
420 | /* | 427 | /* |
421 | * Converts MIDI commands to USB MIDI packets. | 428 | * Converts MIDI commands to USB MIDI packets. |
422 | */ | 429 | */ |
423 | static void f_midi_transmit_byte(struct usb_request *req, | 430 | static void f_midi_transmit_byte(struct usb_request *req, |
424 | struct gmidi_in_port *port, uint8_t b) | 431 | struct gmidi_in_port *port, uint8_t b) |
425 | { | 432 | { |
426 | uint8_t p0 = port->cable << 4; | 433 | uint8_t p[4] = { port->cable << 4, 0, 0, 0 }; |
434 | uint8_t next_state = STATE_INITIAL; | ||
435 | |||
436 | switch (b) { | ||
437 | case 0xf8 ... 0xff: | ||
438 | /* System Real-Time Messages */ | ||
439 | p[0] |= 0x0f; | ||
440 | p[1] = b; | ||
441 | next_state = port->state; | ||
442 | port->state = STATE_REAL_TIME; | ||
443 | break; | ||
427 | 444 | ||
428 | if (b >= 0xf8) { | 445 | case 0xf7: |
429 | f_midi_transmit_packet(req, p0 | 0x0f, b, 0, 0); | 446 | /* End of SysEx */ |
430 | } else if (b >= 0xf0) { | 447 | switch (port->state) { |
448 | case STATE_SYSEX_0: | ||
449 | p[0] |= 0x05; | ||
450 | p[1] = 0xf7; | ||
451 | next_state = STATE_FINISHED; | ||
452 | break; | ||
453 | case STATE_SYSEX_1: | ||
454 | p[0] |= 0x06; | ||
455 | p[1] = port->data[0]; | ||
456 | p[2] = 0xf7; | ||
457 | next_state = STATE_FINISHED; | ||
458 | break; | ||
459 | case STATE_SYSEX_2: | ||
460 | p[0] |= 0x07; | ||
461 | p[1] = port->data[0]; | ||
462 | p[2] = port->data[1]; | ||
463 | p[3] = 0xf7; | ||
464 | next_state = STATE_FINISHED; | ||
465 | break; | ||
466 | default: | ||
467 | /* Ignore byte */ | ||
468 | next_state = port->state; | ||
469 | port->state = STATE_INITIAL; | ||
470 | } | ||
471 | break; | ||
472 | |||
473 | case 0xf0 ... 0xf6: | ||
474 | /* System Common Messages */ | ||
475 | port->data[0] = port->data[1] = 0; | ||
476 | port->state = STATE_INITIAL; | ||
431 | switch (b) { | 477 | switch (b) { |
432 | case 0xf0: | 478 | case 0xf0: |
433 | port->data[0] = b; | 479 | port->data[0] = b; |
434 | port->state = STATE_SYSEX_1; | 480 | port->data[1] = 0; |
481 | next_state = STATE_SYSEX_1; | ||
435 | break; | 482 | break; |
436 | case 0xf1: | 483 | case 0xf1: |
437 | case 0xf3: | 484 | case 0xf3: |
438 | port->data[0] = b; | 485 | port->data[0] = b; |
439 | port->state = STATE_1PARAM; | 486 | next_state = STATE_1PARAM; |
440 | break; | 487 | break; |
441 | case 0xf2: | 488 | case 0xf2: |
442 | port->data[0] = b; | 489 | port->data[0] = b; |
443 | port->state = STATE_2PARAM_1; | 490 | next_state = STATE_2PARAM_1; |
444 | break; | 491 | break; |
445 | case 0xf4: | 492 | case 0xf4: |
446 | case 0xf5: | 493 | case 0xf5: |
447 | port->state = STATE_UNKNOWN; | 494 | next_state = STATE_INITIAL; |
448 | break; | 495 | break; |
449 | case 0xf6: | 496 | case 0xf6: |
450 | f_midi_transmit_packet(req, p0 | 0x05, 0xf6, 0, 0); | 497 | p[0] |= 0x05; |
451 | port->state = STATE_UNKNOWN; | 498 | p[1] = 0xf6; |
452 | break; | 499 | next_state = STATE_FINISHED; |
453 | case 0xf7: | ||
454 | switch (port->state) { | ||
455 | case STATE_SYSEX_0: | ||
456 | f_midi_transmit_packet(req, | ||
457 | p0 | 0x05, 0xf7, 0, 0); | ||
458 | break; | ||
459 | case STATE_SYSEX_1: | ||
460 | f_midi_transmit_packet(req, | ||
461 | p0 | 0x06, port->data[0], 0xf7, 0); | ||
462 | break; | ||
463 | case STATE_SYSEX_2: | ||
464 | f_midi_transmit_packet(req, | ||
465 | p0 | 0x07, port->data[0], | ||
466 | port->data[1], 0xf7); | ||
467 | break; | ||
468 | } | ||
469 | port->state = STATE_UNKNOWN; | ||
470 | break; | 500 | break; |
471 | } | 501 | } |
472 | } else if (b >= 0x80) { | 502 | break; |
503 | |||
504 | case 0x80 ... 0xef: | ||
505 | /* | ||
506 | * Channel Voice Messages, Channel Mode Messages | ||
507 | * and Control Change Messages. | ||
508 | */ | ||
473 | port->data[0] = b; | 509 | port->data[0] = b; |
510 | port->data[1] = 0; | ||
511 | port->state = STATE_INITIAL; | ||
474 | if (b >= 0xc0 && b <= 0xdf) | 512 | if (b >= 0xc0 && b <= 0xdf) |
475 | port->state = STATE_1PARAM; | 513 | next_state = STATE_1PARAM; |
476 | else | 514 | else |
477 | port->state = STATE_2PARAM_1; | 515 | next_state = STATE_2PARAM_1; |
478 | } else { /* b < 0x80 */ | 516 | break; |
517 | |||
518 | case 0x00 ... 0x7f: | ||
519 | /* Message parameters */ | ||
479 | switch (port->state) { | 520 | switch (port->state) { |
480 | case STATE_1PARAM: | 521 | case STATE_1PARAM: |
481 | if (port->data[0] < 0xf0) { | 522 | if (port->data[0] < 0xf0) |
482 | p0 |= port->data[0] >> 4; | 523 | p[0] |= port->data[0] >> 4; |
483 | } else { | 524 | else |
484 | p0 |= 0x02; | 525 | p[0] |= 0x02; |
485 | port->state = STATE_UNKNOWN; | 526 | |
486 | } | 527 | p[1] = port->data[0]; |
487 | f_midi_transmit_packet(req, p0, port->data[0], b, 0); | 528 | p[2] = b; |
529 | /* This is to allow Running State Messages */ | ||
530 | next_state = STATE_1PARAM; | ||
488 | break; | 531 | break; |
489 | case STATE_2PARAM_1: | 532 | case STATE_2PARAM_1: |
490 | port->data[1] = b; | 533 | port->data[1] = b; |
491 | port->state = STATE_2PARAM_2; | 534 | next_state = STATE_2PARAM_2; |
492 | break; | 535 | break; |
493 | case STATE_2PARAM_2: | 536 | case STATE_2PARAM_2: |
494 | if (port->data[0] < 0xf0) { | 537 | if (port->data[0] < 0xf0) |
495 | p0 |= port->data[0] >> 4; | 538 | p[0] |= port->data[0] >> 4; |
496 | port->state = STATE_2PARAM_1; | 539 | else |
497 | } else { | 540 | p[0] |= 0x03; |
498 | p0 |= 0x03; | 541 | |
499 | port->state = STATE_UNKNOWN; | 542 | p[1] = port->data[0]; |
500 | } | 543 | p[2] = port->data[1]; |
501 | f_midi_transmit_packet(req, | 544 | p[3] = b; |
502 | p0, port->data[0], port->data[1], b); | 545 | /* This is to allow Running State Messages */ |
546 | next_state = STATE_2PARAM_1; | ||
503 | break; | 547 | break; |
504 | case STATE_SYSEX_0: | 548 | case STATE_SYSEX_0: |
505 | port->data[0] = b; | 549 | port->data[0] = b; |
506 | port->state = STATE_SYSEX_1; | 550 | next_state = STATE_SYSEX_1; |
507 | break; | 551 | break; |
508 | case STATE_SYSEX_1: | 552 | case STATE_SYSEX_1: |
509 | port->data[1] = b; | 553 | port->data[1] = b; |
510 | port->state = STATE_SYSEX_2; | 554 | next_state = STATE_SYSEX_2; |
511 | break; | 555 | break; |
512 | case STATE_SYSEX_2: | 556 | case STATE_SYSEX_2: |
513 | f_midi_transmit_packet(req, | 557 | p[0] |= 0x04; |
514 | p0 | 0x04, port->data[0], port->data[1], b); | 558 | p[1] = port->data[0]; |
515 | port->state = STATE_SYSEX_0; | 559 | p[2] = port->data[1]; |
560 | p[3] = b; | ||
561 | next_state = STATE_SYSEX_0; | ||
516 | break; | 562 | break; |
517 | } | 563 | } |
564 | break; | ||
518 | } | 565 | } |
519 | } | ||
520 | 566 | ||
521 | static void f_midi_drop_out_substreams(struct f_midi *midi) | 567 | /* States where we have to write into the USB request */ |
522 | { | 568 | if (next_state == STATE_FINISHED || |
523 | unsigned int i; | 569 | port->state == STATE_SYSEX_2 || |
570 | port->state == STATE_1PARAM || | ||
571 | port->state == STATE_2PARAM_2 || | ||
572 | port->state == STATE_REAL_TIME) { | ||
524 | 573 | ||
525 | for (i = 0; i < midi->in_ports; i++) { | 574 | unsigned int length = req->length; |
526 | struct gmidi_in_port *port = midi->in_ports_array + i; | 575 | u8 *buf = (u8 *)req->buf + length; |
527 | struct snd_rawmidi_substream *substream = port->substream; | 576 | |
528 | if (port->active && substream) | 577 | memcpy(buf, p, sizeof(p)); |
529 | snd_rawmidi_drop_output(substream); | 578 | req->length = length + sizeof(p); |
579 | |||
580 | if (next_state == STATE_FINISHED) { | ||
581 | next_state = STATE_INITIAL; | ||
582 | port->data[0] = port->data[1] = 0; | ||
583 | } | ||
530 | } | 584 | } |
585 | |||
586 | port->state = next_state; | ||
531 | } | 587 | } |
532 | 588 | ||
533 | static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep) | 589 | static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep) |
@@ -642,7 +698,7 @@ static int f_midi_in_open(struct snd_rawmidi_substream *substream) | |||
642 | VDBG(midi, "%s()\n", __func__); | 698 | VDBG(midi, "%s()\n", __func__); |
643 | port = midi->in_ports_array + substream->number; | 699 | port = midi->in_ports_array + substream->number; |
644 | port->substream = substream; | 700 | port->substream = substream; |
645 | port->state = STATE_UNKNOWN; | 701 | port->state = STATE_INITIAL; |
646 | return 0; | 702 | return 0; |
647 | } | 703 | } |
648 | 704 | ||
@@ -1123,7 +1179,7 @@ static struct usb_function_instance *f_midi_alloc_inst(void) | |||
1123 | opts->func_inst.free_func_inst = f_midi_free_inst; | 1179 | opts->func_inst.free_func_inst = f_midi_free_inst; |
1124 | opts->index = SNDRV_DEFAULT_IDX1; | 1180 | opts->index = SNDRV_DEFAULT_IDX1; |
1125 | opts->id = SNDRV_DEFAULT_STR1; | 1181 | opts->id = SNDRV_DEFAULT_STR1; |
1126 | opts->buflen = 256; | 1182 | opts->buflen = 512; |
1127 | opts->qlen = 32; | 1183 | opts->qlen = 32; |
1128 | opts->in_ports = 1; | 1184 | opts->in_ports = 1; |
1129 | opts->out_ports = 1; | 1185 | opts->out_ports = 1; |
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 97f0a9bc84df..639603722709 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c | |||
@@ -90,7 +90,9 @@ static inline struct f_ncm *func_to_ncm(struct usb_function *f) | |||
90 | /* peak (theoretical) bulk transfer rate in bits-per-second */ | 90 | /* peak (theoretical) bulk transfer rate in bits-per-second */ |
91 | static inline unsigned ncm_bitrate(struct usb_gadget *g) | 91 | static inline unsigned ncm_bitrate(struct usb_gadget *g) |
92 | { | 92 | { |
93 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | 93 | if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) |
94 | return 13 * 1024 * 8 * 1000 * 8; | ||
95 | else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
94 | return 13 * 512 * 8 * 1000 * 8; | 96 | return 13 * 512 * 8 * 1000 * 8; |
95 | else | 97 | else |
96 | return 19 * 64 * 1 * 1000 * 8; | 98 | return 19 * 64 * 1 * 1000 * 8; |
@@ -333,6 +335,76 @@ static struct usb_descriptor_header *ncm_hs_function[] = { | |||
333 | NULL, | 335 | NULL, |
334 | }; | 336 | }; |
335 | 337 | ||
338 | |||
339 | /* super speed support: */ | ||
340 | |||
341 | static struct usb_endpoint_descriptor ss_ncm_notify_desc = { | ||
342 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
343 | .bDescriptorType = USB_DT_ENDPOINT, | ||
344 | |||
345 | .bEndpointAddress = USB_DIR_IN, | ||
346 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
347 | .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), | ||
348 | .bInterval = USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS) | ||
349 | }; | ||
350 | |||
351 | static struct usb_ss_ep_comp_descriptor ss_ncm_notify_comp_desc = { | ||
352 | .bLength = sizeof(ss_ncm_notify_comp_desc), | ||
353 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
354 | |||
355 | /* the following 3 values can be tweaked if necessary */ | ||
356 | /* .bMaxBurst = 0, */ | ||
357 | /* .bmAttributes = 0, */ | ||
358 | .wBytesPerInterval = cpu_to_le16(NCM_STATUS_BYTECOUNT), | ||
359 | }; | ||
360 | |||
361 | static struct usb_endpoint_descriptor ss_ncm_in_desc = { | ||
362 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
363 | .bDescriptorType = USB_DT_ENDPOINT, | ||
364 | |||
365 | .bEndpointAddress = USB_DIR_IN, | ||
366 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
367 | .wMaxPacketSize = cpu_to_le16(1024), | ||
368 | }; | ||
369 | |||
370 | static struct usb_endpoint_descriptor ss_ncm_out_desc = { | ||
371 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
372 | .bDescriptorType = USB_DT_ENDPOINT, | ||
373 | |||
374 | .bEndpointAddress = USB_DIR_OUT, | ||
375 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
376 | .wMaxPacketSize = cpu_to_le16(1024), | ||
377 | }; | ||
378 | |||
379 | static struct usb_ss_ep_comp_descriptor ss_ncm_bulk_comp_desc = { | ||
380 | .bLength = sizeof(ss_ncm_bulk_comp_desc), | ||
381 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
382 | |||
383 | /* the following 2 values can be tweaked if necessary */ | ||
384 | /* .bMaxBurst = 0, */ | ||
385 | /* .bmAttributes = 0, */ | ||
386 | }; | ||
387 | |||
388 | static struct usb_descriptor_header *ncm_ss_function[] = { | ||
389 | (struct usb_descriptor_header *) &ncm_iad_desc, | ||
390 | /* CDC NCM control descriptors */ | ||
391 | (struct usb_descriptor_header *) &ncm_control_intf, | ||
392 | (struct usb_descriptor_header *) &ncm_header_desc, | ||
393 | (struct usb_descriptor_header *) &ncm_union_desc, | ||
394 | (struct usb_descriptor_header *) &ecm_desc, | ||
395 | (struct usb_descriptor_header *) &ncm_desc, | ||
396 | (struct usb_descriptor_header *) &ss_ncm_notify_desc, | ||
397 | (struct usb_descriptor_header *) &ss_ncm_notify_comp_desc, | ||
398 | /* data interface, altsettings 0 and 1 */ | ||
399 | (struct usb_descriptor_header *) &ncm_data_nop_intf, | ||
400 | (struct usb_descriptor_header *) &ncm_data_intf, | ||
401 | (struct usb_descriptor_header *) &ss_ncm_in_desc, | ||
402 | (struct usb_descriptor_header *) &ss_ncm_bulk_comp_desc, | ||
403 | (struct usb_descriptor_header *) &ss_ncm_out_desc, | ||
404 | (struct usb_descriptor_header *) &ss_ncm_bulk_comp_desc, | ||
405 | NULL, | ||
406 | }; | ||
407 | |||
336 | /* string descriptors: */ | 408 | /* string descriptors: */ |
337 | 409 | ||
338 | #define STRING_CTRL_IDX 0 | 410 | #define STRING_CTRL_IDX 0 |
@@ -852,6 +924,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
852 | */ | 924 | */ |
853 | ncm->port.is_zlp_ok = | 925 | ncm->port.is_zlp_ok = |
854 | gadget_is_zlp_supported(cdev->gadget); | 926 | gadget_is_zlp_supported(cdev->gadget); |
927 | ncm->port.no_skb_reserve = | ||
928 | gadget_avoids_skb_reserve(cdev->gadget); | ||
855 | ncm->port.cdc_filter = DEFAULT_FILTER; | 929 | ncm->port.cdc_filter = DEFAULT_FILTER; |
856 | DBG(cdev, "activate ncm\n"); | 930 | DBG(cdev, "activate ncm\n"); |
857 | net = gether_connect(&ncm->port); | 931 | net = gether_connect(&ncm->port); |
@@ -1431,8 +1505,13 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) | |||
1431 | hs_ncm_notify_desc.bEndpointAddress = | 1505 | hs_ncm_notify_desc.bEndpointAddress = |
1432 | fs_ncm_notify_desc.bEndpointAddress; | 1506 | fs_ncm_notify_desc.bEndpointAddress; |
1433 | 1507 | ||
1508 | ss_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress; | ||
1509 | ss_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress; | ||
1510 | ss_ncm_notify_desc.bEndpointAddress = | ||
1511 | fs_ncm_notify_desc.bEndpointAddress; | ||
1512 | |||
1434 | status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, | 1513 | status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, |
1435 | NULL, NULL); | 1514 | ncm_ss_function, NULL); |
1436 | if (status) | 1515 | if (status) |
1437 | goto fail; | 1516 | goto fail; |
1438 | 1517 | ||
@@ -1450,6 +1529,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) | |||
1450 | ncm->task_timer.function = ncm_tx_timeout; | 1529 | ncm->task_timer.function = ncm_tx_timeout; |
1451 | 1530 | ||
1452 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", | 1531 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", |
1532 | gadget_is_superspeed(c->cdev->gadget) ? "super" : | ||
1453 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | 1533 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", |
1454 | ncm->port.in_ep->name, ncm->port.out_ep->name, | 1534 | ncm->port.in_ep->name, ncm->port.out_ep->name, |
1455 | ncm->notify->name); | 1535 | ncm->notify->name); |
diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 64706a789580..0de36cda6e41 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c | |||
@@ -889,13 +889,17 @@ static void printer_soft_reset(struct printer_dev *dev) | |||
889 | /*-------------------------------------------------------------------------*/ | 889 | /*-------------------------------------------------------------------------*/ |
890 | 890 | ||
891 | static bool gprinter_req_match(struct usb_function *f, | 891 | static bool gprinter_req_match(struct usb_function *f, |
892 | const struct usb_ctrlrequest *ctrl) | 892 | const struct usb_ctrlrequest *ctrl, |
893 | bool config0) | ||
893 | { | 894 | { |
894 | struct printer_dev *dev = func_to_printer(f); | 895 | struct printer_dev *dev = func_to_printer(f); |
895 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 896 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
896 | u16 w_value = le16_to_cpu(ctrl->wValue); | 897 | u16 w_value = le16_to_cpu(ctrl->wValue); |
897 | u16 w_length = le16_to_cpu(ctrl->wLength); | 898 | u16 w_length = le16_to_cpu(ctrl->wLength); |
898 | 899 | ||
900 | if (config0) | ||
901 | return false; | ||
902 | |||
899 | if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || | 903 | if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE || |
900 | (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) | 904 | (ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) |
901 | return false; | 905 | return false; |
diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index df0189ddfdd5..8784fa12ea2c 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c | |||
@@ -293,9 +293,7 @@ static struct usb_gadget_strings *sourcesink_strings[] = { | |||
293 | 293 | ||
294 | static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) | 294 | static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) |
295 | { | 295 | { |
296 | struct f_sourcesink *ss = ep->driver_data; | 296 | return alloc_ep_req(ep, len); |
297 | |||
298 | return alloc_ep_req(ep, len, ss->buflen); | ||
299 | } | 297 | } |
300 | 298 | ||
301 | static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) | 299 | static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) |
@@ -606,7 +604,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, | |||
606 | } else { | 604 | } else { |
607 | ep = is_in ? ss->in_ep : ss->out_ep; | 605 | ep = is_in ? ss->in_ep : ss->out_ep; |
608 | qlen = ss->bulk_qlen; | 606 | qlen = ss->bulk_qlen; |
609 | size = 0; | 607 | size = ss->buflen; |
610 | } | 608 | } |
611 | 609 | ||
612 | for (i = 0; i < qlen; i++) { | 610 | for (i = 0; i < qlen; i++) { |
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 29b41b5dee04..27ed51b5082f 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c | |||
@@ -258,6 +258,13 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
258 | memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); | 258 | memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); |
259 | v4l2_event_queue(&uvc->vdev, &v4l2_event); | 259 | v4l2_event_queue(&uvc->vdev, &v4l2_event); |
260 | 260 | ||
261 | /* Pass additional setup data to userspace */ | ||
262 | if (uvc->event_setup_out && uvc->event_length) { | ||
263 | uvc->control_req->length = uvc->event_length; | ||
264 | return usb_ep_queue(uvc->func.config->cdev->gadget->ep0, | ||
265 | uvc->control_req, GFP_ATOMIC); | ||
266 | } | ||
267 | |||
261 | return 0; | 268 | return 0; |
262 | } | 269 | } |
263 | 270 | ||
diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 990df221c629..8fbf6861690d 100644 --- a/drivers/usb/gadget/function/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c | |||
@@ -369,6 +369,12 @@ ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) | |||
369 | } | 369 | } |
370 | EXPORT_SYMBOL_GPL(fsg_show_removable); | 370 | EXPORT_SYMBOL_GPL(fsg_show_removable); |
371 | 371 | ||
372 | ssize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf) | ||
373 | { | ||
374 | return sprintf(buf, "%s\n", curlun->inquiry_string); | ||
375 | } | ||
376 | EXPORT_SYMBOL_GPL(fsg_show_inquiry_string); | ||
377 | |||
372 | /* | 378 | /* |
373 | * The caller must hold fsg->filesem for reading when calling this function. | 379 | * The caller must hold fsg->filesem for reading when calling this function. |
374 | */ | 380 | */ |
@@ -499,4 +505,22 @@ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, | |||
499 | } | 505 | } |
500 | EXPORT_SYMBOL_GPL(fsg_store_removable); | 506 | EXPORT_SYMBOL_GPL(fsg_store_removable); |
501 | 507 | ||
508 | ssize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, | ||
509 | size_t count) | ||
510 | { | ||
511 | const size_t len = min(count, sizeof(curlun->inquiry_string)); | ||
512 | |||
513 | if (len == 0 || buf[0] == '\n') { | ||
514 | curlun->inquiry_string[0] = 0; | ||
515 | } else { | ||
516 | snprintf(curlun->inquiry_string, | ||
517 | sizeof(curlun->inquiry_string), "%-28s", buf); | ||
518 | if (curlun->inquiry_string[len-1] == '\n') | ||
519 | curlun->inquiry_string[len-1] = ' '; | ||
520 | } | ||
521 | |||
522 | return count; | ||
523 | } | ||
524 | EXPORT_SYMBOL_GPL(fsg_store_inquiry_string); | ||
525 | |||
502 | MODULE_LICENSE("GPL"); | 526 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index c3544e61da66..e69848994cb4 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h | |||
@@ -88,6 +88,12 @@ do { \ | |||
88 | #define ASC(x) ((u8) ((x) >> 8)) | 88 | #define ASC(x) ((u8) ((x) >> 8)) |
89 | #define ASCQ(x) ((u8) (x)) | 89 | #define ASCQ(x) ((u8) (x)) |
90 | 90 | ||
91 | /* | ||
92 | * Vendor (8 chars), product (16 chars), release (4 hexadecimal digits) and NUL | ||
93 | * byte | ||
94 | */ | ||
95 | #define INQUIRY_STRING_LEN ((size_t) (8 + 16 + 4 + 1)) | ||
96 | |||
91 | struct fsg_lun { | 97 | struct fsg_lun { |
92 | struct file *filp; | 98 | struct file *filp; |
93 | loff_t file_length; | 99 | loff_t file_length; |
@@ -112,6 +118,7 @@ struct fsg_lun { | |||
112 | struct device dev; | 118 | struct device dev; |
113 | const char *name; /* "lun.name" */ | 119 | const char *name; /* "lun.name" */ |
114 | const char **name_pfx; /* "function.name" */ | 120 | const char **name_pfx; /* "function.name" */ |
121 | char inquiry_string[INQUIRY_STRING_LEN]; | ||
115 | }; | 122 | }; |
116 | 123 | ||
117 | static inline bool fsg_lun_is_open(struct fsg_lun *curlun) | 124 | static inline bool fsg_lun_is_open(struct fsg_lun *curlun) |
@@ -210,6 +217,7 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf); | |||
210 | ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); | 217 | ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf); |
211 | ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, | 218 | ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, |
212 | char *buf); | 219 | char *buf); |
220 | ssize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf); | ||
213 | ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); | 221 | ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf); |
214 | ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); | 222 | ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf); |
215 | ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, | 223 | ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, |
@@ -221,5 +229,7 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, | |||
221 | const char *buf, size_t count); | 229 | const char *buf, size_t count); |
222 | ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, | 230 | ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, |
223 | size_t count); | 231 | size_t count); |
232 | ssize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, | ||
233 | size_t count); | ||
224 | 234 | ||
225 | #endif /* USB_STORAGE_COMMON_H */ | 235 | #endif /* USB_STORAGE_COMMON_H */ |
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 5f562c1ec795..9c8c9ed1dc9e 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c | |||
@@ -82,6 +82,7 @@ struct eth_dev { | |||
82 | #define WORK_RX_MEMORY 0 | 82 | #define WORK_RX_MEMORY 0 |
83 | 83 | ||
84 | bool zlp; | 84 | bool zlp; |
85 | bool no_skb_reserve; | ||
85 | u8 host_mac[ETH_ALEN]; | 86 | u8 host_mac[ETH_ALEN]; |
86 | u8 dev_mac[ETH_ALEN]; | 87 | u8 dev_mac[ETH_ALEN]; |
87 | }; | 88 | }; |
@@ -233,7 +234,8 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) | |||
233 | * but on at least one, checksumming fails otherwise. Note: | 234 | * but on at least one, checksumming fails otherwise. Note: |
234 | * RNDIS headers involve variable numbers of LE32 values. | 235 | * RNDIS headers involve variable numbers of LE32 values. |
235 | */ | 236 | */ |
236 | skb_reserve(skb, NET_IP_ALIGN); | 237 | if (likely(!dev->no_skb_reserve)) |
238 | skb_reserve(skb, NET_IP_ALIGN); | ||
237 | 239 | ||
238 | req->buf = skb->data; | 240 | req->buf = skb->data; |
239 | req->length = size; | 241 | req->length = size; |
@@ -569,7 +571,8 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
569 | req->complete = tx_complete; | 571 | req->complete = tx_complete; |
570 | 572 | ||
571 | /* NCM requires no zlp if transfer is dwNtbInMaxSize */ | 573 | /* NCM requires no zlp if transfer is dwNtbInMaxSize */ |
572 | if (dev->port_usb->is_fixed && | 574 | if (dev->port_usb && |
575 | dev->port_usb->is_fixed && | ||
573 | length == dev->port_usb->fixed_in_len && | 576 | length == dev->port_usb->fixed_in_len && |
574 | (length % in->maxpacket) == 0) | 577 | (length % in->maxpacket) == 0) |
575 | req->zero = 0; | 578 | req->zero = 0; |
@@ -1063,6 +1066,7 @@ struct net_device *gether_connect(struct gether *link) | |||
1063 | 1066 | ||
1064 | if (result == 0) { | 1067 | if (result == 0) { |
1065 | dev->zlp = link->is_zlp_ok; | 1068 | dev->zlp = link->is_zlp_ok; |
1069 | dev->no_skb_reserve = link->no_skb_reserve; | ||
1066 | DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); | 1070 | DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); |
1067 | 1071 | ||
1068 | dev->header_len = link->header_len; | 1072 | dev->header_len = link->header_len; |
diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index c77145bd6b5b..81d94a7ae4b4 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h | |||
@@ -64,6 +64,7 @@ struct gether { | |||
64 | struct usb_ep *out_ep; | 64 | struct usb_ep *out_ep; |
65 | 65 | ||
66 | bool is_zlp_ok; | 66 | bool is_zlp_ok; |
67 | bool no_skb_reserve; | ||
67 | 68 | ||
68 | u16 cdc_filter; | 69 | u16 cdc_filter; |
69 | 70 | ||
diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index fc2ac150f5ff..0bf39c3ccdb1 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c | |||
@@ -47,7 +47,7 @@ static char *id = SNDRV_DEFAULT_STR1; | |||
47 | module_param(id, charp, S_IRUGO); | 47 | module_param(id, charp, S_IRUGO); |
48 | MODULE_PARM_DESC(id, "ID string for the USB MIDI Gadget adapter."); | 48 | MODULE_PARM_DESC(id, "ID string for the USB MIDI Gadget adapter."); |
49 | 49 | ||
50 | static unsigned int buflen = 256; | 50 | static unsigned int buflen = 512; |
51 | module_param(buflen, uint, S_IRUGO); | 51 | module_param(buflen, uint, S_IRUGO); |
52 | MODULE_PARM_DESC(buflen, "MIDI buffer length"); | 52 | MODULE_PARM_DESC(buflen, "MIDI buffer length"); |
53 | 53 | ||
diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index 4bc7eea8bfc8..18839732c840 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c | |||
@@ -12,14 +12,16 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "u_f.h" | 14 | #include "u_f.h" |
15 | #include <linux/usb/ch9.h> | ||
15 | 16 | ||
16 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) | 17 | struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len) |
17 | { | 18 | { |
18 | struct usb_request *req; | 19 | struct usb_request *req; |
19 | 20 | ||
20 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); | 21 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); |
21 | if (req) { | 22 | if (req) { |
22 | req->length = len ?: default_len; | 23 | req->length = usb_endpoint_dir_out(ep->desc) ? |
24 | usb_ep_align(ep, len) : len; | ||
23 | req->buf = kmalloc(req->length, GFP_ATOMIC); | 25 | req->buf = kmalloc(req->length, GFP_ATOMIC); |
24 | if (!req->buf) { | 26 | if (!req->buf) { |
25 | usb_ep_free_request(ep, req); | 27 | usb_ep_free_request(ep, req); |
diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 4247cc098a89..7d53a4773d1a 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h | |||
@@ -47,8 +47,21 @@ | |||
47 | struct usb_ep; | 47 | struct usb_ep; |
48 | struct usb_request; | 48 | struct usb_request; |
49 | 49 | ||
50 | /* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */ | 50 | /** |
51 | struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len); | 51 | * alloc_ep_req - returns a usb_request allocated by the gadget driver and |
52 | * allocates the request's buffer. | ||
53 | * | ||
54 | * @ep: the endpoint to allocate a usb_request | ||
55 | * @len: usb_requests's buffer suggested size | ||
56 | * | ||
57 | * In case @ep direction is OUT, the @len will be aligned to ep's | ||
58 | * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use | ||
59 | * usb_requests's length (req->length) to refer to the allocated buffer size. | ||
60 | * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req(). | ||
61 | */ | ||
62 | struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len); | ||
63 | |||
64 | /* Frees a usb_request previously allocated by alloc_ep_req() */ | ||
52 | static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) | 65 | static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) |
53 | { | 66 | { |
54 | kfree(req->buf); | 67 | kfree(req->buf); |
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 40c04bb25f2f..9483489080f6 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c | |||
@@ -107,10 +107,8 @@ int usb_ep_enable(struct usb_ep *ep) | |||
107 | goto out; | 107 | goto out; |
108 | 108 | ||
109 | ret = ep->ops->enable(ep, ep->desc); | 109 | ret = ep->ops->enable(ep, ep->desc); |
110 | if (ret) { | 110 | if (ret) |
111 | ret = ret; | ||
112 | goto out; | 111 | goto out; |
113 | } | ||
114 | 112 | ||
115 | ep->enabled = true; | 113 | ep->enabled = true; |
116 | 114 | ||
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 8bb011ea78f7..4fff51b8a18e 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c | |||
@@ -421,10 +421,8 @@ static int qe_ep_rxbd_update(struct qe_ep *ep) | |||
421 | bd = ep->rxbase; | 421 | bd = ep->rxbase; |
422 | 422 | ||
423 | ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC); | 423 | ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC); |
424 | if (ep->rxframe == NULL) { | 424 | if (!ep->rxframe) |
425 | dev_err(ep->udc->dev, "malloc rxframe failed\n"); | ||
426 | return -ENOMEM; | 425 | return -ENOMEM; |
427 | } | ||
428 | 426 | ||
429 | qe_frame_init(ep->rxframe); | 427 | qe_frame_init(ep->rxframe); |
430 | 428 | ||
@@ -435,9 +433,7 @@ static int qe_ep_rxbd_update(struct qe_ep *ep) | |||
435 | 433 | ||
436 | size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1); | 434 | size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1); |
437 | ep->rxbuffer = kzalloc(size, GFP_ATOMIC); | 435 | ep->rxbuffer = kzalloc(size, GFP_ATOMIC); |
438 | if (ep->rxbuffer == NULL) { | 436 | if (!ep->rxbuffer) { |
439 | dev_err(ep->udc->dev, "malloc rxbuffer failed,size=%d\n", | ||
440 | size); | ||
441 | kfree(ep->rxframe); | 437 | kfree(ep->rxframe); |
442 | return -ENOMEM; | 438 | return -ENOMEM; |
443 | } | 439 | } |
@@ -668,10 +664,8 @@ static int qe_ep_init(struct qe_udc *udc, | |||
668 | 664 | ||
669 | if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) { | 665 | if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) { |
670 | ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC); | 666 | ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC); |
671 | if (ep->txframe == NULL) { | 667 | if (!ep->txframe) |
672 | dev_err(udc->dev, "malloc txframe failed\n"); | ||
673 | goto en_done2; | 668 | goto en_done2; |
674 | } | ||
675 | qe_frame_init(ep->txframe); | 669 | qe_frame_init(ep->txframe); |
676 | } | 670 | } |
677 | 671 | ||
@@ -2344,10 +2338,8 @@ static struct qe_udc *qe_udc_config(struct platform_device *ofdev) | |||
2344 | u32 offset; | 2338 | u32 offset; |
2345 | 2339 | ||
2346 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); | 2340 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); |
2347 | if (udc == NULL) { | 2341 | if (!udc) |
2348 | dev_err(&ofdev->dev, "malloc udc failed\n"); | ||
2349 | goto cleanup; | 2342 | goto cleanup; |
2350 | } | ||
2351 | 2343 | ||
2352 | udc->dev = &ofdev->dev; | 2344 | udc->dev = &ofdev->dev; |
2353 | 2345 | ||
diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index d2205d9e0c8b..5107987bd353 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c | |||
@@ -1767,8 +1767,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1767 | 1767 | ||
1768 | /* alloc, and start init */ | 1768 | /* alloc, and start init */ |
1769 | dev = kzalloc (sizeof *dev, GFP_KERNEL); | 1769 | dev = kzalloc (sizeof *dev, GFP_KERNEL); |
1770 | if (dev == NULL){ | 1770 | if (!dev) { |
1771 | pr_debug("enomem %s\n", pci_name(pdev)); | ||
1772 | retval = -ENOMEM; | 1771 | retval = -ENOMEM; |
1773 | goto err; | 1772 | goto err; |
1774 | } | 1773 | } |
@@ -1839,6 +1838,8 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1839 | err: | 1838 | err: |
1840 | if (dev) | 1839 | if (dev) |
1841 | goku_remove (pdev); | 1840 | goku_remove (pdev); |
1841 | /* gadget_release is not registered yet, kfree explicitly */ | ||
1842 | kfree(dev); | ||
1842 | return retval; | 1843 | return retval; |
1843 | } | 1844 | } |
1844 | 1845 | ||
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 614ab951a4ae..61c938c36d88 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
@@ -589,7 +589,7 @@ static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
589 | 589 | ||
590 | ep = container_of(_ep, struct net2280_ep, ep); | 590 | ep = container_of(_ep, struct net2280_ep, ep); |
591 | if (!_ep || !_req) { | 591 | if (!_ep || !_req) { |
592 | dev_err(&ep->dev->pdev->dev, "%s: Inavlid ep=%p or req=%p\n", | 592 | dev_err(&ep->dev->pdev->dev, "%s: Invalid ep=%p or req=%p\n", |
593 | __func__, _ep, _req); | 593 | __func__, _ep, _req); |
594 | return; | 594 | return; |
595 | } | 595 | } |
@@ -1137,8 +1137,10 @@ dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount, | |||
1137 | done(ep, req, status); | 1137 | done(ep, req, status); |
1138 | } | 1138 | } |
1139 | 1139 | ||
1140 | static void scan_dma_completions(struct net2280_ep *ep) | 1140 | static int scan_dma_completions(struct net2280_ep *ep) |
1141 | { | 1141 | { |
1142 | int num_completed = 0; | ||
1143 | |||
1142 | /* only look at descriptors that were "naturally" retired, | 1144 | /* only look at descriptors that were "naturally" retired, |
1143 | * so fifo and list head state won't matter | 1145 | * so fifo and list head state won't matter |
1144 | */ | 1146 | */ |
@@ -1166,6 +1168,7 @@ static void scan_dma_completions(struct net2280_ep *ep) | |||
1166 | break; | 1168 | break; |
1167 | /* single transfer mode */ | 1169 | /* single transfer mode */ |
1168 | dma_done(ep, req, tmp, 0); | 1170 | dma_done(ep, req, tmp, 0); |
1171 | num_completed++; | ||
1169 | break; | 1172 | break; |
1170 | } else if (!ep->is_in && | 1173 | } else if (!ep->is_in && |
1171 | (req->req.length % ep->ep.maxpacket) && | 1174 | (req->req.length % ep->ep.maxpacket) && |
@@ -1194,7 +1197,10 @@ static void scan_dma_completions(struct net2280_ep *ep) | |||
1194 | } | 1197 | } |
1195 | } | 1198 | } |
1196 | dma_done(ep, req, tmp, 0); | 1199 | dma_done(ep, req, tmp, 0); |
1200 | num_completed++; | ||
1197 | } | 1201 | } |
1202 | |||
1203 | return num_completed; | ||
1198 | } | 1204 | } |
1199 | 1205 | ||
1200 | static void restart_dma(struct net2280_ep *ep) | 1206 | static void restart_dma(struct net2280_ep *ep) |
@@ -1567,6 +1573,44 @@ static struct usb_ep *net2280_match_ep(struct usb_gadget *_gadget, | |||
1567 | return ep; | 1573 | return ep; |
1568 | } | 1574 | } |
1569 | 1575 | ||
1576 | /* USB3380: Only first four endpoints have DMA channels. Allocate | ||
1577 | * slower interrupt endpoints from PIO hw endpoints, to allow bulk/isoc | ||
1578 | * endpoints use DMA hw endpoints. | ||
1579 | */ | ||
1580 | if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT && | ||
1581 | usb_endpoint_dir_in(desc)) { | ||
1582 | ep = gadget_find_ep_by_name(_gadget, "ep2in"); | ||
1583 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1584 | return ep; | ||
1585 | ep = gadget_find_ep_by_name(_gadget, "ep4in"); | ||
1586 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1587 | return ep; | ||
1588 | } else if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT && | ||
1589 | !usb_endpoint_dir_in(desc)) { | ||
1590 | ep = gadget_find_ep_by_name(_gadget, "ep1out"); | ||
1591 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1592 | return ep; | ||
1593 | ep = gadget_find_ep_by_name(_gadget, "ep3out"); | ||
1594 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1595 | return ep; | ||
1596 | } else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK && | ||
1597 | usb_endpoint_dir_in(desc)) { | ||
1598 | ep = gadget_find_ep_by_name(_gadget, "ep1in"); | ||
1599 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1600 | return ep; | ||
1601 | ep = gadget_find_ep_by_name(_gadget, "ep3in"); | ||
1602 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1603 | return ep; | ||
1604 | } else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK && | ||
1605 | !usb_endpoint_dir_in(desc)) { | ||
1606 | ep = gadget_find_ep_by_name(_gadget, "ep2out"); | ||
1607 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1608 | return ep; | ||
1609 | ep = gadget_find_ep_by_name(_gadget, "ep4out"); | ||
1610 | if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp)) | ||
1611 | return ep; | ||
1612 | } | ||
1613 | |||
1570 | /* USB3380: use same address for usb and hardware endpoints */ | 1614 | /* USB3380: use same address for usb and hardware endpoints */ |
1571 | snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc), | 1615 | snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc), |
1572 | usb_endpoint_dir_in(desc) ? "in" : "out"); | 1616 | usb_endpoint_dir_in(desc) ? "in" : "out"); |
@@ -2547,8 +2591,11 @@ static void handle_ep_small(struct net2280_ep *ep) | |||
2547 | /* manual DMA queue advance after short OUT */ | 2591 | /* manual DMA queue advance after short OUT */ |
2548 | if (likely(ep->dma)) { | 2592 | if (likely(ep->dma)) { |
2549 | if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) { | 2593 | if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) { |
2550 | u32 count; | 2594 | struct net2280_request *stuck_req = NULL; |
2551 | int stopped = ep->stopped; | 2595 | int stopped = ep->stopped; |
2596 | int num_completed; | ||
2597 | int stuck = 0; | ||
2598 | u32 count; | ||
2552 | 2599 | ||
2553 | /* TRANSFERRED works around OUT_DONE erratum 0112. | 2600 | /* TRANSFERRED works around OUT_DONE erratum 0112. |
2554 | * we expect (N <= maxpacket) bytes; host wrote M. | 2601 | * we expect (N <= maxpacket) bytes; host wrote M. |
@@ -2560,7 +2607,7 @@ static void handle_ep_small(struct net2280_ep *ep) | |||
2560 | /* any preceding dma transfers must finish. | 2607 | /* any preceding dma transfers must finish. |
2561 | * dma handles (M >= N), may empty the queue | 2608 | * dma handles (M >= N), may empty the queue |
2562 | */ | 2609 | */ |
2563 | scan_dma_completions(ep); | 2610 | num_completed = scan_dma_completions(ep); |
2564 | if (unlikely(list_empty(&ep->queue) || | 2611 | if (unlikely(list_empty(&ep->queue) || |
2565 | ep->out_overflow)) { | 2612 | ep->out_overflow)) { |
2566 | req = NULL; | 2613 | req = NULL; |
@@ -2580,6 +2627,31 @@ static void handle_ep_small(struct net2280_ep *ep) | |||
2580 | req = NULL; | 2627 | req = NULL; |
2581 | break; | 2628 | break; |
2582 | } | 2629 | } |
2630 | |||
2631 | /* Escape loop if no dma transfers completed | ||
2632 | * after few retries. | ||
2633 | */ | ||
2634 | if (num_completed == 0) { | ||
2635 | if (stuck_req == req && | ||
2636 | readl(&ep->dma->dmadesc) != | ||
2637 | req->td_dma && stuck++ > 5) { | ||
2638 | count = readl( | ||
2639 | &ep->dma->dmacount); | ||
2640 | count &= DMA_BYTE_COUNT_MASK; | ||
2641 | req = NULL; | ||
2642 | ep_dbg(ep->dev, "%s escape stuck %d, count %u\n", | ||
2643 | ep->ep.name, stuck, | ||
2644 | count); | ||
2645 | break; | ||
2646 | } else if (stuck_req != req) { | ||
2647 | stuck_req = req; | ||
2648 | stuck = 0; | ||
2649 | } | ||
2650 | } else { | ||
2651 | stuck_req = NULL; | ||
2652 | stuck = 0; | ||
2653 | } | ||
2654 | |||
2583 | udelay(1); | 2655 | udelay(1); |
2584 | } | 2656 | } |
2585 | 2657 | ||
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 9b7d39484ed3..a8709f9e5648 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c | |||
@@ -2875,7 +2875,7 @@ bad_on_1710: | |||
2875 | xceiv = NULL; | 2875 | xceiv = NULL; |
2876 | /* "udc" is now valid */ | 2876 | /* "udc" is now valid */ |
2877 | pullup_disable(udc); | 2877 | pullup_disable(udc); |
2878 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 2878 | #if IS_ENABLED(CONFIG_USB_OHCI_HCD) |
2879 | udc->gadget.is_otg = (config->otg != 0); | 2879 | udc->gadget.is_otg = (config->otg != 0); |
2880 | #endif | 2880 | #endif |
2881 | 2881 | ||
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index ad140aa00132..7fa60f5b7ae4 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include <linux/usb/ch9.h> | 34 | #include <linux/usb/ch9.h> |
35 | #include <linux/usb/gadget.h> | 35 | #include <linux/usb/gadget.h> |
36 | #include <linux/usb/phy.h> | ||
36 | 37 | ||
37 | #include "pxa27x_udc.h" | 38 | #include "pxa27x_udc.h" |
38 | 39 | ||
@@ -1655,6 +1656,37 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1655 | return -EOPNOTSUPP; | 1656 | return -EOPNOTSUPP; |
1656 | } | 1657 | } |
1657 | 1658 | ||
1659 | /** | ||
1660 | * pxa_udc_phy_event - Called by phy upon VBus event | ||
1661 | * @nb: notifier block | ||
1662 | * @action: phy action, is vbus connect or disconnect | ||
1663 | * @data: the usb_gadget structure in pxa_udc | ||
1664 | * | ||
1665 | * Called by the USB Phy when a cable connect or disconnect is sensed. | ||
1666 | * | ||
1667 | * Returns 0 | ||
1668 | */ | ||
1669 | static int pxa_udc_phy_event(struct notifier_block *nb, unsigned long action, | ||
1670 | void *data) | ||
1671 | { | ||
1672 | struct usb_gadget *gadget = data; | ||
1673 | |||
1674 | switch (action) { | ||
1675 | case USB_EVENT_VBUS: | ||
1676 | usb_gadget_vbus_connect(gadget); | ||
1677 | return NOTIFY_OK; | ||
1678 | case USB_EVENT_NONE: | ||
1679 | usb_gadget_vbus_disconnect(gadget); | ||
1680 | return NOTIFY_OK; | ||
1681 | default: | ||
1682 | return NOTIFY_DONE; | ||
1683 | } | ||
1684 | } | ||
1685 | |||
1686 | static struct notifier_block pxa27x_udc_phy = { | ||
1687 | .notifier_call = pxa_udc_phy_event, | ||
1688 | }; | ||
1689 | |||
1658 | static int pxa27x_udc_start(struct usb_gadget *g, | 1690 | static int pxa27x_udc_start(struct usb_gadget *g, |
1659 | struct usb_gadget_driver *driver); | 1691 | struct usb_gadget_driver *driver); |
1660 | static int pxa27x_udc_stop(struct usb_gadget *g); | 1692 | static int pxa27x_udc_stop(struct usb_gadget *g); |
@@ -2432,7 +2464,14 @@ static int pxa_udc_probe(struct platform_device *pdev) | |||
2432 | return udc->irq; | 2464 | return udc->irq; |
2433 | 2465 | ||
2434 | udc->dev = &pdev->dev; | 2466 | udc->dev = &pdev->dev; |
2435 | udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 2467 | if (of_have_populated_dt()) { |
2468 | udc->transceiver = | ||
2469 | devm_usb_get_phy_by_phandle(udc->dev, "phys", 0); | ||
2470 | if (IS_ERR(udc->transceiver)) | ||
2471 | return PTR_ERR(udc->transceiver); | ||
2472 | } else { | ||
2473 | udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | ||
2474 | } | ||
2436 | 2475 | ||
2437 | if (IS_ERR(udc->gpiod)) { | 2476 | if (IS_ERR(udc->gpiod)) { |
2438 | dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n", | 2477 | dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n", |
@@ -2465,14 +2504,20 @@ static int pxa_udc_probe(struct platform_device *pdev) | |||
2465 | goto err; | 2504 | goto err; |
2466 | } | 2505 | } |
2467 | 2506 | ||
2507 | if (!IS_ERR_OR_NULL(udc->transceiver)) | ||
2508 | usb_register_notifier(udc->transceiver, &pxa27x_udc_phy); | ||
2468 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); | 2509 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); |
2469 | if (retval) | 2510 | if (retval) |
2470 | goto err; | 2511 | goto err_add_gadget; |
2471 | 2512 | ||
2472 | pxa_init_debugfs(udc); | 2513 | pxa_init_debugfs(udc); |
2473 | if (should_enable_udc(udc)) | 2514 | if (should_enable_udc(udc)) |
2474 | udc_enable(udc); | 2515 | udc_enable(udc); |
2475 | return 0; | 2516 | return 0; |
2517 | |||
2518 | err_add_gadget: | ||
2519 | if (!IS_ERR_OR_NULL(udc->transceiver)) | ||
2520 | usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy); | ||
2476 | err: | 2521 | err: |
2477 | clk_unprepare(udc->clk); | 2522 | clk_unprepare(udc->clk); |
2478 | return retval; | 2523 | return retval; |
@@ -2489,6 +2534,8 @@ static int pxa_udc_remove(struct platform_device *_dev) | |||
2489 | usb_del_gadget_udc(&udc->gadget); | 2534 | usb_del_gadget_udc(&udc->gadget); |
2490 | pxa_cleanup_debugfs(udc); | 2535 | pxa_cleanup_debugfs(udc); |
2491 | 2536 | ||
2537 | if (!IS_ERR_OR_NULL(udc->transceiver)) | ||
2538 | usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy); | ||
2492 | usb_put_phy(udc->transceiver); | 2539 | usb_put_phy(udc->transceiver); |
2493 | 2540 | ||
2494 | udc->transceiver = NULL; | 2541 | udc->transceiver = NULL; |
diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index f8bf290f1894..588e2531b8b8 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c | |||
@@ -973,10 +973,8 @@ static struct usb_request *xudc_ep_alloc_request(struct usb_ep *_ep, | |||
973 | 973 | ||
974 | udc = ep->udc; | 974 | udc = ep->udc; |
975 | req = kzalloc(sizeof(*req), gfp_flags); | 975 | req = kzalloc(sizeof(*req), gfp_flags); |
976 | if (!req) { | 976 | if (!req) |
977 | dev_err(udc->dev, "%s:not enough memory", __func__); | ||
978 | return NULL; | 977 | return NULL; |
979 | } | ||
980 | 978 | ||
981 | req->ep = ep; | 979 | req->ep = ep; |
982 | INIT_LIST_HEAD(&req->queue); | 980 | INIT_LIST_HEAD(&req->queue); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2e710a4cca52..0b80cee30da4 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -472,7 +472,7 @@ config USB_OHCI_HCD_AT91 | |||
472 | 472 | ||
473 | config USB_OHCI_HCD_OMAP3 | 473 | config USB_OHCI_HCD_OMAP3 |
474 | tristate "OHCI support for OMAP3 and later chips" | 474 | tristate "OHCI support for OMAP3 and later chips" |
475 | depends on (ARCH_OMAP3 || ARCH_OMAP4) | 475 | depends on (ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5) |
476 | default y | 476 | default y |
477 | ---help--- | 477 | ---help--- |
478 | Enables support for the on-chip OHCI controller on | 478 | Enables support for the on-chip OHCI controller on |
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 172ef17911aa..5f425c89faf1 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/of_gpio.h> | 29 | #include <linux/of_gpio.h> |
30 | #include <linux/of_platform.h> | ||
30 | #include <linux/usb/ehci_pdriver.h> | 31 | #include <linux/usb/ehci_pdriver.h> |
31 | #include <linux/usb/ohci_pdriver.h> | 32 | #include <linux/usb/ohci_pdriver.h> |
32 | 33 | ||
@@ -34,6 +35,9 @@ MODULE_AUTHOR("Hauke Mehrtens"); | |||
34 | MODULE_DESCRIPTION("Common USB driver for BCMA Bus"); | 35 | MODULE_DESCRIPTION("Common USB driver for BCMA Bus"); |
35 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
36 | 37 | ||
38 | /* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */ | ||
39 | #define USB_BCMA_CLKCTLST_USB_CLK_REQ 0x00000100 | ||
40 | |||
37 | struct bcma_hcd_device { | 41 | struct bcma_hcd_device { |
38 | struct bcma_device *core; | 42 | struct bcma_device *core; |
39 | struct platform_device *ehci_dev; | 43 | struct platform_device *ehci_dev; |
@@ -165,44 +169,80 @@ static void bcma_hcd_init_chip_mips(struct bcma_device *dev) | |||
165 | } | 169 | } |
166 | } | 170 | } |
167 | 171 | ||
168 | static void bcma_hcd_init_chip_arm_phy(struct bcma_device *dev) | 172 | /** |
173 | * bcma_hcd_usb20_old_arm_init - Initialize old USB 2.0 controller on ARM | ||
174 | * | ||
175 | * Old USB 2.0 core is identified as BCMA_CORE_USB20_HOST and was introduced | ||
176 | * long before Northstar devices. It seems some cheaper chipsets like BCM53573 | ||
177 | * still use it. | ||
178 | * Initialization of this old core differs between MIPS and ARM. | ||
179 | */ | ||
180 | static int bcma_hcd_usb20_old_arm_init(struct bcma_hcd_device *usb_dev) | ||
169 | { | 181 | { |
170 | struct bcma_device *arm_core; | 182 | struct bcma_device *core = usb_dev->core; |
171 | void __iomem *dmu; | 183 | struct device *dev = &core->dev; |
172 | 184 | struct bcma_device *pmu_core; | |
173 | arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9); | 185 | |
174 | if (!arm_core) { | 186 | usleep_range(10000, 20000); |
175 | dev_err(&dev->dev, "can not find ARM Cortex A9 ihost core\n"); | 187 | if (core->id.rev < 5) |
176 | return; | 188 | return 0; |
189 | |||
190 | pmu_core = bcma_find_core(core->bus, BCMA_CORE_PMU); | ||
191 | if (!pmu_core) { | ||
192 | dev_err(dev, "Could not find PMU core\n"); | ||
193 | return -ENOENT; | ||
177 | } | 194 | } |
178 | 195 | ||
179 | dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000); | 196 | /* Take USB core out of reset */ |
180 | if (!dmu) { | 197 | bcma_awrite32(core, BCMA_IOCTL, BCMA_IOCTL_CLK | BCMA_IOCTL_FGC); |
181 | dev_err(&dev->dev, "can not map ARM Cortex A9 ihost core\n"); | 198 | usleep_range(100, 200); |
182 | return; | 199 | bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); |
183 | } | 200 | usleep_range(100, 200); |
184 | 201 | bcma_awrite32(core, BCMA_RESET_CTL, 0); | |
185 | /* Unlock DMU PLL settings */ | 202 | usleep_range(100, 200); |
186 | iowrite32(0x0000ea68, dmu + 0x180); | 203 | bcma_awrite32(core, BCMA_IOCTL, BCMA_IOCTL_CLK); |
187 | 204 | usleep_range(100, 200); | |
188 | /* Write USB 2.0 PLL control setting */ | 205 | |
189 | iowrite32(0x00dd10c3, dmu + 0x164); | 206 | /* Enable Misc PLL */ |
207 | bcma_write32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT | | ||
208 | BCMA_CLKCTLST_HQCLKREQ | | ||
209 | USB_BCMA_CLKCTLST_USB_CLK_REQ); | ||
210 | usleep_range(100, 200); | ||
211 | |||
212 | bcma_write32(core, 0x510, 0xc7f85000); | ||
213 | bcma_write32(core, 0x510, 0xc7f85003); | ||
214 | usleep_range(300, 600); | ||
215 | |||
216 | /* Program USB PHY PLL parameters */ | ||
217 | bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_ADDR, 0x6); | ||
218 | bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_DATA, 0x005360c1); | ||
219 | usleep_range(100, 200); | ||
220 | bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_ADDR, 0x7); | ||
221 | bcma_write32(pmu_core, BCMA_CC_PMU_PLLCTL_DATA, 0x0); | ||
222 | usleep_range(100, 200); | ||
223 | bcma_set32(pmu_core, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); | ||
224 | usleep_range(100, 200); | ||
225 | |||
226 | bcma_write32(core, 0x510, 0x7f8d007); | ||
227 | udelay(1000); | ||
228 | |||
229 | /* Take controller out of reset */ | ||
230 | bcma_write32(core, 0x200, 0x4ff); | ||
231 | usleep_range(25, 50); | ||
232 | bcma_write32(core, 0x200, 0x6ff); | ||
233 | usleep_range(25, 50); | ||
234 | bcma_write32(core, 0x200, 0x7ff); | ||
235 | usleep_range(25, 50); | ||
236 | |||
237 | of_platform_default_populate(dev->of_node, NULL, dev); | ||
190 | 238 | ||
191 | /* Lock DMU PLL settings */ | 239 | return 0; |
192 | iowrite32(0x00000000, dmu + 0x180); | ||
193 | |||
194 | iounmap(dmu); | ||
195 | } | 240 | } |
196 | 241 | ||
197 | static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev) | 242 | static void bcma_hcd_usb20_ns_init_hc(struct bcma_device *dev) |
198 | { | 243 | { |
199 | u32 val; | 244 | u32 val; |
200 | 245 | ||
201 | /* | ||
202 | * Delay after PHY initialized to ensure HC is ready to be configured | ||
203 | */ | ||
204 | usleep_range(1000, 2000); | ||
205 | |||
206 | /* Set packet buffer OUT threshold */ | 246 | /* Set packet buffer OUT threshold */ |
207 | val = bcma_read32(dev, 0x94); | 247 | val = bcma_read32(dev, 0x94); |
208 | val &= 0xffff; | 248 | val &= 0xffff; |
@@ -213,20 +253,33 @@ static void bcma_hcd_init_chip_arm_hc(struct bcma_device *dev) | |||
213 | val = bcma_read32(dev, 0x9c); | 253 | val = bcma_read32(dev, 0x9c); |
214 | val |= 1; | 254 | val |= 1; |
215 | bcma_write32(dev, 0x9c, val); | 255 | bcma_write32(dev, 0x9c, val); |
256 | |||
257 | /* | ||
258 | * Broadcom initializes PHY and then waits to ensure HC is ready to be | ||
259 | * configured. In our case the order is reversed. We just initialized | ||
260 | * controller and we let HCD initialize PHY, so let's wait (sleep) now. | ||
261 | */ | ||
262 | usleep_range(1000, 2000); | ||
216 | } | 263 | } |
217 | 264 | ||
218 | static void bcma_hcd_init_chip_arm(struct bcma_device *dev) | 265 | /** |
266 | * bcma_hcd_usb20_ns_init - Initialize Northstar USB 2.0 controller | ||
267 | */ | ||
268 | static int bcma_hcd_usb20_ns_init(struct bcma_hcd_device *bcma_hcd) | ||
219 | { | 269 | { |
220 | bcma_core_enable(dev, 0); | 270 | struct bcma_device *core = bcma_hcd->core; |
271 | struct bcma_chipinfo *ci = &core->bus->chipinfo; | ||
272 | struct device *dev = &core->dev; | ||
221 | 273 | ||
222 | if (dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM4707 || | 274 | bcma_core_enable(core, 0); |
223 | dev->bus->chipinfo.id == BCMA_CHIP_ID_BCM53018) { | ||
224 | if (dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4707 || | ||
225 | dev->bus->chipinfo.pkg == BCMA_PKG_ID_BCM4708) | ||
226 | bcma_hcd_init_chip_arm_phy(dev); | ||
227 | 275 | ||
228 | bcma_hcd_init_chip_arm_hc(dev); | 276 | if (ci->id == BCMA_CHIP_ID_BCM4707 || |
229 | } | 277 | ci->id == BCMA_CHIP_ID_BCM53018) |
278 | bcma_hcd_usb20_ns_init_hc(core); | ||
279 | |||
280 | of_platform_default_populate(dev->of_node, NULL, dev); | ||
281 | |||
282 | return 0; | ||
230 | } | 283 | } |
231 | 284 | ||
232 | static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val) | 285 | static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val) |
@@ -299,16 +352,7 @@ static int bcma_hcd_usb20_init(struct bcma_hcd_device *usb_dev) | |||
299 | if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) | 352 | if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) |
300 | return -EOPNOTSUPP; | 353 | return -EOPNOTSUPP; |
301 | 354 | ||
302 | switch (dev->id.id) { | 355 | bcma_hcd_init_chip_mips(dev); |
303 | case BCMA_CORE_NS_USB20: | ||
304 | bcma_hcd_init_chip_arm(dev); | ||
305 | break; | ||
306 | case BCMA_CORE_USB20_HOST: | ||
307 | bcma_hcd_init_chip_mips(dev); | ||
308 | break; | ||
309 | default: | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | 356 | ||
313 | /* In AI chips EHCI is addrspace 0, OHCI is 1 */ | 357 | /* In AI chips EHCI is addrspace 0, OHCI is 1 */ |
314 | ohci_addr = dev->addr_s[0]; | 358 | ohci_addr = dev->addr_s[0]; |
@@ -338,6 +382,18 @@ err_unregister_ohci_dev: | |||
338 | return err; | 382 | return err; |
339 | } | 383 | } |
340 | 384 | ||
385 | static int bcma_hcd_usb30_init(struct bcma_hcd_device *bcma_hcd) | ||
386 | { | ||
387 | struct bcma_device *core = bcma_hcd->core; | ||
388 | struct device *dev = &core->dev; | ||
389 | |||
390 | bcma_core_enable(core, 0); | ||
391 | |||
392 | of_platform_default_populate(dev->of_node, NULL, dev); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | |||
341 | static int bcma_hcd_probe(struct bcma_device *core) | 397 | static int bcma_hcd_probe(struct bcma_device *core) |
342 | { | 398 | { |
343 | int err; | 399 | int err; |
@@ -357,14 +413,24 @@ static int bcma_hcd_probe(struct bcma_device *core) | |||
357 | 413 | ||
358 | switch (core->id.id) { | 414 | switch (core->id.id) { |
359 | case BCMA_CORE_USB20_HOST: | 415 | case BCMA_CORE_USB20_HOST: |
416 | if (IS_ENABLED(CONFIG_ARM)) | ||
417 | err = bcma_hcd_usb20_old_arm_init(usb_dev); | ||
418 | else if (IS_ENABLED(CONFIG_MIPS)) | ||
419 | err = bcma_hcd_usb20_init(usb_dev); | ||
420 | else | ||
421 | err = -ENOTSUPP; | ||
422 | break; | ||
360 | case BCMA_CORE_NS_USB20: | 423 | case BCMA_CORE_NS_USB20: |
361 | err = bcma_hcd_usb20_init(usb_dev); | 424 | err = bcma_hcd_usb20_ns_init(usb_dev); |
362 | if (err) | 425 | break; |
363 | return err; | 426 | case BCMA_CORE_NS_USB30: |
427 | err = bcma_hcd_usb30_init(usb_dev); | ||
364 | break; | 428 | break; |
365 | default: | 429 | default: |
366 | return -ENODEV; | 430 | return -ENODEV; |
367 | } | 431 | } |
432 | if (err) | ||
433 | return err; | ||
368 | 434 | ||
369 | bcma_set_drvdata(core, usb_dev); | 435 | bcma_set_drvdata(core, usb_dev); |
370 | return 0; | 436 | return 0; |
@@ -416,6 +482,7 @@ static int bcma_hcd_resume(struct bcma_device *dev) | |||
416 | static const struct bcma_device_id bcma_hcd_table[] = { | 482 | static const struct bcma_device_id bcma_hcd_table[] = { |
417 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS), | 483 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS), |
418 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS), | 484 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS), |
485 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB30, BCMA_ANY_REV, BCMA_ANY_CLASS), | ||
419 | {}, | 486 | {}, |
420 | }; | 487 | }; |
421 | MODULE_DEVICE_TABLE(bcma, bcma_hcd_table); | 488 | MODULE_DEVICE_TABLE(bcma, bcma_hcd_table); |
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 6816b8c371d0..876dca4fc216 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "ehci.h" | 38 | #include "ehci.h" |
39 | 39 | ||
40 | #define DRIVER_DESC "EHCI generic platform driver" | 40 | #define DRIVER_DESC "EHCI generic platform driver" |
41 | #define EHCI_MAX_CLKS 3 | 41 | #define EHCI_MAX_CLKS 4 |
42 | #define EHCI_MAX_RSTS 3 | 42 | #define EHCI_MAX_RSTS 3 |
43 | #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) | 43 | #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) |
44 | 44 | ||
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 0960f41f945a..55a0ae6f2d74 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -310,10 +310,8 @@ static struct fhci_usb *fhci_create_lld(struct fhci_hcd *fhci) | |||
310 | 310 | ||
311 | /* allocate memory for SCC data structure */ | 311 | /* allocate memory for SCC data structure */ |
312 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); | 312 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); |
313 | if (!usb) { | 313 | if (!usb) |
314 | fhci_err(fhci, "no memory for SCC data struct\n"); | ||
315 | return NULL; | 314 | return NULL; |
316 | } | ||
317 | 315 | ||
318 | usb->fhci = fhci; | 316 | usb->fhci = fhci; |
319 | usb->hc_list = fhci->hc_list; | 317 | usb->hc_list = fhci->hc_list; |
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 1044b0f9d656..f07ccb25bc24 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c | |||
@@ -222,23 +222,17 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) | |||
222 | pdata->controller_ver = usb_get_ver_info(np); | 222 | pdata->controller_ver = usb_get_ver_info(np); |
223 | 223 | ||
224 | /* Activate Erratum by reading property in device tree */ | 224 | /* Activate Erratum by reading property in device tree */ |
225 | if (of_get_property(np, "fsl,usb-erratum-a007792", NULL)) | 225 | pdata->has_fsl_erratum_a007792 = |
226 | pdata->has_fsl_erratum_a007792 = 1; | 226 | of_property_read_bool(np, "fsl,usb-erratum-a007792"); |
227 | else | 227 | pdata->has_fsl_erratum_a005275 = |
228 | pdata->has_fsl_erratum_a007792 = 0; | 228 | of_property_read_bool(np, "fsl,usb-erratum-a005275"); |
229 | if (of_get_property(np, "fsl,usb-erratum-a005275", NULL)) | ||
230 | pdata->has_fsl_erratum_a005275 = 1; | ||
231 | else | ||
232 | pdata->has_fsl_erratum_a005275 = 0; | ||
233 | 229 | ||
234 | /* | 230 | /* |
235 | * Determine whether phy_clk_valid needs to be checked | 231 | * Determine whether phy_clk_valid needs to be checked |
236 | * by reading property in device tree | 232 | * by reading property in device tree |
237 | */ | 233 | */ |
238 | if (of_get_property(np, "phy-clk-valid", NULL)) | 234 | pdata->check_phy_clk_valid = |
239 | pdata->check_phy_clk_valid = 1; | 235 | of_property_read_bool(np, "phy-clk-valid"); |
240 | else | ||
241 | pdata->check_phy_clk_valid = 0; | ||
242 | 236 | ||
243 | if (pdata->have_sysif_regs) { | 237 | if (pdata->have_sysif_regs) { |
244 | if (pdata->controller_ver == FSL_USB_VER_NONE) { | 238 | if (pdata->controller_ver == FSL_USB_VER_NONE) { |
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 2f7690092a7f..369869a29ebd 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c | |||
@@ -1856,15 +1856,11 @@ max3421_probe(struct spi_device *spi) | |||
1856 | INIT_LIST_HEAD(&max3421_hcd->ep_list); | 1856 | INIT_LIST_HEAD(&max3421_hcd->ep_list); |
1857 | 1857 | ||
1858 | max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); | 1858 | max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); |
1859 | if (!max3421_hcd->tx) { | 1859 | if (!max3421_hcd->tx) |
1860 | dev_err(&spi->dev, "failed to kmalloc tx buffer\n"); | ||
1861 | goto error; | 1860 | goto error; |
1862 | } | ||
1863 | max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); | 1861 | max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); |
1864 | if (!max3421_hcd->rx) { | 1862 | if (!max3421_hcd->rx) |
1865 | dev_err(&spi->dev, "failed to kmalloc rx buffer\n"); | ||
1866 | goto error; | 1863 | goto error; |
1867 | } | ||
1868 | 1864 | ||
1869 | max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, | 1865 | max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, |
1870 | "max3421_spi_thread"); | 1866 | "max3421_spi_thread"); |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index d177372bb357..5b5880c0ae19 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -21,8 +21,11 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/mfd/syscon.h> | ||
25 | #include <linux/regmap.h> | ||
24 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
25 | #include <linux/usb/hcd.h> | 27 | #include <linux/usb/hcd.h> |
28 | #include <soc/at91/atmel-sfr.h> | ||
26 | 29 | ||
27 | #include "ohci.h" | 30 | #include "ohci.h" |
28 | 31 | ||
@@ -51,6 +54,7 @@ struct ohci_at91_priv { | |||
51 | struct clk *hclk; | 54 | struct clk *hclk; |
52 | bool clocked; | 55 | bool clocked; |
53 | bool wakeup; /* Saved wake-up state for resume */ | 56 | bool wakeup; /* Saved wake-up state for resume */ |
57 | struct regmap *sfr_regmap; | ||
54 | }; | 58 | }; |
55 | /* interface and function clocks; sometimes also an AHB clock */ | 59 | /* interface and function clocks; sometimes also an AHB clock */ |
56 | 60 | ||
@@ -134,6 +138,17 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
134 | 138 | ||
135 | static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); | 139 | static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); |
136 | 140 | ||
141 | static struct regmap *at91_dt_syscon_sfr(void) | ||
142 | { | ||
143 | struct regmap *regmap; | ||
144 | |||
145 | regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); | ||
146 | if (IS_ERR(regmap)) | ||
147 | regmap = NULL; | ||
148 | |||
149 | return regmap; | ||
150 | } | ||
151 | |||
137 | /* configure so an HC device and id are always provided */ | 152 | /* configure so an HC device and id are always provided */ |
138 | /* always called with process context; sleeping is OK */ | 153 | /* always called with process context; sleeping is OK */ |
139 | 154 | ||
@@ -197,6 +212,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
197 | goto err; | 212 | goto err; |
198 | } | 213 | } |
199 | 214 | ||
215 | ohci_at91->sfr_regmap = at91_dt_syscon_sfr(); | ||
216 | if (!ohci_at91->sfr_regmap) | ||
217 | dev_warn(dev, "failed to find sfr node\n"); | ||
218 | |||
200 | board = hcd->self.controller->platform_data; | 219 | board = hcd->self.controller->platform_data; |
201 | ohci = hcd_to_ohci(hcd); | 220 | ohci = hcd_to_ohci(hcd); |
202 | ohci->num_ports = board->ports; | 221 | ohci->num_ports = board->ports; |
@@ -282,6 +301,28 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
282 | return length; | 301 | return length; |
283 | } | 302 | } |
284 | 303 | ||
304 | static int ohci_at91_port_suspend(struct regmap *regmap, u8 set) | ||
305 | { | ||
306 | u32 regval; | ||
307 | int ret; | ||
308 | |||
309 | if (!regmap) | ||
310 | return 0; | ||
311 | |||
312 | ret = regmap_read(regmap, AT91_SFR_OHCIICR, ®val); | ||
313 | if (ret) | ||
314 | return ret; | ||
315 | |||
316 | if (set) | ||
317 | regval |= AT91_OHCIICR_USB_SUSPEND; | ||
318 | else | ||
319 | regval &= ~AT91_OHCIICR_USB_SUSPEND; | ||
320 | |||
321 | regmap_write(regmap, AT91_SFR_OHCIICR, regval); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
285 | /* | 326 | /* |
286 | * Look at the control requests to the root hub and see if we need to override. | 327 | * Look at the control requests to the root hub and see if we need to override. |
287 | */ | 328 | */ |
@@ -289,6 +330,7 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
289 | u16 wIndex, char *buf, u16 wLength) | 330 | u16 wIndex, char *buf, u16 wLength) |
290 | { | 331 | { |
291 | struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller); | 332 | struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller); |
333 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | ||
292 | struct usb_hub_descriptor *desc; | 334 | struct usb_hub_descriptor *desc; |
293 | int ret = -EINVAL; | 335 | int ret = -EINVAL; |
294 | u32 *data = (u32 *)buf; | 336 | u32 *data = (u32 *)buf; |
@@ -301,7 +343,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
301 | 343 | ||
302 | switch (typeReq) { | 344 | switch (typeReq) { |
303 | case SetPortFeature: | 345 | case SetPortFeature: |
304 | if (wValue == USB_PORT_FEAT_POWER) { | 346 | switch (wValue) { |
347 | case USB_PORT_FEAT_POWER: | ||
305 | dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); | 348 | dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); |
306 | if (valid_port(wIndex)) { | 349 | if (valid_port(wIndex)) { |
307 | ohci_at91_usb_set_power(pdata, wIndex, 1); | 350 | ohci_at91_usb_set_power(pdata, wIndex, 1); |
@@ -309,6 +352,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
309 | } | 352 | } |
310 | 353 | ||
311 | goto out; | 354 | goto out; |
355 | |||
356 | case USB_PORT_FEAT_SUSPEND: | ||
357 | dev_dbg(hcd->self.controller, "SetPortFeat: SUSPEND\n"); | ||
358 | if (valid_port(wIndex)) { | ||
359 | ohci_at91_port_suspend(ohci_at91->sfr_regmap, | ||
360 | 1); | ||
361 | return 0; | ||
362 | } | ||
363 | break; | ||
312 | } | 364 | } |
313 | break; | 365 | break; |
314 | 366 | ||
@@ -342,6 +394,16 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
342 | ohci_at91_usb_set_power(pdata, wIndex, 0); | 394 | ohci_at91_usb_set_power(pdata, wIndex, 0); |
343 | return 0; | 395 | return 0; |
344 | } | 396 | } |
397 | break; | ||
398 | |||
399 | case USB_PORT_FEAT_SUSPEND: | ||
400 | dev_dbg(hcd->self.controller, "ClearPortFeature: SUSPEND\n"); | ||
401 | if (valid_port(wIndex)) { | ||
402 | ohci_at91_port_suspend(ohci_at91->sfr_regmap, | ||
403 | 0); | ||
404 | return 0; | ||
405 | } | ||
406 | break; | ||
345 | } | 407 | } |
346 | break; | 408 | break; |
347 | } | 409 | } |
@@ -599,6 +661,8 @@ ohci_hcd_at91_drv_suspend(struct device *dev) | |||
599 | if (ohci_at91->wakeup) | 661 | if (ohci_at91->wakeup) |
600 | enable_irq_wake(hcd->irq); | 662 | enable_irq_wake(hcd->irq); |
601 | 663 | ||
664 | ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); | ||
665 | |||
602 | ret = ohci_suspend(hcd, ohci_at91->wakeup); | 666 | ret = ohci_suspend(hcd, ohci_at91->wakeup); |
603 | if (ret) { | 667 | if (ret) { |
604 | if (ohci_at91->wakeup) | 668 | if (ohci_at91->wakeup) |
@@ -638,6 +702,9 @@ ohci_hcd_at91_drv_resume(struct device *dev) | |||
638 | at91_start_clock(ohci_at91); | 702 | at91_start_clock(ohci_at91); |
639 | 703 | ||
640 | ohci_resume(hcd, false); | 704 | ohci_resume(hcd, false); |
705 | |||
706 | ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); | ||
707 | |||
641 | return 0; | 708 | return 0; |
642 | } | 709 | } |
643 | 710 | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index de7c68602a7e..495c1454b9e8 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <mach/mux.h> | 36 | #include <mach/mux.h> |
37 | 37 | ||
38 | #include <mach/hardware.h> | 38 | #include <mach/hardware.h> |
39 | #include <mach/irqs.h> | ||
40 | #include <mach/usb.h> | 39 | #include <mach/usb.h> |
41 | 40 | ||
42 | 41 | ||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 2ac266d692a2..3a9ea32508df 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -13,9 +13,7 @@ | |||
13 | * This file is licenced under the GPL. | 13 | * This file is licenced under the GPL. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <mach/hardware.h> | ||
17 | #include <asm/mach-types.h> | 16 | #include <asm/mach-types.h> |
18 | #include <mach/assabet.h> | ||
19 | #include <asm/hardware/sa1111.h> | 17 | #include <asm/hardware/sa1111.h> |
20 | 18 | ||
21 | #ifndef CONFIG_SA1111 | 19 | #ifndef CONFIG_SA1111 |
@@ -127,7 +125,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) | |||
127 | dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n"); | 125 | dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n"); |
128 | 126 | ||
129 | if (machine_is_xp860() || | 127 | if (machine_is_xp860() || |
130 | machine_has_neponset() || | 128 | machine_is_assabet() || |
131 | machine_is_pfs168() || | 129 | machine_is_pfs168() || |
132 | machine_is_badge4()) | 130 | machine_is_badge4()) |
133 | usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW; | 131 | usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index a7de8e8bb458..5d3d914ab4fb 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -601,11 +601,8 @@ static int uhci_start(struct usb_hcd *hcd) | |||
601 | 601 | ||
602 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), | 602 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), |
603 | GFP_KERNEL); | 603 | GFP_KERNEL); |
604 | if (!uhci->frame_cpu) { | 604 | if (!uhci->frame_cpu) |
605 | dev_err(uhci_dev(uhci), | ||
606 | "unable to allocate memory for frame pointers\n"); | ||
607 | goto err_alloc_frame_cpu; | 605 | goto err_alloc_frame_cpu; |
608 | } | ||
609 | 606 | ||
610 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), | 607 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
611 | sizeof(struct uhci_td), 16, 0); | 608 | sizeof(struct uhci_td), 16, 0); |
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c index e36372393bb1..ad8eb575c30a 100644 --- a/drivers/usb/host/whci/init.c +++ b/drivers/usb/host/whci/init.c | |||
@@ -65,7 +65,7 @@ int whc_init(struct whc *whc) | |||
65 | init_waitqueue_head(&whc->cmd_wq); | 65 | init_waitqueue_head(&whc->cmd_wq); |
66 | init_waitqueue_head(&whc->async_list_wq); | 66 | init_waitqueue_head(&whc->async_list_wq); |
67 | init_waitqueue_head(&whc->periodic_list_wq); | 67 | init_waitqueue_head(&whc->periodic_list_wq); |
68 | whc->workqueue = create_singlethread_workqueue(dev_name(&whc->umc->dev)); | 68 | whc->workqueue = alloc_ordered_workqueue(dev_name(&whc->umc->dev), 0); |
69 | if (whc->workqueue == NULL) { | 69 | if (whc->workqueue == NULL) { |
70 | ret = -ENOMEM; | 70 | ret = -ENOMEM; |
71 | goto error; | 71 | goto error; |
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 0f53ae0f464e..a59fafb4b329 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c | |||
@@ -1033,7 +1033,6 @@ static int tegra_xusb_probe(struct platform_device *pdev) | |||
1033 | tegra->phys = devm_kcalloc(&pdev->dev, tegra->num_phys, | 1033 | tegra->phys = devm_kcalloc(&pdev->dev, tegra->num_phys, |
1034 | sizeof(*tegra->phys), GFP_KERNEL); | 1034 | sizeof(*tegra->phys), GFP_KERNEL); |
1035 | if (!tegra->phys) { | 1035 | if (!tegra->phys) { |
1036 | dev_err(&pdev->dev, "failed to allocate PHY array\n"); | ||
1037 | err = -ENOMEM; | 1036 | err = -ENOMEM; |
1038 | goto put_padctl; | 1037 | goto put_padctl; |
1039 | } | 1038 | } |
@@ -1117,6 +1116,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) | |||
1117 | tegra->hcd); | 1116 | tegra->hcd); |
1118 | if (!xhci->shared_hcd) { | 1117 | if (!xhci->shared_hcd) { |
1119 | dev_err(&pdev->dev, "failed to create shared HCD\n"); | 1118 | dev_err(&pdev->dev, "failed to create shared HCD\n"); |
1119 | err = -ENOMEM; | ||
1120 | goto remove_usb2; | 1120 | goto remove_usb2; |
1121 | } | 1121 | } |
1122 | 1122 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01d96c9b3a75..1a4ca02729c2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -295,10 +295,8 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) | |||
295 | xhci->msix_entries = | 295 | xhci->msix_entries = |
296 | kmalloc((sizeof(struct msix_entry))*xhci->msix_count, | 296 | kmalloc((sizeof(struct msix_entry))*xhci->msix_count, |
297 | GFP_KERNEL); | 297 | GFP_KERNEL); |
298 | if (!xhci->msix_entries) { | 298 | if (!xhci->msix_entries) |
299 | xhci_err(xhci, "Failed to allocate MSI-X entries\n"); | ||
300 | return -ENOMEM; | 299 | return -ENOMEM; |
301 | } | ||
302 | 300 | ||
303 | for (i = 0; i < xhci->msix_count; i++) { | 301 | for (i = 0; i < xhci->msix_count; i++) { |
304 | xhci->msix_entries[i].entry = i; | 302 | xhci->msix_entries[i].entry = i; |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index eb8f8d37cd95..47b357760afc 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -240,6 +240,12 @@ config USB_HSIC_USB3503 | |||
240 | help | 240 | help |
241 | This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver. | 241 | This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver. |
242 | 242 | ||
243 | config USB_HSIC_USB4604 | ||
244 | tristate "USB4604 HSIC to USB20 Driver" | ||
245 | depends on I2C | ||
246 | help | ||
247 | This option enables support for SMSC USB4604 HSIC to USB 2.0 Driver. | ||
248 | |||
243 | config USB_LINK_LAYER_TEST | 249 | config USB_LINK_LAYER_TEST |
244 | tristate "USB Link Layer Test driver" | 250 | tristate "USB Link Layer Test driver" |
245 | help | 251 | help |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 3d79faaad2fb..3d1992750da4 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_USB_USS720) += uss720.o | |||
24 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o | 24 | obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o |
25 | obj-$(CONFIG_USB_YUREX) += yurex.o | 25 | obj-$(CONFIG_USB_YUREX) += yurex.o |
26 | obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o | 26 | obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o |
27 | obj-$(CONFIG_USB_HSIC_USB4604) += usb4604.o | ||
27 | obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o | 28 | obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o |
28 | obj-$(CONFIG_UCSI) += ucsi.o | 29 | obj-$(CONFIG_UCSI) += ucsi.o |
29 | 30 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 3071c0ef909b..564268fca07a 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -672,8 +672,7 @@ static int adu_probe(struct usb_interface *interface, | |||
672 | 672 | ||
673 | /* allocate memory for our device state and initialize it */ | 673 | /* allocate memory for our device state and initialize it */ |
674 | dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); | 674 | dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); |
675 | if (dev == NULL) { | 675 | if (!dev) { |
676 | dev_err(&interface->dev, "Out of memory\n"); | ||
677 | retval = -ENOMEM; | 676 | retval = -ENOMEM; |
678 | goto exit; | 677 | goto exit; |
679 | } | 678 | } |
@@ -710,7 +709,6 @@ static int adu_probe(struct usb_interface *interface, | |||
710 | 709 | ||
711 | dev->read_buffer_primary = kmalloc((4 * in_end_size), GFP_KERNEL); | 710 | dev->read_buffer_primary = kmalloc((4 * in_end_size), GFP_KERNEL); |
712 | if (!dev->read_buffer_primary) { | 711 | if (!dev->read_buffer_primary) { |
713 | dev_err(&interface->dev, "Couldn't allocate read_buffer_primary\n"); | ||
714 | retval = -ENOMEM; | 712 | retval = -ENOMEM; |
715 | goto error; | 713 | goto error; |
716 | } | 714 | } |
@@ -723,7 +721,6 @@ static int adu_probe(struct usb_interface *interface, | |||
723 | 721 | ||
724 | dev->read_buffer_secondary = kmalloc((4 * in_end_size), GFP_KERNEL); | 722 | dev->read_buffer_secondary = kmalloc((4 * in_end_size), GFP_KERNEL); |
725 | if (!dev->read_buffer_secondary) { | 723 | if (!dev->read_buffer_secondary) { |
726 | dev_err(&interface->dev, "Couldn't allocate read_buffer_secondary\n"); | ||
727 | retval = -ENOMEM; | 724 | retval = -ENOMEM; |
728 | goto error; | 725 | goto error; |
729 | } | 726 | } |
@@ -735,29 +732,21 @@ static int adu_probe(struct usb_interface *interface, | |||
735 | memset(dev->read_buffer_secondary + (3 * in_end_size), 'h', in_end_size); | 732 | memset(dev->read_buffer_secondary + (3 * in_end_size), 'h', in_end_size); |
736 | 733 | ||
737 | dev->interrupt_in_buffer = kmalloc(in_end_size, GFP_KERNEL); | 734 | dev->interrupt_in_buffer = kmalloc(in_end_size, GFP_KERNEL); |
738 | if (!dev->interrupt_in_buffer) { | 735 | if (!dev->interrupt_in_buffer) |
739 | dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n"); | ||
740 | goto error; | 736 | goto error; |
741 | } | ||
742 | 737 | ||
743 | /* debug code prime the buffer */ | 738 | /* debug code prime the buffer */ |
744 | memset(dev->interrupt_in_buffer, 'i', in_end_size); | 739 | memset(dev->interrupt_in_buffer, 'i', in_end_size); |
745 | 740 | ||
746 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 741 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
747 | if (!dev->interrupt_in_urb) { | 742 | if (!dev->interrupt_in_urb) |
748 | dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n"); | ||
749 | goto error; | 743 | goto error; |
750 | } | ||
751 | dev->interrupt_out_buffer = kmalloc(out_end_size, GFP_KERNEL); | 744 | dev->interrupt_out_buffer = kmalloc(out_end_size, GFP_KERNEL); |
752 | if (!dev->interrupt_out_buffer) { | 745 | if (!dev->interrupt_out_buffer) |
753 | dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n"); | ||
754 | goto error; | 746 | goto error; |
755 | } | ||
756 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 747 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); |
757 | if (!dev->interrupt_out_urb) { | 748 | if (!dev->interrupt_out_urb) |
758 | dev_err(&interface->dev, "Couldn't allocate interrupt_out_urb\n"); | ||
759 | goto error; | 749 | goto error; |
760 | } | ||
761 | 750 | ||
762 | if (!usb_string(udev, udev->descriptor.iSerialNumber, dev->serial_number, | 751 | if (!usb_string(udev, udev->descriptor.iSerialNumber, dev->serial_number, |
763 | sizeof(dev->serial_number))) { | 752 | sizeof(dev->serial_number))) { |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index a0a3827b4aff..da5ff401a354 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -85,7 +85,6 @@ struct appledisplay { | |||
85 | }; | 85 | }; |
86 | 86 | ||
87 | static atomic_t count_displays = ATOMIC_INIT(0); | 87 | static atomic_t count_displays = ATOMIC_INIT(0); |
88 | static struct workqueue_struct *wq; | ||
89 | 88 | ||
90 | static void appledisplay_complete(struct urb *urb) | 89 | static void appledisplay_complete(struct urb *urb) |
91 | { | 90 | { |
@@ -122,7 +121,7 @@ static void appledisplay_complete(struct urb *urb) | |||
122 | case ACD_BTN_BRIGHT_UP: | 121 | case ACD_BTN_BRIGHT_UP: |
123 | case ACD_BTN_BRIGHT_DOWN: | 122 | case ACD_BTN_BRIGHT_DOWN: |
124 | pdata->button_pressed = 1; | 123 | pdata->button_pressed = 1; |
125 | queue_delayed_work(wq, &pdata->work, 0); | 124 | schedule_delayed_work(&pdata->work, 0); |
126 | break; | 125 | break; |
127 | case ACD_BTN_NONE: | 126 | case ACD_BTN_NONE: |
128 | default: | 127 | default: |
@@ -239,7 +238,6 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
239 | pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); | 238 | pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); |
240 | if (!pdata) { | 239 | if (!pdata) { |
241 | retval = -ENOMEM; | 240 | retval = -ENOMEM; |
242 | dev_err(&iface->dev, "Out of memory\n"); | ||
243 | goto error; | 241 | goto error; |
244 | } | 242 | } |
245 | 243 | ||
@@ -253,8 +251,6 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
253 | pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); | 251 | pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); |
254 | if (!pdata->msgdata) { | 252 | if (!pdata->msgdata) { |
255 | retval = -ENOMEM; | 253 | retval = -ENOMEM; |
256 | dev_err(&iface->dev, | ||
257 | "Allocating buffer for control messages failed\n"); | ||
258 | goto error; | 254 | goto error; |
259 | } | 255 | } |
260 | 256 | ||
@@ -262,7 +258,6 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
262 | pdata->urb = usb_alloc_urb(0, GFP_KERNEL); | 258 | pdata->urb = usb_alloc_urb(0, GFP_KERNEL); |
263 | if (!pdata->urb) { | 259 | if (!pdata->urb) { |
264 | retval = -ENOMEM; | 260 | retval = -ENOMEM; |
265 | dev_err(&iface->dev, "Allocating URB failed\n"); | ||
266 | goto error; | 261 | goto error; |
267 | } | 262 | } |
268 | 263 | ||
@@ -344,7 +339,7 @@ static void appledisplay_disconnect(struct usb_interface *iface) | |||
344 | 339 | ||
345 | if (pdata) { | 340 | if (pdata) { |
346 | usb_kill_urb(pdata->urb); | 341 | usb_kill_urb(pdata->urb); |
347 | cancel_delayed_work(&pdata->work); | 342 | cancel_delayed_work_sync(&pdata->work); |
348 | backlight_device_unregister(pdata->bd); | 343 | backlight_device_unregister(pdata->bd); |
349 | usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN, | 344 | usb_free_coherent(pdata->udev, ACD_URB_BUFFER_LEN, |
350 | pdata->urbdata, pdata->urb->transfer_dma); | 345 | pdata->urbdata, pdata->urb->transfer_dma); |
@@ -365,19 +360,11 @@ static struct usb_driver appledisplay_driver = { | |||
365 | 360 | ||
366 | static int __init appledisplay_init(void) | 361 | static int __init appledisplay_init(void) |
367 | { | 362 | { |
368 | wq = create_singlethread_workqueue("appledisplay"); | ||
369 | if (!wq) { | ||
370 | printk(KERN_ERR "appledisplay: Could not create work queue\n"); | ||
371 | return -ENOMEM; | ||
372 | } | ||
373 | |||
374 | return usb_register(&appledisplay_driver); | 363 | return usb_register(&appledisplay_driver); |
375 | } | 364 | } |
376 | 365 | ||
377 | static void __exit appledisplay_exit(void) | 366 | static void __exit appledisplay_exit(void) |
378 | { | 367 | { |
379 | flush_workqueue(wq); | ||
380 | destroy_workqueue(wq); | ||
381 | usb_deregister(&appledisplay_driver); | 368 | usb_deregister(&appledisplay_driver); |
382 | } | 369 | } |
383 | 370 | ||
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 402b94dd2531..5c93a888c40e 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c | |||
@@ -79,7 +79,6 @@ static int vendor_command(struct cypress *dev, unsigned char request, | |||
79 | /* allocate some memory for the i/o buffer*/ | 79 | /* allocate some memory for the i/o buffer*/ |
80 | iobuf = kzalloc(CYPRESS_MAX_REQSIZE, GFP_KERNEL); | 80 | iobuf = kzalloc(CYPRESS_MAX_REQSIZE, GFP_KERNEL); |
81 | if (!iobuf) { | 81 | if (!iobuf) { |
82 | dev_err(&dev->udev->dev, "Out of memory!\n"); | ||
83 | retval = -ENOMEM; | 82 | retval = -ENOMEM; |
84 | goto error; | 83 | goto error; |
85 | } | 84 | } |
@@ -208,10 +207,8 @@ static int cypress_probe(struct usb_interface *interface, | |||
208 | 207 | ||
209 | /* allocate memory for our device state and initialize it */ | 208 | /* allocate memory for our device state and initialize it */ |
210 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 209 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
211 | if (dev == NULL) { | 210 | if (!dev) |
212 | dev_err(&interface->dev, "Out of memory!\n"); | ||
213 | goto error_mem; | 211 | goto error_mem; |
214 | } | ||
215 | 212 | ||
216 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 213 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
217 | 214 | ||
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 9bab1a33bc16..9d8bb8dacdcd 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
@@ -101,10 +101,8 @@ static ssize_t set_brightness(struct device *dev, struct device_attribute *attr, | |||
101 | int retval; | 101 | int retval; |
102 | 102 | ||
103 | buffer = kmalloc(8, GFP_KERNEL); | 103 | buffer = kmalloc(8, GFP_KERNEL); |
104 | if (!buffer) { | 104 | if (!buffer) |
105 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
106 | return 0; | 105 | return 0; |
107 | } | ||
108 | 106 | ||
109 | cytherm->brightness = simple_strtoul(buf, NULL, 10); | 107 | cytherm->brightness = simple_strtoul(buf, NULL, 10); |
110 | 108 | ||
@@ -148,10 +146,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char | |||
148 | int temp, sign; | 146 | int temp, sign; |
149 | 147 | ||
150 | buffer = kmalloc(8, GFP_KERNEL); | 148 | buffer = kmalloc(8, GFP_KERNEL); |
151 | if (!buffer) { | 149 | if (!buffer) |
152 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
153 | return 0; | 150 | return 0; |
154 | } | ||
155 | 151 | ||
156 | /* read temperature */ | 152 | /* read temperature */ |
157 | retval = vendor_command(cytherm->udev, READ_RAM, TEMP, 0, buffer, 8); | 153 | retval = vendor_command(cytherm->udev, READ_RAM, TEMP, 0, buffer, 8); |
@@ -192,10 +188,8 @@ static ssize_t show_button(struct device *dev, struct device_attribute *attr, ch | |||
192 | unsigned char *buffer; | 188 | unsigned char *buffer; |
193 | 189 | ||
194 | buffer = kmalloc(8, GFP_KERNEL); | 190 | buffer = kmalloc(8, GFP_KERNEL); |
195 | if (!buffer) { | 191 | if (!buffer) |
196 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
197 | return 0; | 192 | return 0; |
198 | } | ||
199 | 193 | ||
200 | /* check button */ | 194 | /* check button */ |
201 | retval = vendor_command(cytherm->udev, READ_RAM, BUTTON, 0, buffer, 8); | 195 | retval = vendor_command(cytherm->udev, READ_RAM, BUTTON, 0, buffer, 8); |
@@ -230,10 +224,8 @@ static ssize_t show_port0(struct device *dev, struct device_attribute *attr, cha | |||
230 | unsigned char *buffer; | 224 | unsigned char *buffer; |
231 | 225 | ||
232 | buffer = kmalloc(8, GFP_KERNEL); | 226 | buffer = kmalloc(8, GFP_KERNEL); |
233 | if (!buffer) { | 227 | if (!buffer) |
234 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
235 | return 0; | 228 | return 0; |
236 | } | ||
237 | 229 | ||
238 | retval = vendor_command(cytherm->udev, READ_PORT, 0, 0, buffer, 8); | 230 | retval = vendor_command(cytherm->udev, READ_PORT, 0, 0, buffer, 8); |
239 | if (retval) | 231 | if (retval) |
@@ -257,10 +249,8 @@ static ssize_t set_port0(struct device *dev, struct device_attribute *attr, cons | |||
257 | int tmp; | 249 | int tmp; |
258 | 250 | ||
259 | buffer = kmalloc(8, GFP_KERNEL); | 251 | buffer = kmalloc(8, GFP_KERNEL); |
260 | if (!buffer) { | 252 | if (!buffer) |
261 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
262 | return 0; | 253 | return 0; |
263 | } | ||
264 | 254 | ||
265 | tmp = simple_strtoul(buf, NULL, 10); | 255 | tmp = simple_strtoul(buf, NULL, 10); |
266 | 256 | ||
@@ -290,10 +280,8 @@ static ssize_t show_port1(struct device *dev, struct device_attribute *attr, cha | |||
290 | unsigned char *buffer; | 280 | unsigned char *buffer; |
291 | 281 | ||
292 | buffer = kmalloc(8, GFP_KERNEL); | 282 | buffer = kmalloc(8, GFP_KERNEL); |
293 | if (!buffer) { | 283 | if (!buffer) |
294 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
295 | return 0; | 284 | return 0; |
296 | } | ||
297 | 285 | ||
298 | retval = vendor_command(cytherm->udev, READ_PORT, 1, 0, buffer, 8); | 286 | retval = vendor_command(cytherm->udev, READ_PORT, 1, 0, buffer, 8); |
299 | if (retval) | 287 | if (retval) |
@@ -317,10 +305,8 @@ static ssize_t set_port1(struct device *dev, struct device_attribute *attr, cons | |||
317 | int tmp; | 305 | int tmp; |
318 | 306 | ||
319 | buffer = kmalloc(8, GFP_KERNEL); | 307 | buffer = kmalloc(8, GFP_KERNEL); |
320 | if (!buffer) { | 308 | if (!buffer) |
321 | dev_err(&cytherm->udev->dev, "out of memory\n"); | ||
322 | return 0; | 309 | return 0; |
323 | } | ||
324 | 310 | ||
325 | tmp = simple_strtoul(buf, NULL, 10); | 311 | tmp = simple_strtoul(buf, NULL, 10); |
326 | 312 | ||
@@ -351,10 +337,8 @@ static int cytherm_probe(struct usb_interface *interface, | |||
351 | int retval = -ENOMEM; | 337 | int retval = -ENOMEM; |
352 | 338 | ||
353 | dev = kzalloc (sizeof(struct usb_cytherm), GFP_KERNEL); | 339 | dev = kzalloc (sizeof(struct usb_cytherm), GFP_KERNEL); |
354 | if (dev == NULL) { | 340 | if (!dev) |
355 | dev_err (&interface->dev, "Out of memory\n"); | ||
356 | goto error_mem; | 341 | goto error_mem; |
357 | } | ||
358 | 342 | ||
359 | dev->udev = usb_get_dev(udev); | 343 | dev->udev = usb_get_dev(udev); |
360 | 344 | ||
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c index 947811bc8126..837208f14f86 100644 --- a/drivers/usb/misc/ezusb.c +++ b/drivers/usb/misc/ezusb.c | |||
@@ -22,7 +22,7 @@ struct ezusb_fx_type { | |||
22 | unsigned short max_internal_adress; | 22 | unsigned short max_internal_adress; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static struct ezusb_fx_type ezusb_fx1 = { | 25 | static const struct ezusb_fx_type ezusb_fx1 = { |
26 | .cpucs_reg = 0x7F92, | 26 | .cpucs_reg = 0x7F92, |
27 | .max_internal_adress = 0x1B3F, | 27 | .max_internal_adress = 0x1B3F, |
28 | }; | 28 | }; |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 9b5b3b2281ca..9a82f8308ad7 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -61,9 +61,6 @@ module_param(distrust_firmware, bool, 0); | |||
61 | MODULE_PARM_DESC(distrust_firmware, | 61 | MODULE_PARM_DESC(distrust_firmware, |
62 | "true to distrust firmware power/overcurrent setup"); | 62 | "true to distrust firmware power/overcurrent setup"); |
63 | extern struct platform_driver u132_platform_driver; | 63 | extern struct platform_driver u132_platform_driver; |
64 | static struct workqueue_struct *status_queue; | ||
65 | static struct workqueue_struct *command_queue; | ||
66 | static struct workqueue_struct *respond_queue; | ||
67 | /* | 64 | /* |
68 | * ftdi_module_lock exists to protect access to global variables | 65 | * ftdi_module_lock exists to protect access to global variables |
69 | * | 66 | * |
@@ -228,56 +225,56 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi) | |||
228 | 225 | ||
229 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 226 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
230 | { | 227 | { |
231 | if (!queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 228 | if (!schedule_delayed_work(&ftdi->status_work, delta)) |
232 | kref_put(&ftdi->kref, ftdi_elan_delete); | 229 | kref_put(&ftdi->kref, ftdi_elan_delete); |
233 | } | 230 | } |
234 | 231 | ||
235 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 232 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
236 | { | 233 | { |
237 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 234 | if (schedule_delayed_work(&ftdi->status_work, delta)) |
238 | kref_get(&ftdi->kref); | 235 | kref_get(&ftdi->kref); |
239 | } | 236 | } |
240 | 237 | ||
241 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) | 238 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) |
242 | { | 239 | { |
243 | if (cancel_delayed_work(&ftdi->status_work)) | 240 | if (cancel_delayed_work_sync(&ftdi->status_work)) |
244 | kref_put(&ftdi->kref, ftdi_elan_delete); | 241 | kref_put(&ftdi->kref, ftdi_elan_delete); |
245 | } | 242 | } |
246 | 243 | ||
247 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 244 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
248 | { | 245 | { |
249 | if (!queue_delayed_work(command_queue, &ftdi->command_work, delta)) | 246 | if (!schedule_delayed_work(&ftdi->command_work, delta)) |
250 | kref_put(&ftdi->kref, ftdi_elan_delete); | 247 | kref_put(&ftdi->kref, ftdi_elan_delete); |
251 | } | 248 | } |
252 | 249 | ||
253 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 250 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
254 | { | 251 | { |
255 | if (queue_delayed_work(command_queue, &ftdi->command_work, delta)) | 252 | if (schedule_delayed_work(&ftdi->command_work, delta)) |
256 | kref_get(&ftdi->kref); | 253 | kref_get(&ftdi->kref); |
257 | } | 254 | } |
258 | 255 | ||
259 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) | 256 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) |
260 | { | 257 | { |
261 | if (cancel_delayed_work(&ftdi->command_work)) | 258 | if (cancel_delayed_work_sync(&ftdi->command_work)) |
262 | kref_put(&ftdi->kref, ftdi_elan_delete); | 259 | kref_put(&ftdi->kref, ftdi_elan_delete); |
263 | } | 260 | } |
264 | 261 | ||
265 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, | 262 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, |
266 | unsigned int delta) | 263 | unsigned int delta) |
267 | { | 264 | { |
268 | if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) | 265 | if (!schedule_delayed_work(&ftdi->respond_work, delta)) |
269 | kref_put(&ftdi->kref, ftdi_elan_delete); | 266 | kref_put(&ftdi->kref, ftdi_elan_delete); |
270 | } | 267 | } |
271 | 268 | ||
272 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 269 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
273 | { | 270 | { |
274 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) | 271 | if (schedule_delayed_work(&ftdi->respond_work, delta)) |
275 | kref_get(&ftdi->kref); | 272 | kref_get(&ftdi->kref); |
276 | } | 273 | } |
277 | 274 | ||
278 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) | 275 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) |
279 | { | 276 | { |
280 | if (cancel_delayed_work(&ftdi->respond_work)) | 277 | if (cancel_delayed_work_sync(&ftdi->respond_work)) |
281 | kref_put(&ftdi->kref, ftdi_elan_delete); | 278 | kref_put(&ftdi->kref, ftdi_elan_delete); |
282 | } | 279 | } |
283 | 280 | ||
@@ -785,11 +782,8 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi) | |||
785 | return 0; | 782 | return 0; |
786 | total_size = ftdi_elan_total_command_size(ftdi, command_size); | 783 | total_size = ftdi_elan_total_command_size(ftdi, command_size); |
787 | urb = usb_alloc_urb(0, GFP_KERNEL); | 784 | urb = usb_alloc_urb(0, GFP_KERNEL); |
788 | if (!urb) { | 785 | if (!urb) |
789 | dev_err(&ftdi->udev->dev, "could not get a urb to write %d commands totaling %d bytes to the Uxxx\n", | ||
790 | command_size, total_size); | ||
791 | return -ENOMEM; | 786 | return -ENOMEM; |
792 | } | ||
793 | buf = usb_alloc_coherent(ftdi->udev, total_size, GFP_KERNEL, | 787 | buf = usb_alloc_coherent(ftdi->udev, total_size, GFP_KERNEL, |
794 | &urb->transfer_dma); | 788 | &urb->transfer_dma); |
795 | if (!buf) { | 789 | if (!buf) { |
@@ -1948,10 +1942,8 @@ static int ftdi_elan_synchronize_flush(struct usb_ftdi *ftdi) | |||
1948 | int I = 257; | 1942 | int I = 257; |
1949 | int i = 0; | 1943 | int i = 0; |
1950 | urb = usb_alloc_urb(0, GFP_KERNEL); | 1944 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1951 | if (!urb) { | 1945 | if (!urb) |
1952 | dev_err(&ftdi->udev->dev, "could not alloc a urb for flush sequence\n"); | ||
1953 | return -ENOMEM; | 1946 | return -ENOMEM; |
1954 | } | ||
1955 | buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma); | 1947 | buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma); |
1956 | if (!buf) { | 1948 | if (!buf) { |
1957 | dev_err(&ftdi->udev->dev, "could not get a buffer for flush sequence\n"); | 1949 | dev_err(&ftdi->udev->dev, "could not get a buffer for flush sequence\n"); |
@@ -1988,10 +1980,8 @@ static int ftdi_elan_synchronize_reset(struct usb_ftdi *ftdi) | |||
1988 | int I = 4; | 1980 | int I = 4; |
1989 | int i = 0; | 1981 | int i = 0; |
1990 | urb = usb_alloc_urb(0, GFP_KERNEL); | 1982 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1991 | if (!urb) { | 1983 | if (!urb) |
1992 | dev_err(&ftdi->udev->dev, "could not get a urb for the reset sequence\n"); | ||
1993 | return -ENOMEM; | 1984 | return -ENOMEM; |
1994 | } | ||
1995 | buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma); | 1985 | buf = usb_alloc_coherent(ftdi->udev, I, GFP_KERNEL, &urb->transfer_dma); |
1996 | if (!buf) { | 1986 | if (!buf) { |
1997 | dev_err(&ftdi->udev->dev, "could not get a buffer for the reset sequence\n"); | 1987 | dev_err(&ftdi->udev->dev, "could not get a buffer for the reset sequence\n"); |
@@ -2740,7 +2730,6 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2740 | ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress; | 2730 | ftdi->bulk_in_endpointAddr = endpoint->bEndpointAddress; |
2741 | ftdi->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | 2731 | ftdi->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); |
2742 | if (!ftdi->bulk_in_buffer) { | 2732 | if (!ftdi->bulk_in_buffer) { |
2743 | dev_err(&ftdi->udev->dev, "Could not allocate bulk_in_buffer\n"); | ||
2744 | retval = -ENOMEM; | 2733 | retval = -ENOMEM; |
2745 | goto error; | 2734 | goto error; |
2746 | } | 2735 | } |
@@ -2823,9 +2812,6 @@ static void ftdi_elan_disconnect(struct usb_interface *interface) | |||
2823 | ftdi->initialized = 0; | 2812 | ftdi->initialized = 0; |
2824 | ftdi->registered = 0; | 2813 | ftdi->registered = 0; |
2825 | } | 2814 | } |
2826 | flush_workqueue(status_queue); | ||
2827 | flush_workqueue(command_queue); | ||
2828 | flush_workqueue(respond_queue); | ||
2829 | ftdi->disconnected += 1; | 2815 | ftdi->disconnected += 1; |
2830 | usb_set_intfdata(interface, NULL); | 2816 | usb_set_intfdata(interface, NULL); |
2831 | dev_info(&ftdi->udev->dev, "USB FTDI U132 host controller interface now disconnected\n"); | 2817 | dev_info(&ftdi->udev->dev, "USB FTDI U132 host controller interface now disconnected\n"); |
@@ -2845,31 +2831,12 @@ static int __init ftdi_elan_init(void) | |||
2845 | pr_info("driver %s\n", ftdi_elan_driver.name); | 2831 | pr_info("driver %s\n", ftdi_elan_driver.name); |
2846 | mutex_init(&ftdi_module_lock); | 2832 | mutex_init(&ftdi_module_lock); |
2847 | INIT_LIST_HEAD(&ftdi_static_list); | 2833 | INIT_LIST_HEAD(&ftdi_static_list); |
2848 | status_queue = create_singlethread_workqueue("ftdi-status-control"); | ||
2849 | if (!status_queue) | ||
2850 | goto err_status_queue; | ||
2851 | command_queue = create_singlethread_workqueue("ftdi-command-engine"); | ||
2852 | if (!command_queue) | ||
2853 | goto err_command_queue; | ||
2854 | respond_queue = create_singlethread_workqueue("ftdi-respond-engine"); | ||
2855 | if (!respond_queue) | ||
2856 | goto err_respond_queue; | ||
2857 | result = usb_register(&ftdi_elan_driver); | 2834 | result = usb_register(&ftdi_elan_driver); |
2858 | if (result) { | 2835 | if (result) { |
2859 | destroy_workqueue(status_queue); | ||
2860 | destroy_workqueue(command_queue); | ||
2861 | destroy_workqueue(respond_queue); | ||
2862 | pr_err("usb_register failed. Error number %d\n", result); | 2836 | pr_err("usb_register failed. Error number %d\n", result); |
2863 | } | 2837 | } |
2864 | return result; | 2838 | return result; |
2865 | 2839 | ||
2866 | err_respond_queue: | ||
2867 | destroy_workqueue(command_queue); | ||
2868 | err_command_queue: | ||
2869 | destroy_workqueue(status_queue); | ||
2870 | err_status_queue: | ||
2871 | pr_err("%s couldn't create workqueue\n", ftdi_elan_driver.name); | ||
2872 | return -ENOMEM; | ||
2873 | } | 2840 | } |
2874 | 2841 | ||
2875 | static void __exit ftdi_elan_exit(void) | 2842 | static void __exit ftdi_elan_exit(void) |
@@ -2882,15 +2849,7 @@ static void __exit ftdi_elan_exit(void) | |||
2882 | ftdi_status_cancel_work(ftdi); | 2849 | ftdi_status_cancel_work(ftdi); |
2883 | ftdi_command_cancel_work(ftdi); | 2850 | ftdi_command_cancel_work(ftdi); |
2884 | ftdi_response_cancel_work(ftdi); | 2851 | ftdi_response_cancel_work(ftdi); |
2885 | } flush_workqueue(status_queue); | 2852 | } |
2886 | destroy_workqueue(status_queue); | ||
2887 | status_queue = NULL; | ||
2888 | flush_workqueue(command_queue); | ||
2889 | destroy_workqueue(command_queue); | ||
2890 | command_queue = NULL; | ||
2891 | flush_workqueue(respond_queue); | ||
2892 | destroy_workqueue(respond_queue); | ||
2893 | respond_queue = NULL; | ||
2894 | } | 2853 | } |
2895 | 2854 | ||
2896 | 2855 | ||
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 5105397e62fc..2975e80b7a56 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -366,7 +366,6 @@ static int idmouse_probe(struct usb_interface *interface, | |||
366 | kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL); | 366 | kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL); |
367 | 367 | ||
368 | if (!dev->bulk_in_buffer) { | 368 | if (!dev->bulk_in_buffer) { |
369 | dev_err(&interface->dev, "Unable to allocate input buffer.\n"); | ||
370 | idmouse_delete(dev); | 369 | idmouse_delete(dev); |
371 | return -ENOMEM; | 370 | return -ENOMEM; |
372 | } | 371 | } |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 1950e87b4219..095778ff984d 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -278,7 +278,7 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, | |||
278 | dev = file->private_data; | 278 | dev = file->private_data; |
279 | 279 | ||
280 | /* verify that the device wasn't unplugged */ | 280 | /* verify that the device wasn't unplugged */ |
281 | if (dev == NULL || !dev->present) | 281 | if (!dev || !dev->present) |
282 | return -ENODEV; | 282 | return -ENODEV; |
283 | 283 | ||
284 | dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n", | 284 | dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n", |
@@ -413,8 +413,6 @@ static ssize_t iowarrior_write(struct file *file, | |||
413 | int_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 413 | int_out_urb = usb_alloc_urb(0, GFP_KERNEL); |
414 | if (!int_out_urb) { | 414 | if (!int_out_urb) { |
415 | retval = -ENOMEM; | 415 | retval = -ENOMEM; |
416 | dev_dbg(&dev->interface->dev, | ||
417 | "Unable to allocate urb\n"); | ||
418 | goto error_no_urb; | 416 | goto error_no_urb; |
419 | } | 417 | } |
420 | buf = usb_alloc_coherent(dev->udev, dev->report_size, | 418 | buf = usb_alloc_coherent(dev->udev, dev->report_size, |
@@ -482,9 +480,8 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
482 | int io_res; /* checks for bytes read/written and copy_to/from_user results */ | 480 | int io_res; /* checks for bytes read/written and copy_to/from_user results */ |
483 | 481 | ||
484 | dev = file->private_data; | 482 | dev = file->private_data; |
485 | if (dev == NULL) { | 483 | if (!dev) |
486 | return -ENODEV; | 484 | return -ENODEV; |
487 | } | ||
488 | 485 | ||
489 | buffer = kzalloc(dev->report_size, GFP_KERNEL); | 486 | buffer = kzalloc(dev->report_size, GFP_KERNEL); |
490 | if (!buffer) | 487 | if (!buffer) |
@@ -654,9 +651,8 @@ static int iowarrior_release(struct inode *inode, struct file *file) | |||
654 | int retval = 0; | 651 | int retval = 0; |
655 | 652 | ||
656 | dev = file->private_data; | 653 | dev = file->private_data; |
657 | if (dev == NULL) { | 654 | if (!dev) |
658 | return -ENODEV; | 655 | return -ENODEV; |
659 | } | ||
660 | 656 | ||
661 | dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor); | 657 | dev_dbg(&dev->interface->dev, "minor %d\n", dev->minor); |
662 | 658 | ||
@@ -766,10 +762,8 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
766 | 762 | ||
767 | /* allocate memory for our device state and initialize it */ | 763 | /* allocate memory for our device state and initialize it */ |
768 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); | 764 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); |
769 | if (dev == NULL) { | 765 | if (!dev) |
770 | dev_err(&interface->dev, "Out of memory\n"); | ||
771 | return retval; | 766 | return retval; |
772 | } | ||
773 | 767 | ||
774 | mutex_init(&dev->mutex); | 768 | mutex_init(&dev->mutex); |
775 | 769 | ||
@@ -812,15 +806,11 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
812 | 806 | ||
813 | /* create the urb and buffer for reading */ | 807 | /* create the urb and buffer for reading */ |
814 | dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 808 | dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
815 | if (!dev->int_in_urb) { | 809 | if (!dev->int_in_urb) |
816 | dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n"); | ||
817 | goto error; | 810 | goto error; |
818 | } | ||
819 | dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL); | 811 | dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL); |
820 | if (!dev->int_in_buffer) { | 812 | if (!dev->int_in_buffer) |
821 | dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n"); | ||
822 | goto error; | 813 | goto error; |
823 | } | ||
824 | usb_fill_int_urb(dev->int_in_urb, dev->udev, | 814 | usb_fill_int_urb(dev->int_in_urb, dev->udev, |
825 | usb_rcvintpipe(dev->udev, | 815 | usb_rcvintpipe(dev->udev, |
826 | dev->int_in_endpoint->bEndpointAddress), | 816 | dev->int_in_endpoint->bEndpointAddress), |
@@ -831,10 +821,8 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
831 | dev->read_queue = | 821 | dev->read_queue = |
832 | kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER), | 822 | kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER), |
833 | GFP_KERNEL); | 823 | GFP_KERNEL); |
834 | if (!dev->read_queue) { | 824 | if (!dev->read_queue) |
835 | dev_err(&interface->dev, "Couldn't allocate read_queue\n"); | ||
836 | goto error; | 825 | goto error; |
837 | } | ||
838 | /* Get the serial-number of the chip */ | 826 | /* Get the serial-number of the chip */ |
839 | memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial)); | 827 | memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial)); |
840 | usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial, | 828 | usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index cce22ff1c2eb..9ca595632f17 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -658,10 +658,8 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
658 | /* allocate memory for our device state and initialize it */ | 658 | /* allocate memory for our device state and initialize it */ |
659 | 659 | ||
660 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 660 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
661 | if (dev == NULL) { | 661 | if (!dev) |
662 | dev_err(&intf->dev, "Out of memory\n"); | ||
663 | goto exit; | 662 | goto exit; |
664 | } | ||
665 | mutex_init(&dev->mutex); | 663 | mutex_init(&dev->mutex); |
666 | spin_lock_init(&dev->rbsl); | 664 | spin_lock_init(&dev->rbsl); |
667 | dev->intf = intf; | 665 | dev->intf = intf; |
@@ -674,10 +672,8 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
674 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && | 672 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) && |
675 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { | 673 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { |
676 | buffer = kmalloc(256, GFP_KERNEL); | 674 | buffer = kmalloc(256, GFP_KERNEL); |
677 | if (buffer == NULL) { | 675 | if (!buffer) |
678 | dev_err(&intf->dev, "Couldn't allocate string buffer\n"); | ||
679 | goto error; | 676 | goto error; |
680 | } | ||
681 | /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ | 677 | /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ |
682 | usb_string(udev, 255, buffer, 256); | 678 | usb_string(udev, 255, buffer, 256); |
683 | kfree(buffer); | 679 | kfree(buffer); |
@@ -704,32 +700,22 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
704 | 700 | ||
705 | dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); | 701 | dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); |
706 | dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); | 702 | dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); |
707 | if (!dev->ring_buffer) { | 703 | if (!dev->ring_buffer) |
708 | dev_err(&intf->dev, "Couldn't allocate ring_buffer\n"); | ||
709 | goto error; | 704 | goto error; |
710 | } | ||
711 | dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); | 705 | dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); |
712 | if (!dev->interrupt_in_buffer) { | 706 | if (!dev->interrupt_in_buffer) |
713 | dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n"); | ||
714 | goto error; | 707 | goto error; |
715 | } | ||
716 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 708 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
717 | if (!dev->interrupt_in_urb) { | 709 | if (!dev->interrupt_in_urb) |
718 | dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); | ||
719 | goto error; | 710 | goto error; |
720 | } | ||
721 | dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) : | 711 | dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) : |
722 | udev->descriptor.bMaxPacketSize0; | 712 | udev->descriptor.bMaxPacketSize0; |
723 | dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); | 713 | dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); |
724 | if (!dev->interrupt_out_buffer) { | 714 | if (!dev->interrupt_out_buffer) |
725 | dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n"); | ||
726 | goto error; | 715 | goto error; |
727 | } | ||
728 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 716 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); |
729 | if (!dev->interrupt_out_urb) { | 717 | if (!dev->interrupt_out_urb) |
730 | dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); | ||
731 | goto error; | 718 | goto error; |
732 | } | ||
733 | dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; | 719 | dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; |
734 | if (dev->interrupt_out_endpoint) | 720 | if (dev->interrupt_out_endpoint) |
735 | dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; | 721 | dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 7771be3ac178..c8fbe7b739a0 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -817,10 +817,8 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
817 | 817 | ||
818 | dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL); | 818 | dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL); |
819 | 819 | ||
820 | if (dev == NULL) { | 820 | if (!dev) |
821 | dev_err(idev, "Out of memory\n"); | ||
822 | goto exit; | 821 | goto exit; |
823 | } | ||
824 | 822 | ||
825 | mutex_init(&dev->lock); | 823 | mutex_init(&dev->lock); |
826 | 824 | ||
@@ -871,51 +869,23 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
871 | } | 869 | } |
872 | 870 | ||
873 | dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL); | 871 | dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL); |
874 | if (!dev->read_buffer) { | 872 | if (!dev->read_buffer) |
875 | dev_err(idev, "Couldn't allocate read_buffer\n"); | ||
876 | goto error; | 873 | goto error; |
877 | } | ||
878 | dev->interrupt_in_buffer = kmalloc (usb_endpoint_maxp(dev->interrupt_in_endpoint), GFP_KERNEL); | 874 | dev->interrupt_in_buffer = kmalloc (usb_endpoint_maxp(dev->interrupt_in_endpoint), GFP_KERNEL); |
879 | if (!dev->interrupt_in_buffer) { | 875 | if (!dev->interrupt_in_buffer) |
880 | dev_err(idev, "Couldn't allocate interrupt_in_buffer\n"); | ||
881 | goto error; | 876 | goto error; |
882 | } | ||
883 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 877 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
884 | if (!dev->interrupt_in_urb) { | 878 | if (!dev->interrupt_in_urb) |
885 | dev_err(idev, "Couldn't allocate interrupt_in_urb\n"); | ||
886 | goto error; | 879 | goto error; |
887 | } | ||
888 | dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL); | 880 | dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL); |
889 | if (!dev->interrupt_out_buffer) { | 881 | if (!dev->interrupt_out_buffer) |
890 | dev_err(idev, "Couldn't allocate interrupt_out_buffer\n"); | ||
891 | goto error; | 882 | goto error; |
892 | } | ||
893 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | 883 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); |
894 | if (!dev->interrupt_out_urb) { | 884 | if (!dev->interrupt_out_urb) |
895 | dev_err(idev, "Couldn't allocate interrupt_out_urb\n"); | ||
896 | goto error; | 885 | goto error; |
897 | } | ||
898 | dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; | 886 | dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; |
899 | dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; | 887 | dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; |
900 | 888 | ||
901 | /* we can register the device now, as it is ready */ | ||
902 | usb_set_intfdata (interface, dev); | ||
903 | |||
904 | retval = usb_register_dev (interface, &tower_class); | ||
905 | |||
906 | if (retval) { | ||
907 | /* something prevented us from registering this driver */ | ||
908 | dev_err(idev, "Not able to get a minor for this device.\n"); | ||
909 | usb_set_intfdata (interface, NULL); | ||
910 | goto error; | ||
911 | } | ||
912 | dev->minor = interface->minor; | ||
913 | |||
914 | /* let the user know what node this device is now attached to */ | ||
915 | dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major " | ||
916 | "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), | ||
917 | USB_MAJOR, dev->minor); | ||
918 | |||
919 | /* get the firmware version and log it */ | 889 | /* get the firmware version and log it */ |
920 | result = usb_control_msg (udev, | 890 | result = usb_control_msg (udev, |
921 | usb_rcvctrlpipe(udev, 0), | 891 | usb_rcvctrlpipe(udev, 0), |
@@ -936,6 +906,23 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
936 | get_version_reply.minor, | 906 | get_version_reply.minor, |
937 | le16_to_cpu(get_version_reply.build_no)); | 907 | le16_to_cpu(get_version_reply.build_no)); |
938 | 908 | ||
909 | /* we can register the device now, as it is ready */ | ||
910 | usb_set_intfdata (interface, dev); | ||
911 | |||
912 | retval = usb_register_dev (interface, &tower_class); | ||
913 | |||
914 | if (retval) { | ||
915 | /* something prevented us from registering this driver */ | ||
916 | dev_err(idev, "Not able to get a minor for this device.\n"); | ||
917 | usb_set_intfdata (interface, NULL); | ||
918 | goto error; | ||
919 | } | ||
920 | dev->minor = interface->minor; | ||
921 | |||
922 | /* let the user know what node this device is now attached to */ | ||
923 | dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major " | ||
924 | "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), | ||
925 | USB_MAJOR, dev->minor); | ||
939 | 926 | ||
940 | exit: | 927 | exit: |
941 | return retval; | 928 | return retval; |
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 86b4e4b2ab9a..77176511658f 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c | |||
@@ -34,8 +34,6 @@ struct lvs_rh { | |||
34 | struct usb_hub_descriptor descriptor; | 34 | struct usb_hub_descriptor descriptor; |
35 | /* urb for polling interrupt pipe */ | 35 | /* urb for polling interrupt pipe */ |
36 | struct urb *urb; | 36 | struct urb *urb; |
37 | /* LVS RH work queue */ | ||
38 | struct workqueue_struct *rh_queue; | ||
39 | /* LVH RH work */ | 37 | /* LVH RH work */ |
40 | struct work_struct rh_work; | 38 | struct work_struct rh_work; |
41 | /* RH port status */ | 39 | /* RH port status */ |
@@ -247,10 +245,8 @@ static ssize_t get_dev_desc_store(struct device *dev, | |||
247 | int ret; | 245 | int ret; |
248 | 246 | ||
249 | descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL); | 247 | descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL); |
250 | if (!descriptor) { | 248 | if (!descriptor) |
251 | dev_err(dev, "failed to allocate descriptor memory\n"); | ||
252 | return -ENOMEM; | 249 | return -ENOMEM; |
253 | } | ||
254 | 250 | ||
255 | udev = create_lvs_device(intf); | 251 | udev = create_lvs_device(intf); |
256 | if (!udev) { | 252 | if (!udev) { |
@@ -355,7 +351,7 @@ static void lvs_rh_irq(struct urb *urb) | |||
355 | { | 351 | { |
356 | struct lvs_rh *lvs = urb->context; | 352 | struct lvs_rh *lvs = urb->context; |
357 | 353 | ||
358 | queue_work(lvs->rh_queue, &lvs->rh_work); | 354 | schedule_work(&lvs->rh_work); |
359 | } | 355 | } |
360 | 356 | ||
361 | static int lvs_rh_probe(struct usb_interface *intf, | 357 | static int lvs_rh_probe(struct usb_interface *intf, |
@@ -397,24 +393,15 @@ static int lvs_rh_probe(struct usb_interface *intf, | |||
397 | 393 | ||
398 | /* submit urb to poll interrupt endpoint */ | 394 | /* submit urb to poll interrupt endpoint */ |
399 | lvs->urb = usb_alloc_urb(0, GFP_KERNEL); | 395 | lvs->urb = usb_alloc_urb(0, GFP_KERNEL); |
400 | if (!lvs->urb) { | 396 | if (!lvs->urb) |
401 | dev_err(&intf->dev, "couldn't allocate lvs urb\n"); | ||
402 | return -ENOMEM; | 397 | return -ENOMEM; |
403 | } | ||
404 | |||
405 | lvs->rh_queue = create_singlethread_workqueue("lvs_rh_queue"); | ||
406 | if (!lvs->rh_queue) { | ||
407 | dev_err(&intf->dev, "couldn't create workqueue\n"); | ||
408 | ret = -ENOMEM; | ||
409 | goto free_urb; | ||
410 | } | ||
411 | 398 | ||
412 | INIT_WORK(&lvs->rh_work, lvs_rh_work); | 399 | INIT_WORK(&lvs->rh_work, lvs_rh_work); |
413 | 400 | ||
414 | ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group); | 401 | ret = sysfs_create_group(&intf->dev.kobj, &lvs_attr_group); |
415 | if (ret < 0) { | 402 | if (ret < 0) { |
416 | dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret); | 403 | dev_err(&intf->dev, "Failed to create sysfs node %d\n", ret); |
417 | goto destroy_queue; | 404 | goto free_urb; |
418 | } | 405 | } |
419 | 406 | ||
420 | pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); | 407 | pipe = usb_rcvintpipe(hdev, endpoint->bEndpointAddress); |
@@ -432,8 +419,6 @@ static int lvs_rh_probe(struct usb_interface *intf, | |||
432 | 419 | ||
433 | sysfs_remove: | 420 | sysfs_remove: |
434 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); | 421 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); |
435 | destroy_queue: | ||
436 | destroy_workqueue(lvs->rh_queue); | ||
437 | free_urb: | 422 | free_urb: |
438 | usb_free_urb(lvs->urb); | 423 | usb_free_urb(lvs->urb); |
439 | return ret; | 424 | return ret; |
@@ -444,7 +429,7 @@ static void lvs_rh_disconnect(struct usb_interface *intf) | |||
444 | struct lvs_rh *lvs = usb_get_intfdata(intf); | 429 | struct lvs_rh *lvs = usb_get_intfdata(intf); |
445 | 430 | ||
446 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); | 431 | sysfs_remove_group(&intf->dev.kobj, &lvs_attr_group); |
447 | destroy_workqueue(lvs->rh_queue); | 432 | flush_work(&lvs->rh_work); |
448 | usb_free_urb(lvs->urb); | 433 | usb_free_urb(lvs->urb); |
449 | } | 434 | } |
450 | 435 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 02abfcdfbf7b..05bd39d62568 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -3084,7 +3084,6 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3084 | /* Allocate URBs */ | 3084 | /* Allocate URBs */ |
3085 | sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL); | 3085 | sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL); |
3086 | if (!sisusb->sisurbin) { | 3086 | if (!sisusb->sisurbin) { |
3087 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n"); | ||
3088 | retval = -ENOMEM; | 3087 | retval = -ENOMEM; |
3089 | goto error_3; | 3088 | goto error_3; |
3090 | } | 3089 | } |
@@ -3093,8 +3092,6 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3093 | for (i = 0; i < sisusb->numobufs; i++) { | 3092 | for (i = 0; i < sisusb->numobufs; i++) { |
3094 | sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL); | 3093 | sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL); |
3095 | if (!sisusb->sisurbout[i]) { | 3094 | if (!sisusb->sisurbout[i]) { |
3096 | dev_err(&sisusb->sisusb_dev->dev, | ||
3097 | "Failed to allocate URBs\n"); | ||
3098 | retval = -ENOMEM; | 3095 | retval = -ENOMEM; |
3099 | goto error_4; | 3096 | goto error_4; |
3100 | } | 3097 | } |
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 4145314a515b..9795457723d8 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c | |||
@@ -95,8 +95,7 @@ static int tv_probe(struct usb_interface *interface, | |||
95 | int retval; | 95 | int retval; |
96 | 96 | ||
97 | dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL); | 97 | dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL); |
98 | if (dev == NULL) { | 98 | if (!dev) { |
99 | dev_err(&interface->dev, "Out of memory\n"); | ||
100 | retval = -ENOMEM; | 99 | retval = -ENOMEM; |
101 | goto error; | 100 | goto error; |
102 | } | 101 | } |
diff --git a/drivers/usb/misc/usb4604.c b/drivers/usb/misc/usb4604.c new file mode 100644 index 000000000000..e9f37fb746ac --- /dev/null +++ b/drivers/usb/misc/usb4604.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Driver for SMSC USB4604 USB HSIC 4-port 2.0 hub controller driver | ||
3 | * Based on usb3503 driver | ||
4 | * | ||
5 | * Copyright (c) 2012-2013 Dongjin Kim (tobetter@gmail.com) | ||
6 | * Copyright (c) 2016 Linaro Ltd. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/gpio/consumer.h> | ||
24 | |||
25 | enum usb4604_mode { | ||
26 | USB4604_MODE_UNKNOWN, | ||
27 | USB4604_MODE_HUB, | ||
28 | USB4604_MODE_STANDBY, | ||
29 | }; | ||
30 | |||
31 | struct usb4604 { | ||
32 | enum usb4604_mode mode; | ||
33 | struct device *dev; | ||
34 | struct gpio_desc *gpio_reset; | ||
35 | }; | ||
36 | |||
37 | static void usb4604_reset(struct usb4604 *hub, int state) | ||
38 | { | ||
39 | gpiod_set_value_cansleep(hub->gpio_reset, state); | ||
40 | |||
41 | /* Wait for i2c logic to come up */ | ||
42 | if (state) | ||
43 | msleep(250); | ||
44 | } | ||
45 | |||
46 | static int usb4604_connect(struct usb4604 *hub) | ||
47 | { | ||
48 | struct device *dev = hub->dev; | ||
49 | struct i2c_client *client = to_i2c_client(dev); | ||
50 | int err; | ||
51 | u8 connect_cmd[] = { 0xaa, 0x55, 0x00 }; | ||
52 | |||
53 | usb4604_reset(hub, 1); | ||
54 | |||
55 | err = i2c_master_send(client, connect_cmd, ARRAY_SIZE(connect_cmd)); | ||
56 | if (err < 0) { | ||
57 | usb4604_reset(hub, 0); | ||
58 | return err; | ||
59 | } | ||
60 | |||
61 | hub->mode = USB4604_MODE_HUB; | ||
62 | dev_dbg(dev, "switched to HUB mode\n"); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static int usb4604_switch_mode(struct usb4604 *hub, enum usb4604_mode mode) | ||
68 | { | ||
69 | struct device *dev = hub->dev; | ||
70 | int err = 0; | ||
71 | |||
72 | switch (mode) { | ||
73 | case USB4604_MODE_HUB: | ||
74 | err = usb4604_connect(hub); | ||
75 | break; | ||
76 | |||
77 | case USB4604_MODE_STANDBY: | ||
78 | usb4604_reset(hub, 0); | ||
79 | dev_dbg(dev, "switched to STANDBY mode\n"); | ||
80 | break; | ||
81 | |||
82 | default: | ||
83 | dev_err(dev, "unknown mode is requested\n"); | ||
84 | err = -EINVAL; | ||
85 | break; | ||
86 | } | ||
87 | |||
88 | return err; | ||
89 | } | ||
90 | |||
91 | static int usb4604_probe(struct usb4604 *hub) | ||
92 | { | ||
93 | struct device *dev = hub->dev; | ||
94 | struct device_node *np = dev->of_node; | ||
95 | struct gpio_desc *gpio; | ||
96 | u32 mode = USB4604_MODE_HUB; | ||
97 | |||
98 | gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); | ||
99 | if (IS_ERR(gpio)) | ||
100 | return PTR_ERR(gpio); | ||
101 | hub->gpio_reset = gpio; | ||
102 | |||
103 | if (of_property_read_u32(np, "initial-mode", &hub->mode)) | ||
104 | hub->mode = mode; | ||
105 | |||
106 | return usb4604_switch_mode(hub, hub->mode); | ||
107 | } | ||
108 | |||
109 | static int usb4604_i2c_probe(struct i2c_client *i2c, | ||
110 | const struct i2c_device_id *id) | ||
111 | { | ||
112 | struct usb4604 *hub; | ||
113 | |||
114 | hub = devm_kzalloc(&i2c->dev, sizeof(*hub), GFP_KERNEL); | ||
115 | if (!hub) | ||
116 | return -ENOMEM; | ||
117 | |||
118 | i2c_set_clientdata(i2c, hub); | ||
119 | hub->dev = &i2c->dev; | ||
120 | |||
121 | return usb4604_probe(hub); | ||
122 | } | ||
123 | |||
124 | #ifdef CONFIG_PM_SLEEP | ||
125 | static int usb4604_i2c_suspend(struct device *dev) | ||
126 | { | ||
127 | struct i2c_client *client = to_i2c_client(dev); | ||
128 | struct usb4604 *hub = i2c_get_clientdata(client); | ||
129 | |||
130 | usb4604_switch_mode(hub, USB4604_MODE_STANDBY); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int usb4604_i2c_resume(struct device *dev) | ||
136 | { | ||
137 | struct i2c_client *client = to_i2c_client(dev); | ||
138 | struct usb4604 *hub = i2c_get_clientdata(client); | ||
139 | |||
140 | usb4604_switch_mode(hub, hub->mode); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | #endif | ||
145 | |||
146 | static SIMPLE_DEV_PM_OPS(usb4604_i2c_pm_ops, usb4604_i2c_suspend, | ||
147 | usb4604_i2c_resume); | ||
148 | |||
149 | static const struct i2c_device_id usb4604_id[] = { | ||
150 | { "usb4604", 0 }, | ||
151 | { } | ||
152 | }; | ||
153 | MODULE_DEVICE_TABLE(i2c, usb4604_id); | ||
154 | |||
155 | #ifdef CONFIG_OF | ||
156 | static const struct of_device_id usb4604_of_match[] = { | ||
157 | { .compatible = "smsc,usb4604" }, | ||
158 | {} | ||
159 | }; | ||
160 | MODULE_DEVICE_TABLE(of, usb4604_of_match); | ||
161 | #endif | ||
162 | |||
163 | static struct i2c_driver usb4604_i2c_driver = { | ||
164 | .driver = { | ||
165 | .name = "usb4604", | ||
166 | .pm = &usb4604_i2c_pm_ops, | ||
167 | .of_match_table = of_match_ptr(usb4604_of_match), | ||
168 | }, | ||
169 | .probe = usb4604_i2c_probe, | ||
170 | .id_table = usb4604_id, | ||
171 | }; | ||
172 | module_i2c_driver(usb4604_i2c_driver); | ||
173 | |||
174 | MODULE_DESCRIPTION("USB4604 USB HUB driver"); | ||
175 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 1184390508e9..9f48419abc46 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -321,10 +321,8 @@ static int lcd_probe(struct usb_interface *interface, | |||
321 | 321 | ||
322 | /* allocate memory for our device state and initialize it */ | 322 | /* allocate memory for our device state and initialize it */ |
323 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 323 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
324 | if (dev == NULL) { | 324 | if (!dev) |
325 | dev_err(&interface->dev, "Out of memory\n"); | ||
326 | goto error; | 325 | goto error; |
327 | } | ||
328 | kref_init(&dev->kref); | 326 | kref_init(&dev->kref); |
329 | sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES); | 327 | sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES); |
330 | init_usb_anchor(&dev->submitted); | 328 | init_usb_anchor(&dev->submitted); |
@@ -351,11 +349,8 @@ static int lcd_probe(struct usb_interface *interface, | |||
351 | dev->bulk_in_size = buffer_size; | 349 | dev->bulk_in_size = buffer_size; |
352 | dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; | 350 | dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; |
353 | dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | 351 | dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); |
354 | if (!dev->bulk_in_buffer) { | 352 | if (!dev->bulk_in_buffer) |
355 | dev_err(&interface->dev, | ||
356 | "Could not allocate bulk_in_buffer\n"); | ||
357 | goto error; | 353 | goto error; |
358 | } | ||
359 | } | 354 | } |
360 | 355 | ||
361 | if (!dev->bulk_out_endpointAddr && | 356 | if (!dev->bulk_out_endpointAddr && |
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 1fe6b73c22f3..a0ba5298160c 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c | |||
@@ -128,10 +128,8 @@ static void update_display_visual(struct usb_sevsegdev *mydev, gfp_t mf) | |||
128 | return; | 128 | return; |
129 | 129 | ||
130 | buffer = kzalloc(MAXLEN, mf); | 130 | buffer = kzalloc(MAXLEN, mf); |
131 | if (!buffer) { | 131 | if (!buffer) |
132 | dev_err(&mydev->udev->dev, "out of memory\n"); | ||
133 | return; | 132 | return; |
134 | } | ||
135 | 133 | ||
136 | /* The device is right to left, where as you write left to right */ | 134 | /* The device is right to left, where as you write left to right */ |
137 | for (i = 0; i < mydev->textlength; i++) | 135 | for (i = 0; i < mydev->textlength; i++) |
@@ -346,10 +344,8 @@ static int sevseg_probe(struct usb_interface *interface, | |||
346 | int rc = -ENOMEM; | 344 | int rc = -ENOMEM; |
347 | 345 | ||
348 | mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL); | 346 | mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL); |
349 | if (mydev == NULL) { | 347 | if (!mydev) |
350 | dev_err(&interface->dev, "Out of memory\n"); | ||
351 | goto error_mem; | 348 | goto error_mem; |
352 | } | ||
353 | 349 | ||
354 | mydev->udev = usb_get_dev(udev); | 350 | mydev->udev = usb_get_dev(udev); |
355 | mydev->intf = interface; | 351 | mydev->intf = interface; |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index bbd029c9c725..356d312add57 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -150,10 +150,8 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p | |||
150 | if (!usbdev) | 150 | if (!usbdev) |
151 | return NULL; | 151 | return NULL; |
152 | rq = kzalloc(sizeof(struct uss720_async_request), mem_flags); | 152 | rq = kzalloc(sizeof(struct uss720_async_request), mem_flags); |
153 | if (!rq) { | 153 | if (!rq) |
154 | dev_err(&usbdev->dev, "submit_async_request out of memory\n"); | ||
155 | return NULL; | 154 | return NULL; |
156 | } | ||
157 | kref_init(&rq->ref_count); | 155 | kref_init(&rq->ref_count); |
158 | INIT_LIST_HEAD(&rq->asynclist); | 156 | INIT_LIST_HEAD(&rq->asynclist); |
159 | init_completion(&rq->compl); | 157 | init_completion(&rq->compl); |
@@ -162,7 +160,6 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p | |||
162 | rq->urb = usb_alloc_urb(0, mem_flags); | 160 | rq->urb = usb_alloc_urb(0, mem_flags); |
163 | if (!rq->urb) { | 161 | if (!rq->urb) { |
164 | kref_put(&rq->ref_count, destroy_async); | 162 | kref_put(&rq->ref_count, destroy_async); |
165 | dev_err(&usbdev->dev, "submit_async_request out of memory\n"); | ||
166 | return NULL; | 163 | return NULL; |
167 | } | 164 | } |
168 | rq->dr = kmalloc(sizeof(*rq->dr), mem_flags); | 165 | rq->dr = kmalloc(sizeof(*rq->dr), mem_flags); |
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 343fa6ff9f4b..54e53ac4c08f 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c | |||
@@ -200,10 +200,8 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ | |||
200 | 200 | ||
201 | /* allocate memory for our device state and initialize it */ | 201 | /* allocate memory for our device state and initialize it */ |
202 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 202 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
203 | if (!dev) { | 203 | if (!dev) |
204 | dev_err(&interface->dev, "Out of memory\n"); | ||
205 | goto error; | 204 | goto error; |
206 | } | ||
207 | kref_init(&dev->kref); | 205 | kref_init(&dev->kref); |
208 | mutex_init(&dev->io_mutex); | 206 | mutex_init(&dev->io_mutex); |
209 | spin_lock_init(&dev->lock); | 207 | spin_lock_init(&dev->lock); |
@@ -231,17 +229,13 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ | |||
231 | 229 | ||
232 | /* allocate control URB */ | 230 | /* allocate control URB */ |
233 | dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL); | 231 | dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL); |
234 | if (!dev->cntl_urb) { | 232 | if (!dev->cntl_urb) |
235 | dev_err(&interface->dev, "Could not allocate control URB\n"); | ||
236 | goto error; | 233 | goto error; |
237 | } | ||
238 | 234 | ||
239 | /* allocate buffer for control req */ | 235 | /* allocate buffer for control req */ |
240 | dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); | 236 | dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); |
241 | if (!dev->cntl_req) { | 237 | if (!dev->cntl_req) |
242 | dev_err(&interface->dev, "Could not allocate cntl_req\n"); | ||
243 | goto error; | 238 | goto error; |
244 | } | ||
245 | 239 | ||
246 | /* allocate buffer for control msg */ | 240 | /* allocate buffer for control msg */ |
247 | dev->cntl_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, | 241 | dev->cntl_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, |
@@ -269,10 +263,8 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ | |||
269 | 263 | ||
270 | /* allocate interrupt URB */ | 264 | /* allocate interrupt URB */ |
271 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); | 265 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); |
272 | if (!dev->urb) { | 266 | if (!dev->urb) |
273 | dev_err(&interface->dev, "Could not allocate URB\n"); | ||
274 | goto error; | 267 | goto error; |
275 | } | ||
276 | 268 | ||
277 | /* allocate buffer for interrupt in */ | 269 | /* allocate buffer for interrupt in */ |
278 | dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, | 270 | dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 73cfa13fc0dc..72a2a5040848 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -82,7 +82,7 @@ config USB_MUSB_DA8XX | |||
82 | tristate "DA8xx/OMAP-L1x" | 82 | tristate "DA8xx/OMAP-L1x" |
83 | depends on ARCH_DAVINCI_DA8XX | 83 | depends on ARCH_DAVINCI_DA8XX |
84 | depends on NOP_USB_XCEIV | 84 | depends on NOP_USB_XCEIV |
85 | depends on BROKEN | 85 | select PHY_DA8XX_USB |
86 | 86 | ||
87 | config USB_MUSB_TUSB6010 | 87 | config USB_MUSB_TUSB6010 |
88 | tristate "TUSB6010" | 88 | tristate "TUSB6010" |
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index c41fe588d14d..50ca8052bc8e 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
@@ -474,10 +474,8 @@ static int am35x_probe(struct platform_device *pdev) | |||
474 | int ret = -ENOMEM; | 474 | int ret = -ENOMEM; |
475 | 475 | ||
476 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 476 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
477 | if (!glue) { | 477 | if (!glue) |
478 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
479 | goto err0; | 478 | goto err0; |
480 | } | ||
481 | 479 | ||
482 | phy_clk = clk_get(&pdev->dev, "fck"); | 480 | phy_clk = clk_get(&pdev->dev, "fck"); |
483 | if (IS_ERR(phy_clk)) { | 481 | if (IS_ERR(phy_clk)) { |
@@ -512,8 +510,10 @@ static int am35x_probe(struct platform_device *pdev) | |||
512 | pdata->platform_ops = &am35x_ops; | 510 | pdata->platform_ops = &am35x_ops; |
513 | 511 | ||
514 | glue->phy = usb_phy_generic_register(); | 512 | glue->phy = usb_phy_generic_register(); |
515 | if (IS_ERR(glue->phy)) | 513 | if (IS_ERR(glue->phy)) { |
514 | ret = PTR_ERR(glue->phy); | ||
516 | goto err7; | 515 | goto err7; |
516 | } | ||
517 | platform_set_drvdata(pdev, glue); | 517 | platform_set_drvdata(pdev, glue); |
518 | 518 | ||
519 | pinfo = am35x_dev_info; | 519 | pinfo = am35x_dev_info; |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index b03d3b867fca..210b7e43a6fd 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -30,13 +30,11 @@ | |||
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/err.h> | 31 | #include <linux/err.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/phy/phy.h> | ||
33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
35 | #include <linux/usb/usb_phy_generic.h> | 36 | #include <linux/usb/usb_phy_generic.h> |
36 | 37 | ||
37 | #include <mach/da8xx.h> | ||
38 | #include <linux/platform_data/usb-davinci.h> | ||
39 | |||
40 | #include "musb_core.h" | 38 | #include "musb_core.h" |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -80,61 +78,15 @@ | |||
80 | 78 | ||
81 | #define DA8XX_MENTOR_CORE_OFFSET 0x400 | 79 | #define DA8XX_MENTOR_CORE_OFFSET 0x400 |
82 | 80 | ||
83 | #define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG) | ||
84 | |||
85 | struct da8xx_glue { | 81 | struct da8xx_glue { |
86 | struct device *dev; | 82 | struct device *dev; |
87 | struct platform_device *musb; | 83 | struct platform_device *musb; |
88 | struct platform_device *phy; | 84 | struct platform_device *usb_phy; |
89 | struct clk *clk; | 85 | struct clk *clk; |
86 | struct phy *phy; | ||
90 | }; | 87 | }; |
91 | 88 | ||
92 | /* | 89 | /* |
93 | * REVISIT (PM): we should be able to keep the PHY in low power mode most | ||
94 | * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 | ||
95 | * and, when in host mode, autosuspending idle root ports... PHY_PLLON | ||
96 | * (overriding SUSPENDM?) then likely needs to stay off. | ||
97 | */ | ||
98 | |||
99 | static inline void phy_on(void) | ||
100 | { | ||
101 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | ||
102 | |||
103 | /* | ||
104 | * Start the on-chip PHY and its PLL. | ||
105 | */ | ||
106 | cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN); | ||
107 | cfgchip2 |= CFGCHIP2_PHY_PLLON; | ||
108 | __raw_writel(cfgchip2, CFGCHIP2); | ||
109 | |||
110 | pr_info("Waiting for USB PHY clock good...\n"); | ||
111 | while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD)) | ||
112 | cpu_relax(); | ||
113 | } | ||
114 | |||
115 | static inline void phy_off(void) | ||
116 | { | ||
117 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | ||
118 | |||
119 | /* | ||
120 | * Ensure that USB 1.1 reference clock is not being sourced from | ||
121 | * USB 2.0 PHY. Otherwise do not power down the PHY. | ||
122 | */ | ||
123 | if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) && | ||
124 | (cfgchip2 & CFGCHIP2_USB1SUSPENDM)) { | ||
125 | pr_warning("USB 1.1 clocked from USB 2.0 PHY -- " | ||
126 | "can't power it down\n"); | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Power down the on-chip PHY. | ||
132 | */ | ||
133 | cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN; | ||
134 | __raw_writel(cfgchip2, CFGCHIP2); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Because we don't set CTRL.UINT, it's "important" to: | 90 | * Because we don't set CTRL.UINT, it's "important" to: |
139 | * - not read/write INTRUSB/INTRUSBE (except during | 91 | * - not read/write INTRUSB/INTRUSBE (except during |
140 | * initial setup, as a workaround); | 92 | * initial setup, as a workaround); |
@@ -385,29 +337,29 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) | |||
385 | 337 | ||
386 | static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode) | 338 | static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode) |
387 | { | 339 | { |
388 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | 340 | struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); |
341 | enum phy_mode phy_mode; | ||
389 | 342 | ||
390 | cfgchip2 &= ~CFGCHIP2_OTGMODE; | ||
391 | switch (musb_mode) { | 343 | switch (musb_mode) { |
392 | case MUSB_HOST: /* Force VBUS valid, ID = 0 */ | 344 | case MUSB_HOST: /* Force VBUS valid, ID = 0 */ |
393 | cfgchip2 |= CFGCHIP2_FORCE_HOST; | 345 | phy_mode = PHY_MODE_USB_HOST; |
394 | break; | 346 | break; |
395 | case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ | 347 | case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ |
396 | cfgchip2 |= CFGCHIP2_FORCE_DEVICE; | 348 | phy_mode = PHY_MODE_USB_DEVICE; |
397 | break; | 349 | break; |
398 | case MUSB_OTG: /* Don't override the VBUS/ID comparators */ | 350 | case MUSB_OTG: /* Don't override the VBUS/ID comparators */ |
399 | cfgchip2 |= CFGCHIP2_NO_OVERRIDE; | 351 | phy_mode = PHY_MODE_USB_OTG; |
400 | break; | 352 | break; |
401 | default: | 353 | default: |
402 | dev_dbg(musb->controller, "Trying to set unsupported mode %u\n", musb_mode); | 354 | return -EINVAL; |
403 | } | 355 | } |
404 | 356 | ||
405 | __raw_writel(cfgchip2, CFGCHIP2); | 357 | return phy_set_mode(glue->phy, phy_mode); |
406 | return 0; | ||
407 | } | 358 | } |
408 | 359 | ||
409 | static int da8xx_musb_init(struct musb *musb) | 360 | static int da8xx_musb_init(struct musb *musb) |
410 | { | 361 | { |
362 | struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
411 | void __iomem *reg_base = musb->ctrl_base; | 363 | void __iomem *reg_base = musb->ctrl_base; |
412 | u32 rev; | 364 | u32 rev; |
413 | int ret = -ENODEV; | 365 | int ret = -ENODEV; |
@@ -425,32 +377,56 @@ static int da8xx_musb_init(struct musb *musb) | |||
425 | goto fail; | 377 | goto fail; |
426 | } | 378 | } |
427 | 379 | ||
380 | ret = clk_prepare_enable(glue->clk); | ||
381 | if (ret) { | ||
382 | dev_err(glue->dev, "failed to enable clock\n"); | ||
383 | goto fail; | ||
384 | } | ||
385 | |||
428 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); | 386 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); |
429 | 387 | ||
430 | /* Reset the controller */ | 388 | /* Reset the controller */ |
431 | musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); | 389 | musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); |
432 | 390 | ||
433 | /* Start the on-chip PHY and its PLL. */ | 391 | /* Start the on-chip PHY and its PLL. */ |
434 | phy_on(); | 392 | ret = phy_init(glue->phy); |
393 | if (ret) { | ||
394 | dev_err(glue->dev, "Failed to init phy.\n"); | ||
395 | goto err_phy_init; | ||
396 | } | ||
397 | |||
398 | ret = phy_power_on(glue->phy); | ||
399 | if (ret) { | ||
400 | dev_err(glue->dev, "Failed to power on phy.\n"); | ||
401 | goto err_phy_power_on; | ||
402 | } | ||
435 | 403 | ||
436 | msleep(5); | 404 | msleep(5); |
437 | 405 | ||
438 | /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */ | 406 | /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */ |
439 | pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n", | 407 | pr_debug("DA8xx OTG revision %08x, control %02x\n", rev, |
440 | rev, __raw_readl(CFGCHIP2), | ||
441 | musb_readb(reg_base, DA8XX_USB_CTRL_REG)); | 408 | musb_readb(reg_base, DA8XX_USB_CTRL_REG)); |
442 | 409 | ||
443 | musb->isr = da8xx_musb_interrupt; | 410 | musb->isr = da8xx_musb_interrupt; |
444 | return 0; | 411 | return 0; |
412 | |||
413 | err_phy_power_on: | ||
414 | phy_exit(glue->phy); | ||
415 | err_phy_init: | ||
416 | clk_disable_unprepare(glue->clk); | ||
445 | fail: | 417 | fail: |
446 | return ret; | 418 | return ret; |
447 | } | 419 | } |
448 | 420 | ||
449 | static int da8xx_musb_exit(struct musb *musb) | 421 | static int da8xx_musb_exit(struct musb *musb) |
450 | { | 422 | { |
423 | struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
424 | |||
451 | del_timer_sync(&otg_workaround); | 425 | del_timer_sync(&otg_workaround); |
452 | 426 | ||
453 | phy_off(); | 427 | phy_power_off(glue->phy); |
428 | phy_exit(glue->phy); | ||
429 | clk_disable_unprepare(glue->clk); | ||
454 | 430 | ||
455 | usb_put_phy(musb->xceiv); | 431 | usb_put_phy(musb->xceiv); |
456 | 432 | ||
@@ -486,30 +462,25 @@ static int da8xx_probe(struct platform_device *pdev) | |||
486 | { | 462 | { |
487 | struct resource musb_resources[2]; | 463 | struct resource musb_resources[2]; |
488 | struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); | 464 | struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); |
489 | struct platform_device *musb; | ||
490 | struct da8xx_glue *glue; | 465 | struct da8xx_glue *glue; |
491 | struct platform_device_info pinfo; | 466 | struct platform_device_info pinfo; |
492 | struct clk *clk; | 467 | struct clk *clk; |
468 | int ret; | ||
493 | 469 | ||
494 | int ret = -ENOMEM; | 470 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
495 | 471 | if (!glue) | |
496 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 472 | return -ENOMEM; |
497 | if (!glue) { | ||
498 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
499 | goto err0; | ||
500 | } | ||
501 | 473 | ||
502 | clk = clk_get(&pdev->dev, "usb20"); | 474 | clk = devm_clk_get(&pdev->dev, "usb20"); |
503 | if (IS_ERR(clk)) { | 475 | if (IS_ERR(clk)) { |
504 | dev_err(&pdev->dev, "failed to get clock\n"); | 476 | dev_err(&pdev->dev, "failed to get clock\n"); |
505 | ret = PTR_ERR(clk); | 477 | return PTR_ERR(clk); |
506 | goto err3; | ||
507 | } | 478 | } |
508 | 479 | ||
509 | ret = clk_enable(clk); | 480 | glue->phy = devm_phy_get(&pdev->dev, "usb-phy"); |
510 | if (ret) { | 481 | if (IS_ERR(glue->phy)) { |
511 | dev_err(&pdev->dev, "failed to enable clock\n"); | 482 | dev_err(&pdev->dev, "failed to get phy\n"); |
512 | goto err4; | 483 | return PTR_ERR(glue->phy); |
513 | } | 484 | } |
514 | 485 | ||
515 | glue->dev = &pdev->dev; | 486 | glue->dev = &pdev->dev; |
@@ -517,10 +488,11 @@ static int da8xx_probe(struct platform_device *pdev) | |||
517 | 488 | ||
518 | pdata->platform_ops = &da8xx_ops; | 489 | pdata->platform_ops = &da8xx_ops; |
519 | 490 | ||
520 | glue->phy = usb_phy_generic_register(); | 491 | glue->usb_phy = usb_phy_generic_register(); |
521 | if (IS_ERR(glue->phy)) { | 492 | ret = PTR_ERR_OR_ZERO(glue->usb_phy); |
522 | ret = PTR_ERR(glue->phy); | 493 | if (ret) { |
523 | goto err5; | 494 | dev_err(&pdev->dev, "failed to register usb_phy\n"); |
495 | return ret; | ||
524 | } | 496 | } |
525 | platform_set_drvdata(pdev, glue); | 497 | platform_set_drvdata(pdev, glue); |
526 | 498 | ||
@@ -544,28 +516,13 @@ static int da8xx_probe(struct platform_device *pdev) | |||
544 | pinfo.data = pdata; | 516 | pinfo.data = pdata; |
545 | pinfo.size_data = sizeof(*pdata); | 517 | pinfo.size_data = sizeof(*pdata); |
546 | 518 | ||
547 | glue->musb = musb = platform_device_register_full(&pinfo); | 519 | glue->musb = platform_device_register_full(&pinfo); |
548 | if (IS_ERR(musb)) { | 520 | ret = PTR_ERR_OR_ZERO(glue->musb); |
549 | ret = PTR_ERR(musb); | 521 | if (ret) { |
550 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); | 522 | dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); |
551 | goto err6; | 523 | usb_phy_generic_unregister(glue->usb_phy); |
552 | } | 524 | } |
553 | 525 | ||
554 | return 0; | ||
555 | |||
556 | err6: | ||
557 | usb_phy_generic_unregister(glue->phy); | ||
558 | |||
559 | err5: | ||
560 | clk_disable(clk); | ||
561 | |||
562 | err4: | ||
563 | clk_put(clk); | ||
564 | |||
565 | err3: | ||
566 | kfree(glue); | ||
567 | |||
568 | err0: | ||
569 | return ret; | 526 | return ret; |
570 | } | 527 | } |
571 | 528 | ||
@@ -574,10 +531,7 @@ static int da8xx_remove(struct platform_device *pdev) | |||
574 | struct da8xx_glue *glue = platform_get_drvdata(pdev); | 531 | struct da8xx_glue *glue = platform_get_drvdata(pdev); |
575 | 532 | ||
576 | platform_device_unregister(glue->musb); | 533 | platform_device_unregister(glue->musb); |
577 | usb_phy_generic_unregister(glue->phy); | 534 | usb_phy_generic_unregister(glue->usb_phy); |
578 | clk_disable(glue->clk); | ||
579 | clk_put(glue->clk); | ||
580 | kfree(glue); | ||
581 | 535 | ||
582 | return 0; | 536 | return 0; |
583 | } | 537 | } |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 74fc3069cb42..27dadc0d9114 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1448,7 +1448,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) | |||
1448 | { | 1448 | { |
1449 | u8 reg; | 1449 | u8 reg; |
1450 | char *type; | 1450 | char *type; |
1451 | char aInfo[90], aRevision[32], aDate[12]; | 1451 | char aInfo[90]; |
1452 | void __iomem *mbase = musb->mregs; | 1452 | void __iomem *mbase = musb->mregs; |
1453 | int status = 0; | 1453 | int status = 0; |
1454 | int i; | 1454 | int i; |
@@ -1482,7 +1482,6 @@ static int musb_core_init(u16 musb_type, struct musb *musb) | |||
1482 | 1482 | ||
1483 | pr_debug("%s: ConfigData=0x%02x (%s)\n", musb_driver_name, reg, aInfo); | 1483 | pr_debug("%s: ConfigData=0x%02x (%s)\n", musb_driver_name, reg, aInfo); |
1484 | 1484 | ||
1485 | aDate[0] = 0; | ||
1486 | if (MUSB_CONTROLLER_MHDRC == musb_type) { | 1485 | if (MUSB_CONTROLLER_MHDRC == musb_type) { |
1487 | musb->is_multipoint = 1; | 1486 | musb->is_multipoint = 1; |
1488 | type = "M"; | 1487 | type = "M"; |
@@ -1497,11 +1496,10 @@ static int musb_core_init(u16 musb_type, struct musb *musb) | |||
1497 | 1496 | ||
1498 | /* log release info */ | 1497 | /* log release info */ |
1499 | musb->hwvers = musb_read_hwvers(mbase); | 1498 | musb->hwvers = musb_read_hwvers(mbase); |
1500 | snprintf(aRevision, 32, "%d.%d%s", MUSB_HWVERS_MAJOR(musb->hwvers), | 1499 | pr_debug("%s: %sHDRC RTL version %d.%d%s\n", |
1501 | MUSB_HWVERS_MINOR(musb->hwvers), | 1500 | musb_driver_name, type, MUSB_HWVERS_MAJOR(musb->hwvers), |
1502 | (musb->hwvers & MUSB_HWVERS_RC) ? "RC" : ""); | 1501 | MUSB_HWVERS_MINOR(musb->hwvers), |
1503 | pr_debug("%s: %sHDRC RTL version %s %s\n", | 1502 | (musb->hwvers & MUSB_HWVERS_RC) ? "RC" : ""); |
1504 | musb_driver_name, type, aRevision, aDate); | ||
1505 | 1503 | ||
1506 | /* configure ep0 */ | 1504 | /* configure ep0 */ |
1507 | musb_configure_ep0(musb); | 1505 | musb_configure_ep0(musb); |
@@ -1831,11 +1829,80 @@ static const struct attribute_group musb_attr_group = { | |||
1831 | .attrs = musb_attributes, | 1829 | .attrs = musb_attributes, |
1832 | }; | 1830 | }; |
1833 | 1831 | ||
1832 | #define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \ | ||
1833 | (2 << MUSB_DEVCTL_VBUS_SHIFT) | \ | ||
1834 | MUSB_DEVCTL_SESSION) | ||
1835 | #define MUSB_QUIRK_A_DISCONNECT_19 ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \ | ||
1836 | MUSB_DEVCTL_SESSION) | ||
1837 | |||
1838 | /* | ||
1839 | * Check the musb devctl session bit to determine if we want to | ||
1840 | * allow PM runtime for the device. In general, we want to keep things | ||
1841 | * active when the session bit is set except after host disconnect. | ||
1842 | * | ||
1843 | * Only called from musb_irq_work. If this ever needs to get called | ||
1844 | * elsewhere, proper locking must be implemented for musb->session. | ||
1845 | */ | ||
1846 | static void musb_pm_runtime_check_session(struct musb *musb) | ||
1847 | { | ||
1848 | u8 devctl, s; | ||
1849 | int error; | ||
1850 | |||
1851 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
1852 | |||
1853 | /* Handle session status quirks first */ | ||
1854 | s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV | | ||
1855 | MUSB_DEVCTL_HR; | ||
1856 | switch (devctl & ~s) { | ||
1857 | case MUSB_QUIRK_B_INVALID_VBUS_91: | ||
1858 | if (!musb->session && !musb->quirk_invalid_vbus) { | ||
1859 | musb->quirk_invalid_vbus = true; | ||
1860 | musb_dbg(musb, | ||
1861 | "First invalid vbus, assume no session"); | ||
1862 | return; | ||
1863 | } | ||
1864 | break; | ||
1865 | case MUSB_QUIRK_A_DISCONNECT_19: | ||
1866 | if (!musb->session) | ||
1867 | break; | ||
1868 | musb_dbg(musb, "Allow PM on possible host mode disconnect"); | ||
1869 | pm_runtime_mark_last_busy(musb->controller); | ||
1870 | pm_runtime_put_autosuspend(musb->controller); | ||
1871 | musb->session = false; | ||
1872 | return; | ||
1873 | default: | ||
1874 | break; | ||
1875 | } | ||
1876 | |||
1877 | /* No need to do anything if session has not changed */ | ||
1878 | s = devctl & MUSB_DEVCTL_SESSION; | ||
1879 | if (s == musb->session) | ||
1880 | return; | ||
1881 | |||
1882 | /* Block PM or allow PM? */ | ||
1883 | if (s) { | ||
1884 | musb_dbg(musb, "Block PM on active session: %02x", devctl); | ||
1885 | error = pm_runtime_get_sync(musb->controller); | ||
1886 | if (error < 0) | ||
1887 | dev_err(musb->controller, "Could not enable: %i\n", | ||
1888 | error); | ||
1889 | } else { | ||
1890 | musb_dbg(musb, "Allow PM with no session: %02x", devctl); | ||
1891 | musb->quirk_invalid_vbus = false; | ||
1892 | pm_runtime_mark_last_busy(musb->controller); | ||
1893 | pm_runtime_put_autosuspend(musb->controller); | ||
1894 | } | ||
1895 | |||
1896 | musb->session = s; | ||
1897 | } | ||
1898 | |||
1834 | /* Only used to provide driver mode change events */ | 1899 | /* Only used to provide driver mode change events */ |
1835 | static void musb_irq_work(struct work_struct *data) | 1900 | static void musb_irq_work(struct work_struct *data) |
1836 | { | 1901 | { |
1837 | struct musb *musb = container_of(data, struct musb, irq_work); | 1902 | struct musb *musb = container_of(data, struct musb, irq_work); |
1838 | 1903 | ||
1904 | musb_pm_runtime_check_session(musb); | ||
1905 | |||
1839 | if (musb->xceiv->otg->state != musb->xceiv_old_state) { | 1906 | if (musb->xceiv->otg->state != musb->xceiv_old_state) { |
1840 | musb->xceiv_old_state = musb->xceiv->otg->state; | 1907 | musb->xceiv_old_state = musb->xceiv->otg->state; |
1841 | sysfs_notify(&musb->controller->kobj, NULL, "mode"); | 1908 | sysfs_notify(&musb->controller->kobj, NULL, "mode"); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b55a776b03eb..2cb88a498f8a 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -378,6 +378,8 @@ struct musb { | |||
378 | u8 min_power; /* vbus for periph, in mA/2 */ | 378 | u8 min_power; /* vbus for periph, in mA/2 */ |
379 | 379 | ||
380 | int port_mode; /* MUSB_PORT_MODE_* */ | 380 | int port_mode; /* MUSB_PORT_MODE_* */ |
381 | bool session; | ||
382 | bool quirk_invalid_vbus; | ||
381 | bool is_host; | 383 | bool is_host; |
382 | 384 | ||
383 | int a_wait_bcon; /* VBUS timeout in msecs */ | 385 | int a_wait_bcon; /* VBUS timeout in msecs */ |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 2537179636db..0f17d2140db6 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -145,43 +145,6 @@ static const struct debugfs_reg32 dsps_musb_regs[] = { | |||
145 | { "mode", 0xe8 }, | 145 | { "mode", 0xe8 }, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) | ||
149 | { | ||
150 | struct device *dev = musb->controller; | ||
151 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | ||
152 | |||
153 | if (timeout == 0) | ||
154 | timeout = jiffies + msecs_to_jiffies(3); | ||
155 | |||
156 | /* Never idle if active, or when VBUS timeout is not set as host */ | ||
157 | if (musb->is_active || (musb->a_wait_bcon == 0 && | ||
158 | musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) { | ||
159 | dev_dbg(musb->controller, "%s active, deleting timer\n", | ||
160 | usb_otg_state_string(musb->xceiv->otg->state)); | ||
161 | del_timer(&glue->timer); | ||
162 | glue->last_timer = jiffies; | ||
163 | return; | ||
164 | } | ||
165 | if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) | ||
166 | return; | ||
167 | |||
168 | if (!musb->g.dev.driver) | ||
169 | return; | ||
170 | |||
171 | if (time_after(glue->last_timer, timeout) && | ||
172 | timer_pending(&glue->timer)) { | ||
173 | dev_dbg(musb->controller, | ||
174 | "Longer idle timer already pending, ignoring...\n"); | ||
175 | return; | ||
176 | } | ||
177 | glue->last_timer = timeout; | ||
178 | |||
179 | dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", | ||
180 | usb_otg_state_string(musb->xceiv->otg->state), | ||
181 | jiffies_to_msecs(timeout - jiffies)); | ||
182 | mod_timer(&glue->timer, timeout); | ||
183 | } | ||
184 | |||
185 | /** | 148 | /** |
186 | * dsps_musb_enable - enable interrupts | 149 | * dsps_musb_enable - enable interrupts |
187 | */ | 150 | */ |
@@ -206,7 +169,6 @@ static void dsps_musb_enable(struct musb *musb) | |||
206 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) | 169 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) |
207 | mod_timer(&glue->timer, jiffies + | 170 | mod_timer(&glue->timer, jiffies + |
208 | msecs_to_jiffies(wrp->poll_timeout)); | 171 | msecs_to_jiffies(wrp->poll_timeout)); |
209 | dsps_musb_try_idle(musb, 0); | ||
210 | } | 172 | } |
211 | 173 | ||
212 | /** | 174 | /** |
@@ -236,6 +198,11 @@ static void otg_timer(unsigned long _musb) | |||
236 | u8 devctl; | 198 | u8 devctl; |
237 | unsigned long flags; | 199 | unsigned long flags; |
238 | int skip_session = 0; | 200 | int skip_session = 0; |
201 | int err; | ||
202 | |||
203 | err = pm_runtime_get_sync(dev); | ||
204 | if (err < 0) | ||
205 | dev_err(dev, "Poll could not pm_runtime_get: %i\n", err); | ||
239 | 206 | ||
240 | /* | 207 | /* |
241 | * We poll because DSPS IP's won't expose several OTG-critical | 208 | * We poll because DSPS IP's won't expose several OTG-critical |
@@ -247,6 +214,10 @@ static void otg_timer(unsigned long _musb) | |||
247 | 214 | ||
248 | spin_lock_irqsave(&musb->lock, flags); | 215 | spin_lock_irqsave(&musb->lock, flags); |
249 | switch (musb->xceiv->otg->state) { | 216 | switch (musb->xceiv->otg->state) { |
217 | case OTG_STATE_A_WAIT_VRISE: | ||
218 | mod_timer(&glue->timer, jiffies + | ||
219 | msecs_to_jiffies(wrp->poll_timeout)); | ||
220 | break; | ||
250 | case OTG_STATE_A_WAIT_BCON: | 221 | case OTG_STATE_A_WAIT_BCON: |
251 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | 222 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
252 | skip_session = 1; | 223 | skip_session = 1; |
@@ -275,6 +246,9 @@ static void otg_timer(unsigned long _musb) | |||
275 | break; | 246 | break; |
276 | } | 247 | } |
277 | spin_unlock_irqrestore(&musb->lock, flags); | 248 | spin_unlock_irqrestore(&musb->lock, flags); |
249 | |||
250 | pm_runtime_mark_last_busy(dev); | ||
251 | pm_runtime_put_autosuspend(dev); | ||
278 | } | 252 | } |
279 | 253 | ||
280 | static irqreturn_t dsps_interrupt(int irq, void *hci) | 254 | static irqreturn_t dsps_interrupt(int irq, void *hci) |
@@ -338,7 +312,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
338 | MUSB_HST_MODE(musb); | 312 | MUSB_HST_MODE(musb); |
339 | musb->xceiv->otg->default_a = 1; | 313 | musb->xceiv->otg->default_a = 1; |
340 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; | 314 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
341 | del_timer(&glue->timer); | 315 | mod_timer(&glue->timer, jiffies + |
316 | msecs_to_jiffies(wrp->poll_timeout)); | ||
342 | } else { | 317 | } else { |
343 | musb->is_active = 0; | 318 | musb->is_active = 0; |
344 | MUSB_DEV_MODE(musb); | 319 | MUSB_DEV_MODE(musb); |
@@ -358,11 +333,17 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
358 | if (musb->int_tx || musb->int_rx || musb->int_usb) | 333 | if (musb->int_tx || musb->int_rx || musb->int_usb) |
359 | ret |= musb_interrupt(musb); | 334 | ret |= musb_interrupt(musb); |
360 | 335 | ||
361 | /* Poll for ID change in OTG port mode */ | 336 | /* Poll for ID change and connect */ |
362 | if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && | 337 | switch (musb->xceiv->otg->state) { |
363 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) | 338 | case OTG_STATE_B_IDLE: |
339 | case OTG_STATE_A_WAIT_BCON: | ||
364 | mod_timer(&glue->timer, jiffies + | 340 | mod_timer(&glue->timer, jiffies + |
365 | msecs_to_jiffies(wrp->poll_timeout)); | 341 | msecs_to_jiffies(wrp->poll_timeout)); |
342 | break; | ||
343 | default: | ||
344 | break; | ||
345 | } | ||
346 | |||
366 | out: | 347 | out: |
367 | spin_unlock_irqrestore(&musb->lock, flags); | 348 | spin_unlock_irqrestore(&musb->lock, flags); |
368 | 349 | ||
@@ -461,6 +442,9 @@ static int dsps_musb_init(struct musb *musb) | |||
461 | musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); | 442 | musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); |
462 | } | 443 | } |
463 | 444 | ||
445 | mod_timer(&glue->timer, jiffies + | ||
446 | msecs_to_jiffies(glue->wrp->poll_timeout)); | ||
447 | |||
464 | return dsps_musb_dbg_init(musb, glue); | 448 | return dsps_musb_dbg_init(musb, glue); |
465 | } | 449 | } |
466 | 450 | ||
@@ -620,7 +604,6 @@ static struct musb_platform_ops dsps_ops = { | |||
620 | .enable = dsps_musb_enable, | 604 | .enable = dsps_musb_enable, |
621 | .disable = dsps_musb_disable, | 605 | .disable = dsps_musb_disable, |
622 | 606 | ||
623 | .try_idle = dsps_musb_try_idle, | ||
624 | .set_mode = dsps_musb_set_mode, | 607 | .set_mode = dsps_musb_set_mode, |
625 | .recover = dsps_musb_recover, | 608 | .recover = dsps_musb_recover, |
626 | }; | 609 | }; |
@@ -784,6 +767,8 @@ static int dsps_probe(struct platform_device *pdev) | |||
784 | 767 | ||
785 | platform_set_drvdata(pdev, glue); | 768 | platform_set_drvdata(pdev, glue); |
786 | pm_runtime_enable(&pdev->dev); | 769 | pm_runtime_enable(&pdev->dev); |
770 | pm_runtime_use_autosuspend(&pdev->dev); | ||
771 | pm_runtime_set_autosuspend_delay(&pdev->dev, 200); | ||
787 | 772 | ||
788 | ret = pm_runtime_get_sync(&pdev->dev); | 773 | ret = pm_runtime_get_sync(&pdev->dev); |
789 | if (ret < 0) { | 774 | if (ret < 0) { |
@@ -795,11 +780,15 @@ static int dsps_probe(struct platform_device *pdev) | |||
795 | if (ret) | 780 | if (ret) |
796 | goto err3; | 781 | goto err3; |
797 | 782 | ||
783 | pm_runtime_mark_last_busy(&pdev->dev); | ||
784 | pm_runtime_put_autosuspend(&pdev->dev); | ||
785 | |||
798 | return 0; | 786 | return 0; |
799 | 787 | ||
800 | err3: | 788 | err3: |
801 | pm_runtime_put(&pdev->dev); | 789 | pm_runtime_put_sync(&pdev->dev); |
802 | err2: | 790 | err2: |
791 | pm_runtime_dont_use_autosuspend(&pdev->dev); | ||
803 | pm_runtime_disable(&pdev->dev); | 792 | pm_runtime_disable(&pdev->dev); |
804 | return ret; | 793 | return ret; |
805 | } | 794 | } |
@@ -811,7 +800,8 @@ static int dsps_remove(struct platform_device *pdev) | |||
811 | platform_device_unregister(glue->musb); | 800 | platform_device_unregister(glue->musb); |
812 | 801 | ||
813 | /* disable usbss clocks */ | 802 | /* disable usbss clocks */ |
814 | pm_runtime_put(&pdev->dev); | 803 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
804 | pm_runtime_put_sync(&pdev->dev); | ||
815 | pm_runtime_disable(&pdev->dev); | 805 | pm_runtime_disable(&pdev->dev); |
816 | 806 | ||
817 | return 0; | 807 | return 0; |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6d1e975e9605..bff4869a57cd 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1964,6 +1964,9 @@ static int musb_gadget_stop(struct usb_gadget *g) | |||
1964 | * that currently misbehaves. | 1964 | * that currently misbehaves. |
1965 | */ | 1965 | */ |
1966 | 1966 | ||
1967 | /* Force check of devctl register for PM runtime */ | ||
1968 | schedule_work(&musb->irq_work); | ||
1969 | |||
1967 | pm_runtime_mark_last_busy(musb->controller); | 1970 | pm_runtime_mark_last_busy(musb->controller); |
1968 | pm_runtime_put_autosuspend(musb->controller); | 1971 | pm_runtime_put_autosuspend(musb->controller); |
1969 | 1972 | ||
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index fe08e776fec3..61b5f1c3c5bc 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -245,6 +245,7 @@ void musb_root_disconnect(struct musb *musb) | |||
245 | usb_otg_state_string(musb->xceiv->otg->state)); | 245 | usb_otg_state_string(musb->xceiv->otg->state)); |
246 | } | 246 | } |
247 | } | 247 | } |
248 | EXPORT_SYMBOL_GPL(musb_root_disconnect); | ||
248 | 249 | ||
249 | 250 | ||
250 | /*---------------------------------------------------------------------*/ | 251 | /*---------------------------------------------------------------------*/ |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 0b4cec940386..1ab6973d4f61 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -49,9 +49,6 @@ struct omap2430_glue { | |||
49 | enum musb_vbus_id_status status; | 49 | enum musb_vbus_id_status status; |
50 | struct work_struct omap_musb_mailbox_work; | 50 | struct work_struct omap_musb_mailbox_work; |
51 | struct device *control_otghs; | 51 | struct device *control_otghs; |
52 | bool cable_connected; | ||
53 | bool enabled; | ||
54 | bool powered; | ||
55 | }; | 52 | }; |
56 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 53 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
57 | 54 | ||
@@ -141,45 +138,6 @@ static inline void omap2430_low_level_init(struct musb *musb) | |||
141 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); | 138 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); |
142 | } | 139 | } |
143 | 140 | ||
144 | /* | ||
145 | * We can get multiple cable events so we need to keep track | ||
146 | * of the power state. Only keep power enabled if USB cable is | ||
147 | * connected and a gadget is started. | ||
148 | */ | ||
149 | static void omap2430_set_power(struct musb *musb, bool enabled, bool cable) | ||
150 | { | ||
151 | struct device *dev = musb->controller; | ||
152 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | ||
153 | bool power_up; | ||
154 | int res; | ||
155 | |||
156 | if (glue->enabled != enabled) | ||
157 | glue->enabled = enabled; | ||
158 | |||
159 | if (glue->cable_connected != cable) | ||
160 | glue->cable_connected = cable; | ||
161 | |||
162 | power_up = glue->enabled && glue->cable_connected; | ||
163 | if (power_up == glue->powered) { | ||
164 | dev_warn(musb->controller, "power state already %i\n", | ||
165 | power_up); | ||
166 | return; | ||
167 | } | ||
168 | |||
169 | glue->powered = power_up; | ||
170 | |||
171 | if (power_up) { | ||
172 | res = pm_runtime_get_sync(musb->controller); | ||
173 | if (res < 0) { | ||
174 | dev_err(musb->controller, "could not enable: %i", res); | ||
175 | glue->powered = false; | ||
176 | } | ||
177 | } else { | ||
178 | pm_runtime_mark_last_busy(musb->controller); | ||
179 | pm_runtime_put_autosuspend(musb->controller); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static int omap2430_musb_mailbox(enum musb_vbus_id_status status) | 141 | static int omap2430_musb_mailbox(enum musb_vbus_id_status status) |
184 | { | 142 | { |
185 | struct omap2430_glue *glue = _glue; | 143 | struct omap2430_glue *glue = _glue; |
@@ -203,21 +161,15 @@ static int omap2430_musb_mailbox(enum musb_vbus_id_status status) | |||
203 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) | 161 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) |
204 | { | 162 | { |
205 | struct musb *musb = glue_to_musb(glue); | 163 | struct musb *musb = glue_to_musb(glue); |
206 | struct device *dev = musb->controller; | 164 | struct musb_hdrc_platform_data *pdata = |
207 | struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); | 165 | dev_get_platdata(musb->controller); |
208 | struct omap_musb_board_data *data = pdata->board_data; | 166 | struct omap_musb_board_data *data = pdata->board_data; |
209 | struct usb_otg *otg = musb->xceiv->otg; | 167 | struct usb_otg *otg = musb->xceiv->otg; |
210 | bool cable_connected; | ||
211 | |||
212 | cable_connected = ((glue->status == MUSB_ID_GROUND) || | ||
213 | (glue->status == MUSB_VBUS_VALID)); | ||
214 | |||
215 | if (cable_connected) | ||
216 | omap2430_set_power(musb, glue->enabled, cable_connected); | ||
217 | 168 | ||
169 | pm_runtime_get_sync(musb->controller); | ||
218 | switch (glue->status) { | 170 | switch (glue->status) { |
219 | case MUSB_ID_GROUND: | 171 | case MUSB_ID_GROUND: |
220 | dev_dbg(dev, "ID GND\n"); | 172 | dev_dbg(musb->controller, "ID GND\n"); |
221 | 173 | ||
222 | otg->default_a = true; | 174 | otg->default_a = true; |
223 | musb->xceiv->otg->state = OTG_STATE_A_IDLE; | 175 | musb->xceiv->otg->state = OTG_STATE_A_IDLE; |
@@ -230,7 +182,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
230 | break; | 182 | break; |
231 | 183 | ||
232 | case MUSB_VBUS_VALID: | 184 | case MUSB_VBUS_VALID: |
233 | dev_dbg(dev, "VBUS Connect\n"); | 185 | dev_dbg(musb->controller, "VBUS Connect\n"); |
234 | 186 | ||
235 | otg->default_a = false; | 187 | otg->default_a = false; |
236 | musb->xceiv->otg->state = OTG_STATE_B_IDLE; | 188 | musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
@@ -240,7 +192,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
240 | 192 | ||
241 | case MUSB_ID_FLOAT: | 193 | case MUSB_ID_FLOAT: |
242 | case MUSB_VBUS_OFF: | 194 | case MUSB_VBUS_OFF: |
243 | dev_dbg(dev, "VBUS Disconnect\n"); | 195 | dev_dbg(musb->controller, "VBUS Disconnect\n"); |
244 | 196 | ||
245 | musb->xceiv->last_event = USB_EVENT_NONE; | 197 | musb->xceiv->last_event = USB_EVENT_NONE; |
246 | if (musb->gadget_driver) | 198 | if (musb->gadget_driver) |
@@ -253,12 +205,10 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
253 | USB_MODE_DISCONNECT); | 205 | USB_MODE_DISCONNECT); |
254 | break; | 206 | break; |
255 | default: | 207 | default: |
256 | dev_dbg(dev, "ID float\n"); | 208 | dev_dbg(musb->controller, "ID float\n"); |
257 | } | 209 | } |
258 | 210 | pm_runtime_mark_last_busy(musb->controller); | |
259 | if (!cable_connected) | 211 | pm_runtime_put_autosuspend(musb->controller); |
260 | omap2430_set_power(musb, glue->enabled, cable_connected); | ||
261 | |||
262 | atomic_notifier_call_chain(&musb->xceiv->notifier, | 212 | atomic_notifier_call_chain(&musb->xceiv->notifier, |
263 | musb->xceiv->last_event, NULL); | 213 | musb->xceiv->last_event, NULL); |
264 | } | 214 | } |
@@ -376,8 +326,6 @@ static void omap2430_musb_enable(struct musb *musb) | |||
376 | if (!WARN_ON(!musb->phy)) | 326 | if (!WARN_ON(!musb->phy)) |
377 | phy_power_on(musb->phy); | 327 | phy_power_on(musb->phy); |
378 | 328 | ||
379 | omap2430_set_power(musb, true, glue->cable_connected); | ||
380 | |||
381 | switch (glue->status) { | 329 | switch (glue->status) { |
382 | 330 | ||
383 | case MUSB_ID_GROUND: | 331 | case MUSB_ID_GROUND: |
@@ -419,8 +367,6 @@ static void omap2430_musb_disable(struct musb *musb) | |||
419 | if (glue->status != MUSB_UNKNOWN) | 367 | if (glue->status != MUSB_UNKNOWN) |
420 | omap_control_usb_set_mode(glue->control_otghs, | 368 | omap_control_usb_set_mode(glue->control_otghs, |
421 | USB_MODE_DISCONNECT); | 369 | USB_MODE_DISCONNECT); |
422 | |||
423 | omap2430_set_power(musb, false, glue->cable_connected); | ||
424 | } | 370 | } |
425 | 371 | ||
426 | static int omap2430_musb_exit(struct musb *musb) | 372 | static int omap2430_musb_exit(struct musb *musb) |
@@ -571,7 +517,7 @@ static int omap2430_probe(struct platform_device *pdev) | |||
571 | 517 | ||
572 | pm_runtime_enable(glue->dev); | 518 | pm_runtime_enable(glue->dev); |
573 | pm_runtime_use_autosuspend(glue->dev); | 519 | pm_runtime_use_autosuspend(glue->dev); |
574 | pm_runtime_set_autosuspend_delay(glue->dev, 500); | 520 | pm_runtime_set_autosuspend_delay(glue->dev, 100); |
575 | 521 | ||
576 | ret = platform_device_add(musb); | 522 | ret = platform_device_add(musb); |
577 | if (ret) { | 523 | if (ret) { |
@@ -591,11 +537,9 @@ err0: | |||
591 | static int omap2430_remove(struct platform_device *pdev) | 537 | static int omap2430_remove(struct platform_device *pdev) |
592 | { | 538 | { |
593 | struct omap2430_glue *glue = platform_get_drvdata(pdev); | 539 | struct omap2430_glue *glue = platform_get_drvdata(pdev); |
594 | struct musb *musb = glue_to_musb(glue); | ||
595 | 540 | ||
596 | pm_runtime_get_sync(glue->dev); | 541 | pm_runtime_get_sync(glue->dev); |
597 | platform_device_unregister(glue->musb); | 542 | platform_device_unregister(glue->musb); |
598 | omap2430_set_power(musb, false, false); | ||
599 | pm_runtime_put_sync(glue->dev); | 543 | pm_runtime_put_sync(glue->dev); |
600 | pm_runtime_dont_use_autosuspend(glue->dev); | 544 | pm_runtime_dont_use_autosuspend(glue->dev); |
601 | pm_runtime_disable(glue->dev); | 545 | pm_runtime_disable(glue->dev); |
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index c6ee16660572..1408245be18e 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #define SUNXI_MUSB_FL_HAS_SRAM 5 | 74 | #define SUNXI_MUSB_FL_HAS_SRAM 5 |
75 | #define SUNXI_MUSB_FL_HAS_RESET 6 | 75 | #define SUNXI_MUSB_FL_HAS_RESET 6 |
76 | #define SUNXI_MUSB_FL_NO_CONFIGDATA 7 | 76 | #define SUNXI_MUSB_FL_NO_CONFIGDATA 7 |
77 | #define SUNXI_MUSB_FL_PHY_MODE_PEND 8 | ||
77 | 78 | ||
78 | /* Our read/write methods need access and do not get passed in a musb ref :| */ | 79 | /* Our read/write methods need access and do not get passed in a musb ref :| */ |
79 | static struct musb *sunxi_musb; | 80 | static struct musb *sunxi_musb; |
@@ -87,6 +88,7 @@ struct sunxi_glue { | |||
87 | struct phy *phy; | 88 | struct phy *phy; |
88 | struct platform_device *usb_phy; | 89 | struct platform_device *usb_phy; |
89 | struct usb_phy *xceiv; | 90 | struct usb_phy *xceiv; |
91 | enum phy_mode phy_mode; | ||
90 | unsigned long flags; | 92 | unsigned long flags; |
91 | struct work_struct work; | 93 | struct work_struct work; |
92 | struct extcon_dev *extcon; | 94 | struct extcon_dev *extcon; |
@@ -140,6 +142,9 @@ static void sunxi_musb_work(struct work_struct *work) | |||
140 | clear_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags); | 142 | clear_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags); |
141 | } | 143 | } |
142 | } | 144 | } |
145 | |||
146 | if (test_and_clear_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags)) | ||
147 | phy_set_mode(glue->phy, glue->phy_mode); | ||
143 | } | 148 | } |
144 | 149 | ||
145 | static void sunxi_musb_set_vbus(struct musb *musb, int is_on) | 150 | static void sunxi_musb_set_vbus(struct musb *musb, int is_on) |
@@ -341,6 +346,50 @@ static void sunxi_musb_dma_controller_destroy(struct dma_controller *c) | |||
341 | { | 346 | { |
342 | } | 347 | } |
343 | 348 | ||
349 | static int sunxi_musb_set_mode(struct musb *musb, u8 mode) | ||
350 | { | ||
351 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
352 | enum phy_mode new_mode; | ||
353 | |||
354 | switch (mode) { | ||
355 | case MUSB_HOST: | ||
356 | new_mode = PHY_MODE_USB_HOST; | ||
357 | break; | ||
358 | case MUSB_PERIPHERAL: | ||
359 | new_mode = PHY_MODE_USB_DEVICE; | ||
360 | break; | ||
361 | case MUSB_OTG: | ||
362 | new_mode = PHY_MODE_USB_OTG; | ||
363 | break; | ||
364 | default: | ||
365 | dev_err(musb->controller->parent, | ||
366 | "Error requested mode not supported by this kernel\n"); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | if (glue->phy_mode == new_mode) | ||
371 | return 0; | ||
372 | |||
373 | if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) { | ||
374 | dev_err(musb->controller->parent, | ||
375 | "Error changing modes is only supported in dual role mode\n"); | ||
376 | return -EINVAL; | ||
377 | } | ||
378 | |||
379 | if (musb->port1_status & USB_PORT_STAT_ENABLE) | ||
380 | musb_root_disconnect(musb); | ||
381 | |||
382 | /* | ||
383 | * phy_set_mode may sleep, and we're called with a spinlock held, | ||
384 | * so let sunxi_musb_work deal with it. | ||
385 | */ | ||
386 | glue->phy_mode = new_mode; | ||
387 | set_bit(SUNXI_MUSB_FL_PHY_MODE_PEND, &glue->flags); | ||
388 | schedule_work(&glue->work); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
344 | /* | 393 | /* |
345 | * sunxi musb register layout | 394 | * sunxi musb register layout |
346 | * 0x00 - 0x17 fifo regs, 1 long per fifo | 395 | * 0x00 - 0x17 fifo regs, 1 long per fifo |
@@ -568,6 +617,7 @@ static const struct musb_platform_ops sunxi_musb_ops = { | |||
568 | .writew = sunxi_musb_writew, | 617 | .writew = sunxi_musb_writew, |
569 | .dma_init = sunxi_musb_dma_controller_create, | 618 | .dma_init = sunxi_musb_dma_controller_create, |
570 | .dma_exit = sunxi_musb_dma_controller_destroy, | 619 | .dma_exit = sunxi_musb_dma_controller_destroy, |
620 | .set_mode = sunxi_musb_set_mode, | ||
571 | .set_vbus = sunxi_musb_set_vbus, | 621 | .set_vbus = sunxi_musb_set_vbus, |
572 | .pre_root_reset_end = sunxi_musb_pre_root_reset_end, | 622 | .pre_root_reset_end = sunxi_musb_pre_root_reset_end, |
573 | .post_root_reset_end = sunxi_musb_post_root_reset_end, | 623 | .post_root_reset_end = sunxi_musb_post_root_reset_end, |
@@ -614,21 +664,28 @@ static int sunxi_musb_probe(struct platform_device *pdev) | |||
614 | return -EINVAL; | 664 | return -EINVAL; |
615 | } | 665 | } |
616 | 666 | ||
667 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | ||
668 | if (!glue) | ||
669 | return -ENOMEM; | ||
670 | |||
617 | memset(&pdata, 0, sizeof(pdata)); | 671 | memset(&pdata, 0, sizeof(pdata)); |
618 | switch (usb_get_dr_mode(&pdev->dev)) { | 672 | switch (usb_get_dr_mode(&pdev->dev)) { |
619 | #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST | 673 | #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST |
620 | case USB_DR_MODE_HOST: | 674 | case USB_DR_MODE_HOST: |
621 | pdata.mode = MUSB_PORT_MODE_HOST; | 675 | pdata.mode = MUSB_PORT_MODE_HOST; |
676 | glue->phy_mode = PHY_MODE_USB_HOST; | ||
622 | break; | 677 | break; |
623 | #endif | 678 | #endif |
624 | #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET | 679 | #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET |
625 | case USB_DR_MODE_PERIPHERAL: | 680 | case USB_DR_MODE_PERIPHERAL: |
626 | pdata.mode = MUSB_PORT_MODE_GADGET; | 681 | pdata.mode = MUSB_PORT_MODE_GADGET; |
682 | glue->phy_mode = PHY_MODE_USB_DEVICE; | ||
627 | break; | 683 | break; |
628 | #endif | 684 | #endif |
629 | #ifdef CONFIG_USB_MUSB_DUAL_ROLE | 685 | #ifdef CONFIG_USB_MUSB_DUAL_ROLE |
630 | case USB_DR_MODE_OTG: | 686 | case USB_DR_MODE_OTG: |
631 | pdata.mode = MUSB_PORT_MODE_DUAL_ROLE; | 687 | pdata.mode = MUSB_PORT_MODE_DUAL_ROLE; |
688 | glue->phy_mode = PHY_MODE_USB_OTG; | ||
632 | break; | 689 | break; |
633 | #endif | 690 | #endif |
634 | default: | 691 | default: |
@@ -638,10 +695,6 @@ static int sunxi_musb_probe(struct platform_device *pdev) | |||
638 | pdata.platform_ops = &sunxi_musb_ops; | 695 | pdata.platform_ops = &sunxi_musb_ops; |
639 | pdata.config = &sunxi_musb_hdrc_config; | 696 | pdata.config = &sunxi_musb_hdrc_config; |
640 | 697 | ||
641 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | ||
642 | if (!glue) | ||
643 | return -ENOMEM; | ||
644 | |||
645 | glue->dev = &pdev->dev; | 698 | glue->dev = &pdev->dev; |
646 | INIT_WORK(&glue->work, sunxi_musb_work); | 699 | INIT_WORK(&glue->work, sunxi_musb_work); |
647 | glue->host_nb.notifier_call = sunxi_musb_host_notifier; | 700 | glue->host_nb.notifier_call = sunxi_musb_host_notifier; |
diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 0c912d3950a5..a03caf4b1327 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c | |||
@@ -1248,7 +1248,7 @@ static void ab8500_usb_set_ab8500_tuning_values(struct ab8500_usb *ab) | |||
1248 | err = abx500_set_register_interruptible(ab->dev, | 1248 | err = abx500_set_register_interruptible(ab->dev, |
1249 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); | 1249 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); |
1250 | if (err < 0) | 1250 | if (err < 0) |
1251 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", | 1251 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n", |
1252 | err); | 1252 | err); |
1253 | 1253 | ||
1254 | /* Switch to normal mode/disable Bank 0x12 access */ | 1254 | /* Switch to normal mode/disable Bank 0x12 access */ |
@@ -1290,7 +1290,7 @@ static void ab8500_usb_set_ab8505_tuning_values(struct ab8500_usb *ab) | |||
1290 | 0xFC, 0x80); | 1290 | 0xFC, 0x80); |
1291 | 1291 | ||
1292 | if (err < 0) | 1292 | if (err < 0) |
1293 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", | 1293 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n", |
1294 | err); | 1294 | err); |
1295 | 1295 | ||
1296 | /* Switch to normal mode/disable Bank 0x12 access */ | 1296 | /* Switch to normal mode/disable Bank 0x12 access */ |
@@ -1321,7 +1321,7 @@ static void ab8500_usb_set_ab8540_tuning_values(struct ab8500_usb *ab) | |||
1321 | err = abx500_set_register_interruptible(ab->dev, | 1321 | err = abx500_set_register_interruptible(ab->dev, |
1322 | AB8540_DEBUG, AB8500_USB_PHY_TUNE3, 0x90); | 1322 | AB8540_DEBUG, AB8500_USB_PHY_TUNE3, 0x90); |
1323 | if (err < 0) | 1323 | if (err < 0) |
1324 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester ret=%d\n", | 1324 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register ret=%d\n", |
1325 | err); | 1325 | err); |
1326 | } | 1326 | } |
1327 | 1327 | ||
@@ -1351,7 +1351,7 @@ static void ab8500_usb_set_ab9540_tuning_values(struct ab8500_usb *ab) | |||
1351 | err = abx500_set_register_interruptible(ab->dev, | 1351 | err = abx500_set_register_interruptible(ab->dev, |
1352 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x80); | 1352 | AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x80); |
1353 | if (err < 0) | 1353 | if (err < 0) |
1354 | dev_err(ab->dev, "Failed to set PHY_TUNE3 regester err=%d\n", | 1354 | dev_err(ab->dev, "Failed to set PHY_TUNE3 register err=%d\n", |
1355 | err); | 1355 | err); |
1356 | 1356 | ||
1357 | /* Switch to normal mode/disable Bank 0x12 access */ | 1357 | /* Switch to normal mode/disable Bank 0x12 access */ |
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 427efb5eebae..8311ba2968cd 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -118,8 +118,6 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | |||
118 | status = USB_EVENT_VBUS; | 118 | status = USB_EVENT_VBUS; |
119 | otg->state = OTG_STATE_B_PERIPHERAL; | 119 | otg->state = OTG_STATE_B_PERIPHERAL; |
120 | nop->phy.last_event = status; | 120 | nop->phy.last_event = status; |
121 | if (otg->gadget) | ||
122 | usb_gadget_vbus_connect(otg->gadget); | ||
123 | 121 | ||
124 | /* drawing a "unit load" is *always* OK, except for OTG */ | 122 | /* drawing a "unit load" is *always* OK, except for OTG */ |
125 | nop_set_vbus_draw(nop, 100); | 123 | nop_set_vbus_draw(nop, 100); |
@@ -129,8 +127,6 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | |||
129 | } else { | 127 | } else { |
130 | nop_set_vbus_draw(nop, 0); | 128 | nop_set_vbus_draw(nop, 0); |
131 | 129 | ||
132 | if (otg->gadget) | ||
133 | usb_gadget_vbus_disconnect(otg->gadget); | ||
134 | status = USB_EVENT_NONE; | 130 | status = USB_EVENT_NONE; |
135 | otg->state = OTG_STATE_B_IDLE; | 131 | otg->state = OTG_STATE_B_IDLE; |
136 | nop->phy.last_event = status; | 132 | nop->phy.last_event = status; |
@@ -191,7 +187,8 @@ static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) | |||
191 | 187 | ||
192 | otg->gadget = gadget; | 188 | otg->gadget = gadget; |
193 | if (otg->state == OTG_STATE_B_PERIPHERAL) | 189 | if (otg->state == OTG_STATE_B_PERIPHERAL) |
194 | usb_gadget_vbus_connect(gadget); | 190 | atomic_notifier_call_chain(&otg->usb_phy->notifier, |
191 | USB_EVENT_VBUS, otg->gadget); | ||
195 | else | 192 | else |
196 | otg->state = OTG_STATE_B_IDLE; | 193 | otg->state = OTG_STATE_B_IDLE; |
197 | return 0; | 194 | return 0; |
@@ -326,6 +323,8 @@ static int usb_phy_generic_probe(struct platform_device *pdev) | |||
326 | gpiod_to_irq(nop->gpiod_vbus), err); | 323 | gpiod_to_irq(nop->gpiod_vbus), err); |
327 | return err; | 324 | return err; |
328 | } | 325 | } |
326 | nop->phy.otg->state = gpiod_get_value(nop->gpiod_vbus) ? | ||
327 | OTG_STATE_B_PERIPHERAL : OTG_STATE_B_IDLE; | ||
329 | } | 328 | } |
330 | 329 | ||
331 | nop->phy.init = usb_gen_phy_init; | 330 | nop->phy.init = usb_gen_phy_init; |
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 00bfea01be65..0e2f1a36d315 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #define DRIVER_NAME "mxs_phy" | 27 | #define DRIVER_NAME "mxs_phy" |
28 | 28 | ||
29 | #define HW_USBPHY_PWD 0x00 | 29 | #define HW_USBPHY_PWD 0x00 |
30 | #define HW_USBPHY_TX 0x10 | ||
30 | #define HW_USBPHY_CTRL 0x30 | 31 | #define HW_USBPHY_CTRL 0x30 |
31 | #define HW_USBPHY_CTRL_SET 0x34 | 32 | #define HW_USBPHY_CTRL_SET 0x34 |
32 | #define HW_USBPHY_CTRL_CLR 0x38 | 33 | #define HW_USBPHY_CTRL_CLR 0x38 |
@@ -38,6 +39,10 @@ | |||
38 | #define HW_USBPHY_IP_SET 0x94 | 39 | #define HW_USBPHY_IP_SET 0x94 |
39 | #define HW_USBPHY_IP_CLR 0x98 | 40 | #define HW_USBPHY_IP_CLR 0x98 |
40 | 41 | ||
42 | #define GM_USBPHY_TX_TXCAL45DP(x) (((x) & 0xf) << 16) | ||
43 | #define GM_USBPHY_TX_TXCAL45DN(x) (((x) & 0xf) << 8) | ||
44 | #define GM_USBPHY_TX_D_CAL(x) (((x) & 0xf) << 0) | ||
45 | |||
41 | #define BM_USBPHY_CTRL_SFTRST BIT(31) | 46 | #define BM_USBPHY_CTRL_SFTRST BIT(31) |
42 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) | 47 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) |
43 | #define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27) | 48 | #define BM_USBPHY_CTRL_OTG_ID_VALUE BIT(27) |
@@ -115,6 +120,12 @@ | |||
115 | */ | 120 | */ |
116 | #define MXS_PHY_NEED_IP_FIX BIT(3) | 121 | #define MXS_PHY_NEED_IP_FIX BIT(3) |
117 | 122 | ||
123 | /* Minimum and maximum values for device tree entries */ | ||
124 | #define MXS_PHY_TX_CAL45_MIN 30 | ||
125 | #define MXS_PHY_TX_CAL45_MAX 55 | ||
126 | #define MXS_PHY_TX_D_CAL_MIN 79 | ||
127 | #define MXS_PHY_TX_D_CAL_MAX 119 | ||
128 | |||
118 | struct mxs_phy_data { | 129 | struct mxs_phy_data { |
119 | unsigned int flags; | 130 | unsigned int flags; |
120 | }; | 131 | }; |
@@ -164,6 +175,8 @@ struct mxs_phy { | |||
164 | const struct mxs_phy_data *data; | 175 | const struct mxs_phy_data *data; |
165 | struct regmap *regmap_anatop; | 176 | struct regmap *regmap_anatop; |
166 | int port_id; | 177 | int port_id; |
178 | u32 tx_reg_set; | ||
179 | u32 tx_reg_mask; | ||
167 | }; | 180 | }; |
168 | 181 | ||
169 | static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy) | 182 | static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy) |
@@ -185,6 +198,20 @@ static void mxs_phy_clock_switch_delay(void) | |||
185 | usleep_range(300, 400); | 198 | usleep_range(300, 400); |
186 | } | 199 | } |
187 | 200 | ||
201 | static void mxs_phy_tx_init(struct mxs_phy *mxs_phy) | ||
202 | { | ||
203 | void __iomem *base = mxs_phy->phy.io_priv; | ||
204 | u32 phytx; | ||
205 | |||
206 | /* Update TX register if there is anything to write */ | ||
207 | if (mxs_phy->tx_reg_mask) { | ||
208 | phytx = readl(base + HW_USBPHY_TX); | ||
209 | phytx &= ~mxs_phy->tx_reg_mask; | ||
210 | phytx |= mxs_phy->tx_reg_set; | ||
211 | writel(phytx, base + HW_USBPHY_TX); | ||
212 | } | ||
213 | } | ||
214 | |||
188 | static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) | 215 | static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) |
189 | { | 216 | { |
190 | int ret; | 217 | int ret; |
@@ -214,6 +241,8 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) | |||
214 | if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) | 241 | if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) |
215 | writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); | 242 | writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); |
216 | 243 | ||
244 | mxs_phy_tx_init(mxs_phy); | ||
245 | |||
217 | return 0; | 246 | return 0; |
218 | } | 247 | } |
219 | 248 | ||
@@ -459,6 +488,7 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
459 | int ret; | 488 | int ret; |
460 | const struct of_device_id *of_id; | 489 | const struct of_device_id *of_id; |
461 | struct device_node *np = pdev->dev.of_node; | 490 | struct device_node *np = pdev->dev.of_node; |
491 | u32 val; | ||
462 | 492 | ||
463 | of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev); | 493 | of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev); |
464 | if (!of_id) | 494 | if (!of_id) |
@@ -491,6 +521,37 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
491 | } | 521 | } |
492 | } | 522 | } |
493 | 523 | ||
524 | /* Precompute which bits of the TX register are to be updated, if any */ | ||
525 | if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) && | ||
526 | val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) { | ||
527 | /* Scale to a 4-bit value */ | ||
528 | val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF | ||
529 | / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN); | ||
530 | mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0); | ||
531 | mxs_phy->tx_reg_set |= GM_USBPHY_TX_TXCAL45DN(val); | ||
532 | } | ||
533 | |||
534 | if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) && | ||
535 | val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) { | ||
536 | /* Scale to a 4-bit value. */ | ||
537 | val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF | ||
538 | / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN); | ||
539 | mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0); | ||
540 | mxs_phy->tx_reg_set |= GM_USBPHY_TX_TXCAL45DP(val); | ||
541 | } | ||
542 | |||
543 | if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) && | ||
544 | val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) { | ||
545 | /* Scale to a 4-bit value. Round up the values and heavily | ||
546 | * weight the rounding by adding 2/3 of the denominator. | ||
547 | */ | ||
548 | val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF | ||
549 | + (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3) | ||
550 | / (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN); | ||
551 | mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0); | ||
552 | mxs_phy->tx_reg_set |= GM_USBPHY_TX_D_CAL(val); | ||
553 | } | ||
554 | |||
494 | ret = of_alias_get_id(np, "usbphy"); | 555 | ret = of_alias_get_id(np, "usbphy"); |
495 | if (ret < 0) | 556 | if (ret < 0) |
496 | dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret); | 557 | dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret); |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index ac67bab9124c..012a37aa3e0d 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -482,6 +482,10 @@ static const struct of_device_id usbhs_of_match[] = { | |||
482 | .data = (void *)USBHS_TYPE_RCAR_GEN3, | 482 | .data = (void *)USBHS_TYPE_RCAR_GEN3, |
483 | }, | 483 | }, |
484 | { | 484 | { |
485 | .compatible = "renesas,usbhs-r8a7796", | ||
486 | .data = (void *)USBHS_TYPE_RCAR_GEN3, | ||
487 | }, | ||
488 | { | ||
485 | .compatible = "renesas,rcar-gen2-usbhs", | 489 | .compatible = "renesas,rcar-gen2-usbhs", |
486 | .data = (void *)USBHS_TYPE_RCAR_GEN2, | 490 | .data = (void *)USBHS_TYPE_RCAR_GEN2, |
487 | }, | 491 | }, |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index c4c64740a3e7..5bc7a6138855 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -335,7 +335,6 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, | |||
335 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | 335 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); |
336 | if (!buf) { | 336 | if (!buf) { |
337 | usb_ep_free_request(&dcp->ep, req); | 337 | usb_ep_free_request(&dcp->ep, req); |
338 | dev_err(dev, "recip data allocation fail\n"); | ||
339 | return; | 338 | return; |
340 | } | 339 | } |
341 | 340 | ||
@@ -1062,14 +1061,11 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
1062 | int ret; | 1061 | int ret; |
1063 | 1062 | ||
1064 | gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); | 1063 | gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); |
1065 | if (!gpriv) { | 1064 | if (!gpriv) |
1066 | dev_err(dev, "Could not allocate gadget priv\n"); | ||
1067 | return -ENOMEM; | 1065 | return -ENOMEM; |
1068 | } | ||
1069 | 1066 | ||
1070 | uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); | 1067 | uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); |
1071 | if (!uep) { | 1068 | if (!uep) { |
1072 | dev_err(dev, "Could not allocate ep\n"); | ||
1073 | ret = -ENOMEM; | 1069 | ret = -ENOMEM; |
1074 | goto usbhs_mod_gadget_probe_err_gpriv; | 1070 | goto usbhs_mod_gadget_probe_err_gpriv; |
1075 | } | 1071 | } |
@@ -1106,6 +1102,8 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
1106 | gpriv->gadget.name = "renesas_usbhs_udc"; | 1102 | gpriv->gadget.name = "renesas_usbhs_udc"; |
1107 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 1103 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
1108 | gpriv->gadget.max_speed = USB_SPEED_HIGH; | 1104 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |
1105 | gpriv->gadget.quirk_avoids_skb_reserve = usbhs_get_dparam(priv, | ||
1106 | has_usb_dmac); | ||
1109 | 1107 | ||
1110 | INIT_LIST_HEAD(&gpriv->gadget.ep_list); | 1108 | INIT_LIST_HEAD(&gpriv->gadget.ep_list); |
1111 | 1109 | ||
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 3bf0b72eb359..165e81bfd93a 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -166,14 +166,10 @@ static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, | |||
166 | gfp_t mem_flags) | 166 | gfp_t mem_flags) |
167 | { | 167 | { |
168 | struct usbhsh_request *ureq; | 168 | struct usbhsh_request *ureq; |
169 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
170 | struct device *dev = usbhs_priv_to_dev(priv); | ||
171 | 169 | ||
172 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); | 170 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); |
173 | if (!ureq) { | 171 | if (!ureq) |
174 | dev_err(dev, "ureq alloc fail\n"); | ||
175 | return NULL; | 172 | return NULL; |
176 | } | ||
177 | 173 | ||
178 | usbhs_pkt_init(&ureq->pkt); | 174 | usbhs_pkt_init(&ureq->pkt); |
179 | ureq->urb = urb; | 175 | ureq->urb = urb; |
@@ -388,10 +384,8 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, | |||
388 | unsigned long flags; | 384 | unsigned long flags; |
389 | 385 | ||
390 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 386 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); |
391 | if (!uep) { | 387 | if (!uep) |
392 | dev_err(dev, "usbhsh_ep alloc fail\n"); | ||
393 | return -ENOMEM; | 388 | return -ENOMEM; |
394 | } | ||
395 | 389 | ||
396 | /******************** spin lock ********************/ | 390 | /******************** spin lock ********************/ |
397 | usbhs_lock(priv, flags); | 391 | usbhs_lock(priv, flags); |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index c238772b9e9e..9396a8c14af8 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
@@ -804,10 +804,8 @@ int usbhs_pipe_probe(struct usbhs_priv *priv) | |||
804 | } | 804 | } |
805 | 805 | ||
806 | info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL); | 806 | info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL); |
807 | if (!info->pipe) { | 807 | if (!info->pipe) |
808 | dev_err(dev, "Could not allocate pipe\n"); | ||
809 | return -ENOMEM; | 808 | return -ENOMEM; |
810 | } | ||
811 | 809 | ||
812 | info->size = pipe_size; | 810 | info->size = pipe_size; |
813 | 811 | ||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 4d6a5c672a3d..54a4de0efdba 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = { | |||
118 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ | 118 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ |
119 | { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ | 119 | { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ |
120 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 120 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
121 | { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ | ||
121 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ | 122 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ |
122 | { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ | 123 | { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ |
123 | { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ | 124 | { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 4f7e072e4e00..e49ad0c63ad8 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -30,12 +30,12 @@ | |||
30 | #include <linux/usb/ezusb.h> | 30 | #include <linux/usb/ezusb.h> |
31 | 31 | ||
32 | /* make a simple define to handle if we are compiling keyspan_pda or xircom support */ | 32 | /* make a simple define to handle if we are compiling keyspan_pda or xircom support */ |
33 | #if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE) | 33 | #if IS_ENABLED(CONFIG_USB_SERIAL_KEYSPAN_PDA) |
34 | #define KEYSPAN | 34 | #define KEYSPAN |
35 | #else | 35 | #else |
36 | #undef KEYSPAN | 36 | #undef KEYSPAN |
37 | #endif | 37 | #endif |
38 | #if defined(CONFIG_USB_SERIAL_XIRCOM) || defined(CONFIG_USB_SERIAL_XIRCOM_MODULE) | 38 | #if IS_ENABLED(CONFIG_USB_SERIAL_XIRCOM) |
39 | #define XIRCOM | 39 | #define XIRCOM |
40 | #else | 40 | #else |
41 | #undef XIRCOM | 41 | #undef XIRCOM |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 07b4bf01061d..a8b9bdba314f 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -179,23 +179,23 @@ | |||
179 | 179 | ||
180 | /* Config struct */ | 180 | /* Config struct */ |
181 | struct ti_uart_config { | 181 | struct ti_uart_config { |
182 | __u16 wBaudRate; | 182 | __be16 wBaudRate; |
183 | __u16 wFlags; | 183 | __be16 wFlags; |
184 | __u8 bDataBits; | 184 | u8 bDataBits; |
185 | __u8 bParity; | 185 | u8 bParity; |
186 | __u8 bStopBits; | 186 | u8 bStopBits; |
187 | char cXon; | 187 | char cXon; |
188 | char cXoff; | 188 | char cXoff; |
189 | __u8 bUartMode; | 189 | u8 bUartMode; |
190 | } __packed; | 190 | } __packed; |
191 | 191 | ||
192 | /* Get port status */ | 192 | /* Get port status */ |
193 | struct ti_port_status { | 193 | struct ti_port_status { |
194 | __u8 bCmdCode; | 194 | u8 bCmdCode; |
195 | __u8 bModuleId; | 195 | u8 bModuleId; |
196 | __u8 bErrorCode; | 196 | u8 bErrorCode; |
197 | __u8 bMSR; | 197 | u8 bMSR; |
198 | __u8 bLSR; | 198 | u8 bLSR; |
199 | } __packed; | 199 | } __packed; |
200 | 200 | ||
201 | /* Purge modes */ | 201 | /* Purge modes */ |
@@ -218,12 +218,12 @@ struct ti_port_status { | |||
218 | #define TI_RW_DATA_DOUBLE_WORD 0x04 | 218 | #define TI_RW_DATA_DOUBLE_WORD 0x04 |
219 | 219 | ||
220 | struct ti_write_data_bytes { | 220 | struct ti_write_data_bytes { |
221 | __u8 bAddrType; | 221 | u8 bAddrType; |
222 | __u8 bDataType; | 222 | u8 bDataType; |
223 | __u8 bDataCounter; | 223 | u8 bDataCounter; |
224 | __be16 wBaseAddrHi; | 224 | __be16 wBaseAddrHi; |
225 | __be16 wBaseAddrLo; | 225 | __be16 wBaseAddrLo; |
226 | __u8 bData[0]; | 226 | u8 bData[0]; |
227 | } __packed; | 227 | } __packed; |
228 | 228 | ||
229 | struct ti_read_data_request { | 229 | struct ti_read_data_request { |
@@ -258,7 +258,7 @@ struct ti_interrupt { | |||
258 | /* Firmware image header */ | 258 | /* Firmware image header */ |
259 | struct ti_firmware_header { | 259 | struct ti_firmware_header { |
260 | __le16 wLength; | 260 | __le16 wLength; |
261 | __u8 bCheckSum; | 261 | u8 bCheckSum; |
262 | } __packed; | 262 | } __packed; |
263 | 263 | ||
264 | /* UART addresses */ | 264 | /* UART addresses */ |
@@ -276,9 +276,6 @@ struct ti_firmware_header { | |||
276 | 276 | ||
277 | #define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ | 277 | #define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ |
278 | 278 | ||
279 | /* supported setserial flags */ | ||
280 | #define TI_SET_SERIAL_FLAGS 0 | ||
281 | |||
282 | /* read urb states */ | 279 | /* read urb states */ |
283 | #define TI_READ_URB_RUNNING 0 | 280 | #define TI_READ_URB_RUNNING 0 |
284 | #define TI_READ_URB_STOPPING 1 | 281 | #define TI_READ_URB_STOPPING 1 |
@@ -288,11 +285,10 @@ struct ti_firmware_header { | |||
288 | 285 | ||
289 | struct ti_port { | 286 | struct ti_port { |
290 | int tp_is_open; | 287 | int tp_is_open; |
291 | __u8 tp_msr; | 288 | u8 tp_msr; |
292 | __u8 tp_shadow_mcr; | 289 | u8 tp_shadow_mcr; |
293 | __u8 tp_uart_mode; /* 232 or 485 modes */ | 290 | u8 tp_uart_mode; /* 232 or 485 modes */ |
294 | unsigned int tp_uart_base_addr; | 291 | unsigned int tp_uart_base_addr; |
295 | int tp_flags; | ||
296 | struct ti_device *tp_tdev; | 292 | struct ti_device *tp_tdev; |
297 | struct usb_serial_port *tp_port; | 293 | struct usb_serial_port *tp_port; |
298 | spinlock_t tp_lock; | 294 | spinlock_t tp_lock; |
@@ -306,7 +302,6 @@ struct ti_device { | |||
306 | struct usb_serial *td_serial; | 302 | struct usb_serial *td_serial; |
307 | int td_is_3410; | 303 | int td_is_3410; |
308 | bool td_rs485_only; | 304 | bool td_rs485_only; |
309 | int td_urb_error; | ||
310 | }; | 305 | }; |
311 | 306 | ||
312 | static int ti_startup(struct usb_serial *serial); | 307 | static int ti_startup(struct usb_serial *serial); |
@@ -343,7 +338,7 @@ static int ti_get_serial_info(struct ti_port *tport, | |||
343 | struct serial_struct __user *ret_arg); | 338 | struct serial_struct __user *ret_arg); |
344 | static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, | 339 | static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, |
345 | struct serial_struct __user *new_arg); | 340 | struct serial_struct __user *new_arg); |
346 | static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); | 341 | static void ti_handle_new_msr(struct ti_port *tport, u8 msr); |
347 | 342 | ||
348 | static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty); | 343 | static void ti_stop_read(struct ti_port *tport, struct tty_struct *tty); |
349 | static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty); | 344 | static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty); |
@@ -354,7 +349,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, | |||
354 | __u16 moduleid, __u16 value, __u8 *data, int size); | 349 | __u16 moduleid, __u16 value, __u8 *data, int size); |
355 | 350 | ||
356 | static int ti_write_byte(struct usb_serial_port *port, struct ti_device *tdev, | 351 | static int ti_write_byte(struct usb_serial_port *port, struct ti_device *tdev, |
357 | unsigned long addr, __u8 mask, __u8 byte); | 352 | unsigned long addr, u8 mask, u8 byte); |
358 | 353 | ||
359 | static int ti_download_firmware(struct ti_device *tdev); | 354 | static int ti_download_firmware(struct ti_device *tdev); |
360 | 355 | ||
@@ -647,12 +642,11 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
647 | struct urb *urb; | 642 | struct urb *urb; |
648 | int port_number; | 643 | int port_number; |
649 | int status; | 644 | int status; |
650 | __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINUOUS | | 645 | u16 open_settings; |
651 | TI_PIPE_TIMEOUT_ENABLE | | ||
652 | (TI_TRANSFER_TIMEOUT << 2)); | ||
653 | 646 | ||
654 | if (tport == NULL) | 647 | open_settings = (TI_PIPE_MODE_CONTINUOUS | |
655 | return -ENODEV; | 648 | TI_PIPE_TIMEOUT_ENABLE | |
649 | (TI_TRANSFER_TIMEOUT << 2)); | ||
656 | 650 | ||
657 | dev = port->serial->dev; | 651 | dev = port->serial->dev; |
658 | tdev = tport->tp_tdev; | 652 | tdev = tport->tp_tdev; |
@@ -686,7 +680,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
686 | if (tty) | 680 | if (tty) |
687 | ti_set_termios(tty, port, &tty->termios); | 681 | ti_set_termios(tty, port, &tty->termios); |
688 | 682 | ||
689 | dev_dbg(&port->dev, "%s - sending TI_OPEN_PORT\n", __func__); | ||
690 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 683 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
691 | (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); | 684 | (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); |
692 | if (status) { | 685 | if (status) { |
@@ -695,7 +688,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
695 | goto unlink_int_urb; | 688 | goto unlink_int_urb; |
696 | } | 689 | } |
697 | 690 | ||
698 | dev_dbg(&port->dev, "%s - sending TI_START_PORT\n", __func__); | ||
699 | status = ti_command_out_sync(tdev, TI_START_PORT, | 691 | status = ti_command_out_sync(tdev, TI_START_PORT, |
700 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); | 692 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); |
701 | if (status) { | 693 | if (status) { |
@@ -704,7 +696,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
704 | goto unlink_int_urb; | 696 | goto unlink_int_urb; |
705 | } | 697 | } |
706 | 698 | ||
707 | dev_dbg(&port->dev, "%s - sending TI_PURGE_PORT\n", __func__); | ||
708 | status = ti_command_out_sync(tdev, TI_PURGE_PORT, | 699 | status = ti_command_out_sync(tdev, TI_PURGE_PORT, |
709 | (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0); | 700 | (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0); |
710 | if (status) { | 701 | if (status) { |
@@ -728,7 +719,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
728 | if (tty) | 719 | if (tty) |
729 | ti_set_termios(tty, port, &tty->termios); | 720 | ti_set_termios(tty, port, &tty->termios); |
730 | 721 | ||
731 | dev_dbg(&port->dev, "%s - sending TI_OPEN_PORT (2)\n", __func__); | ||
732 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 722 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
733 | (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); | 723 | (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0); |
734 | if (status) { | 724 | if (status) { |
@@ -737,7 +727,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
737 | goto unlink_int_urb; | 727 | goto unlink_int_urb; |
738 | } | 728 | } |
739 | 729 | ||
740 | dev_dbg(&port->dev, "%s - sending TI_START_PORT (2)\n", __func__); | ||
741 | status = ti_command_out_sync(tdev, TI_START_PORT, | 730 | status = ti_command_out_sync(tdev, TI_START_PORT, |
742 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); | 731 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); |
743 | if (status) { | 732 | if (status) { |
@@ -747,7 +736,6 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
747 | } | 736 | } |
748 | 737 | ||
749 | /* start read urb */ | 738 | /* start read urb */ |
750 | dev_dbg(&port->dev, "%s - start read urb\n", __func__); | ||
751 | urb = port->read_urb; | 739 | urb = port->read_urb; |
752 | if (!urb) { | 740 | if (!urb) { |
753 | dev_err(&port->dev, "%s - no read urb\n", __func__); | 741 | dev_err(&port->dev, "%s - no read urb\n", __func__); |
@@ -773,7 +761,6 @@ unlink_int_urb: | |||
773 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); | 761 | usb_kill_urb(port->serial->port[0]->interrupt_in_urb); |
774 | release_lock: | 762 | release_lock: |
775 | mutex_unlock(&tdev->td_open_close_lock); | 763 | mutex_unlock(&tdev->td_open_close_lock); |
776 | dev_dbg(&port->dev, "%s - exit %d\n", __func__, status); | ||
777 | return status; | 764 | return status; |
778 | } | 765 | } |
779 | 766 | ||
@@ -789,8 +776,6 @@ static void ti_close(struct usb_serial_port *port) | |||
789 | 776 | ||
790 | tdev = usb_get_serial_data(port->serial); | 777 | tdev = usb_get_serial_data(port->serial); |
791 | tport = usb_get_serial_port_data(port); | 778 | tport = usb_get_serial_port_data(port); |
792 | if (tdev == NULL || tport == NULL) | ||
793 | return; | ||
794 | 779 | ||
795 | tport->tp_is_open = 0; | 780 | tport->tp_is_open = 0; |
796 | 781 | ||
@@ -803,7 +788,6 @@ static void ti_close(struct usb_serial_port *port) | |||
803 | 788 | ||
804 | port_number = port->port_number; | 789 | port_number = port->port_number; |
805 | 790 | ||
806 | dev_dbg(&port->dev, "%s - sending TI_CLOSE_PORT\n", __func__); | ||
807 | status = ti_command_out_sync(tdev, TI_CLOSE_PORT, | 791 | status = ti_command_out_sync(tdev, TI_CLOSE_PORT, |
808 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); | 792 | (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0); |
809 | if (status) | 793 | if (status) |
@@ -830,11 +814,10 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
830 | struct ti_port *tport = usb_get_serial_port_data(port); | 814 | struct ti_port *tport = usb_get_serial_port_data(port); |
831 | 815 | ||
832 | if (count == 0) { | 816 | if (count == 0) { |
833 | dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__); | ||
834 | return 0; | 817 | return 0; |
835 | } | 818 | } |
836 | 819 | ||
837 | if (tport == NULL || !tport->tp_is_open) | 820 | if (!tport->tp_is_open) |
838 | return -ENODEV; | 821 | return -ENODEV; |
839 | 822 | ||
840 | count = kfifo_in_locked(&port->write_fifo, data, count, | 823 | count = kfifo_in_locked(&port->write_fifo, data, count, |
@@ -852,9 +835,6 @@ static int ti_write_room(struct tty_struct *tty) | |||
852 | int room = 0; | 835 | int room = 0; |
853 | unsigned long flags; | 836 | unsigned long flags; |
854 | 837 | ||
855 | if (tport == NULL) | ||
856 | return 0; | ||
857 | |||
858 | spin_lock_irqsave(&tport->tp_lock, flags); | 838 | spin_lock_irqsave(&tport->tp_lock, flags); |
859 | room = kfifo_avail(&port->write_fifo); | 839 | room = kfifo_avail(&port->write_fifo); |
860 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 840 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
@@ -871,9 +851,6 @@ static int ti_chars_in_buffer(struct tty_struct *tty) | |||
871 | int chars = 0; | 851 | int chars = 0; |
872 | unsigned long flags; | 852 | unsigned long flags; |
873 | 853 | ||
874 | if (tport == NULL) | ||
875 | return 0; | ||
876 | |||
877 | spin_lock_irqsave(&tport->tp_lock, flags); | 854 | spin_lock_irqsave(&tport->tp_lock, flags); |
878 | chars = kfifo_len(&port->write_fifo); | 855 | chars = kfifo_len(&port->write_fifo); |
879 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 856 | spin_unlock_irqrestore(&tport->tp_lock, flags); |
@@ -900,9 +877,6 @@ static void ti_throttle(struct tty_struct *tty) | |||
900 | struct usb_serial_port *port = tty->driver_data; | 877 | struct usb_serial_port *port = tty->driver_data; |
901 | struct ti_port *tport = usb_get_serial_port_data(port); | 878 | struct ti_port *tport = usb_get_serial_port_data(port); |
902 | 879 | ||
903 | if (tport == NULL) | ||
904 | return; | ||
905 | |||
906 | if (I_IXOFF(tty) || C_CRTSCTS(tty)) | 880 | if (I_IXOFF(tty) || C_CRTSCTS(tty)) |
907 | ti_stop_read(tport, tty); | 881 | ti_stop_read(tport, tty); |
908 | 882 | ||
@@ -915,9 +889,6 @@ static void ti_unthrottle(struct tty_struct *tty) | |||
915 | struct ti_port *tport = usb_get_serial_port_data(port); | 889 | struct ti_port *tport = usb_get_serial_port_data(port); |
916 | int status; | 890 | int status; |
917 | 891 | ||
918 | if (tport == NULL) | ||
919 | return; | ||
920 | |||
921 | if (I_IXOFF(tty) || C_CRTSCTS(tty)) { | 892 | if (I_IXOFF(tty) || C_CRTSCTS(tty)) { |
922 | status = ti_restart_read(tport, tty); | 893 | status = ti_restart_read(tport, tty); |
923 | if (status) | 894 | if (status) |
@@ -932,16 +903,11 @@ static int ti_ioctl(struct tty_struct *tty, | |||
932 | struct usb_serial_port *port = tty->driver_data; | 903 | struct usb_serial_port *port = tty->driver_data; |
933 | struct ti_port *tport = usb_get_serial_port_data(port); | 904 | struct ti_port *tport = usb_get_serial_port_data(port); |
934 | 905 | ||
935 | if (tport == NULL) | ||
936 | return -ENODEV; | ||
937 | |||
938 | switch (cmd) { | 906 | switch (cmd) { |
939 | case TIOCGSERIAL: | 907 | case TIOCGSERIAL: |
940 | dev_dbg(&port->dev, "%s - TIOCGSERIAL\n", __func__); | ||
941 | return ti_get_serial_info(tport, | 908 | return ti_get_serial_info(tport, |
942 | (struct serial_struct __user *)arg); | 909 | (struct serial_struct __user *)arg); |
943 | case TIOCSSERIAL: | 910 | case TIOCSSERIAL: |
944 | dev_dbg(&port->dev, "%s - TIOCSSERIAL\n", __func__); | ||
945 | return ti_set_serial_info(tty, tport, | 911 | return ti_set_serial_info(tty, tport, |
946 | (struct serial_struct __user *)arg); | 912 | (struct serial_struct __user *)arg); |
947 | } | 913 | } |
@@ -959,6 +925,8 @@ static void ti_set_termios(struct tty_struct *tty, | |||
959 | int status; | 925 | int status; |
960 | int port_number = port->port_number; | 926 | int port_number = port->port_number; |
961 | unsigned int mcr; | 927 | unsigned int mcr; |
928 | u16 wbaudrate; | ||
929 | u16 wflags = 0; | ||
962 | 930 | ||
963 | cflag = tty->termios.c_cflag; | 931 | cflag = tty->termios.c_cflag; |
964 | iflag = tty->termios.c_iflag; | 932 | iflag = tty->termios.c_iflag; |
@@ -967,21 +935,16 @@ static void ti_set_termios(struct tty_struct *tty, | |||
967 | dev_dbg(&port->dev, "%s - old clfag %08x, old iflag %08x\n", __func__, | 935 | dev_dbg(&port->dev, "%s - old clfag %08x, old iflag %08x\n", __func__, |
968 | old_termios->c_cflag, old_termios->c_iflag); | 936 | old_termios->c_cflag, old_termios->c_iflag); |
969 | 937 | ||
970 | if (tport == NULL) | ||
971 | return; | ||
972 | |||
973 | config = kmalloc(sizeof(*config), GFP_KERNEL); | 938 | config = kmalloc(sizeof(*config), GFP_KERNEL); |
974 | if (!config) | 939 | if (!config) |
975 | return; | 940 | return; |
976 | 941 | ||
977 | config->wFlags = 0; | ||
978 | |||
979 | /* these flags must be set */ | 942 | /* these flags must be set */ |
980 | config->wFlags |= TI_UART_ENABLE_MS_INTS; | 943 | wflags |= TI_UART_ENABLE_MS_INTS; |
981 | config->wFlags |= TI_UART_ENABLE_AUTO_START_DMA; | 944 | wflags |= TI_UART_ENABLE_AUTO_START_DMA; |
982 | config->bUartMode = (__u8)(tport->tp_uart_mode); | 945 | config->bUartMode = tport->tp_uart_mode; |
983 | 946 | ||
984 | switch (cflag & CSIZE) { | 947 | switch (C_CSIZE(tty)) { |
985 | case CS5: | 948 | case CS5: |
986 | config->bDataBits = TI_UART_5_DATA_BITS; | 949 | config->bDataBits = TI_UART_5_DATA_BITS; |
987 | break; | 950 | break; |
@@ -1000,29 +963,29 @@ static void ti_set_termios(struct tty_struct *tty, | |||
1000 | /* CMSPAR isn't supported by this driver */ | 963 | /* CMSPAR isn't supported by this driver */ |
1001 | tty->termios.c_cflag &= ~CMSPAR; | 964 | tty->termios.c_cflag &= ~CMSPAR; |
1002 | 965 | ||
1003 | if (cflag & PARENB) { | 966 | if (C_PARENB(tty)) { |
1004 | if (cflag & PARODD) { | 967 | if (C_PARODD(tty)) { |
1005 | config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; | 968 | wflags |= TI_UART_ENABLE_PARITY_CHECKING; |
1006 | config->bParity = TI_UART_ODD_PARITY; | 969 | config->bParity = TI_UART_ODD_PARITY; |
1007 | } else { | 970 | } else { |
1008 | config->wFlags |= TI_UART_ENABLE_PARITY_CHECKING; | 971 | wflags |= TI_UART_ENABLE_PARITY_CHECKING; |
1009 | config->bParity = TI_UART_EVEN_PARITY; | 972 | config->bParity = TI_UART_EVEN_PARITY; |
1010 | } | 973 | } |
1011 | } else { | 974 | } else { |
1012 | config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING; | 975 | wflags &= ~TI_UART_ENABLE_PARITY_CHECKING; |
1013 | config->bParity = TI_UART_NO_PARITY; | 976 | config->bParity = TI_UART_NO_PARITY; |
1014 | } | 977 | } |
1015 | 978 | ||
1016 | if (cflag & CSTOPB) | 979 | if (C_CSTOPB(tty)) |
1017 | config->bStopBits = TI_UART_2_STOP_BITS; | 980 | config->bStopBits = TI_UART_2_STOP_BITS; |
1018 | else | 981 | else |
1019 | config->bStopBits = TI_UART_1_STOP_BITS; | 982 | config->bStopBits = TI_UART_1_STOP_BITS; |
1020 | 983 | ||
1021 | if (cflag & CRTSCTS) { | 984 | if (C_CRTSCTS(tty)) { |
1022 | /* RTS flow control must be off to drop RTS for baud rate B0 */ | 985 | /* RTS flow control must be off to drop RTS for baud rate B0 */ |
1023 | if ((cflag & CBAUD) != B0) | 986 | if ((C_BAUD(tty)) != B0) |
1024 | config->wFlags |= TI_UART_ENABLE_RTS_IN; | 987 | wflags |= TI_UART_ENABLE_RTS_IN; |
1025 | config->wFlags |= TI_UART_ENABLE_CTS_OUT; | 988 | wflags |= TI_UART_ENABLE_CTS_OUT; |
1026 | } else { | 989 | } else { |
1027 | ti_restart_read(tport, tty); | 990 | ti_restart_read(tport, tty); |
1028 | } | 991 | } |
@@ -1032,34 +995,34 @@ static void ti_set_termios(struct tty_struct *tty, | |||
1032 | config->cXoff = STOP_CHAR(tty); | 995 | config->cXoff = STOP_CHAR(tty); |
1033 | 996 | ||
1034 | if (I_IXOFF(tty)) | 997 | if (I_IXOFF(tty)) |
1035 | config->wFlags |= TI_UART_ENABLE_X_IN; | 998 | wflags |= TI_UART_ENABLE_X_IN; |
1036 | else | 999 | else |
1037 | ti_restart_read(tport, tty); | 1000 | ti_restart_read(tport, tty); |
1038 | 1001 | ||
1039 | if (I_IXON(tty)) | 1002 | if (I_IXON(tty)) |
1040 | config->wFlags |= TI_UART_ENABLE_X_OUT; | 1003 | wflags |= TI_UART_ENABLE_X_OUT; |
1041 | } | 1004 | } |
1042 | 1005 | ||
1043 | baud = tty_get_baud_rate(tty); | 1006 | baud = tty_get_baud_rate(tty); |
1044 | if (!baud) | 1007 | if (!baud) |
1045 | baud = 9600; | 1008 | baud = 9600; |
1046 | if (tport->tp_tdev->td_is_3410) | 1009 | if (tport->tp_tdev->td_is_3410) |
1047 | config->wBaudRate = (__u16)((923077 + baud/2) / baud); | 1010 | wbaudrate = (923077 + baud/2) / baud; |
1048 | else | 1011 | else |
1049 | config->wBaudRate = (__u16)((461538 + baud/2) / baud); | 1012 | wbaudrate = (461538 + baud/2) / baud; |
1050 | 1013 | ||
1051 | /* FIXME: Should calculate resulting baud here and report it back */ | 1014 | /* FIXME: Should calculate resulting baud here and report it back */ |
1052 | if ((cflag & CBAUD) != B0) | 1015 | if ((C_BAUD(tty)) != B0) |
1053 | tty_encode_baud_rate(tty, baud, baud); | 1016 | tty_encode_baud_rate(tty, baud, baud); |
1054 | 1017 | ||
1055 | dev_dbg(&port->dev, | 1018 | dev_dbg(&port->dev, |
1056 | "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d\n", | 1019 | "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d\n", |
1057 | __func__, baud, config->wBaudRate, config->wFlags, | 1020 | __func__, baud, wbaudrate, wflags, |
1058 | config->bDataBits, config->bParity, config->bStopBits, | 1021 | config->bDataBits, config->bParity, config->bStopBits, |
1059 | config->cXon, config->cXoff, config->bUartMode); | 1022 | config->cXon, config->cXoff, config->bUartMode); |
1060 | 1023 | ||
1061 | cpu_to_be16s(&config->wBaudRate); | 1024 | config->wBaudRate = cpu_to_be16(wbaudrate); |
1062 | cpu_to_be16s(&config->wFlags); | 1025 | config->wFlags = cpu_to_be16(wflags); |
1063 | 1026 | ||
1064 | status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG, | 1027 | status = ti_command_out_sync(tport->tp_tdev, TI_SET_CONFIG, |
1065 | (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config, | 1028 | (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config, |
@@ -1071,7 +1034,7 @@ static void ti_set_termios(struct tty_struct *tty, | |||
1071 | /* SET_CONFIG asserts RTS and DTR, reset them correctly */ | 1034 | /* SET_CONFIG asserts RTS and DTR, reset them correctly */ |
1072 | mcr = tport->tp_shadow_mcr; | 1035 | mcr = tport->tp_shadow_mcr; |
1073 | /* if baud rate is B0, clear RTS and DTR */ | 1036 | /* if baud rate is B0, clear RTS and DTR */ |
1074 | if ((cflag & CBAUD) == B0) | 1037 | if (C_BAUD(tty) == B0) |
1075 | mcr &= ~(TI_MCR_DTR | TI_MCR_RTS); | 1038 | mcr &= ~(TI_MCR_DTR | TI_MCR_RTS); |
1076 | status = ti_set_mcr(tport, mcr); | 1039 | status = ti_set_mcr(tport, mcr); |
1077 | if (status) | 1040 | if (status) |
@@ -1092,9 +1055,6 @@ static int ti_tiocmget(struct tty_struct *tty) | |||
1092 | unsigned int mcr; | 1055 | unsigned int mcr; |
1093 | unsigned long flags; | 1056 | unsigned long flags; |
1094 | 1057 | ||
1095 | if (tport == NULL) | ||
1096 | return -ENODEV; | ||
1097 | |||
1098 | spin_lock_irqsave(&tport->tp_lock, flags); | 1058 | spin_lock_irqsave(&tport->tp_lock, flags); |
1099 | msr = tport->tp_msr; | 1059 | msr = tport->tp_msr; |
1100 | mcr = tport->tp_shadow_mcr; | 1060 | mcr = tport->tp_shadow_mcr; |
@@ -1122,9 +1082,6 @@ static int ti_tiocmset(struct tty_struct *tty, | |||
1122 | unsigned int mcr; | 1082 | unsigned int mcr; |
1123 | unsigned long flags; | 1083 | unsigned long flags; |
1124 | 1084 | ||
1125 | if (tport == NULL) | ||
1126 | return -ENODEV; | ||
1127 | |||
1128 | spin_lock_irqsave(&tport->tp_lock, flags); | 1085 | spin_lock_irqsave(&tport->tp_lock, flags); |
1129 | mcr = tport->tp_shadow_mcr; | 1086 | mcr = tport->tp_shadow_mcr; |
1130 | 1087 | ||
@@ -1155,9 +1112,6 @@ static void ti_break(struct tty_struct *tty, int break_state) | |||
1155 | 1112 | ||
1156 | dev_dbg(&port->dev, "%s - state = %d\n", __func__, break_state); | 1113 | dev_dbg(&port->dev, "%s - state = %d\n", __func__, break_state); |
1157 | 1114 | ||
1158 | if (tport == NULL) | ||
1159 | return; | ||
1160 | |||
1161 | status = ti_write_byte(port, tport->tp_tdev, | 1115 | status = ti_write_byte(port, tport->tp_tdev, |
1162 | tport->tp_uart_base_addr + TI_UART_OFFSET_LCR, | 1116 | tport->tp_uart_base_addr + TI_UART_OFFSET_LCR, |
1163 | TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0); | 1117 | TI_LCR_BREAK, break_state == -1 ? TI_LCR_BREAK : 0); |
@@ -1189,7 +1143,7 @@ static void ti_interrupt_callback(struct urb *urb) | |||
1189 | int function; | 1143 | int function; |
1190 | int status = urb->status; | 1144 | int status = urb->status; |
1191 | int retval; | 1145 | int retval; |
1192 | __u8 msr; | 1146 | u8 msr; |
1193 | 1147 | ||
1194 | switch (status) { | 1148 | switch (status) { |
1195 | case 0: | 1149 | case 0: |
@@ -1198,11 +1152,9 @@ static void ti_interrupt_callback(struct urb *urb) | |||
1198 | case -ENOENT: | 1152 | case -ENOENT: |
1199 | case -ESHUTDOWN: | 1153 | case -ESHUTDOWN: |
1200 | dev_dbg(dev, "%s - urb shutting down, %d\n", __func__, status); | 1154 | dev_dbg(dev, "%s - urb shutting down, %d\n", __func__, status); |
1201 | tdev->td_urb_error = 1; | ||
1202 | return; | 1155 | return; |
1203 | default: | 1156 | default: |
1204 | dev_err(dev, "%s - nonzero urb status, %d\n", __func__, status); | 1157 | dev_err(dev, "%s - nonzero urb status, %d\n", __func__, status); |
1205 | tdev->td_urb_error = 1; | ||
1206 | goto exit; | 1158 | goto exit; |
1207 | } | 1159 | } |
1208 | 1160 | ||
@@ -1275,12 +1227,10 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1275 | case -ENOENT: | 1227 | case -ENOENT: |
1276 | case -ESHUTDOWN: | 1228 | case -ESHUTDOWN: |
1277 | dev_dbg(dev, "%s - urb shutting down, %d\n", __func__, status); | 1229 | dev_dbg(dev, "%s - urb shutting down, %d\n", __func__, status); |
1278 | tport->tp_tdev->td_urb_error = 1; | ||
1279 | return; | 1230 | return; |
1280 | default: | 1231 | default: |
1281 | dev_err(dev, "%s - nonzero urb status, %d\n", | 1232 | dev_err(dev, "%s - nonzero urb status, %d\n", |
1282 | __func__, status); | 1233 | __func__, status); |
1283 | tport->tp_tdev->td_urb_error = 1; | ||
1284 | } | 1234 | } |
1285 | 1235 | ||
1286 | if (status == -EPIPE) | 1236 | if (status == -EPIPE) |
@@ -1335,12 +1285,10 @@ static void ti_bulk_out_callback(struct urb *urb) | |||
1335 | case -ENOENT: | 1285 | case -ENOENT: |
1336 | case -ESHUTDOWN: | 1286 | case -ESHUTDOWN: |
1337 | dev_dbg(&port->dev, "%s - urb shutting down, %d\n", __func__, status); | 1287 | dev_dbg(&port->dev, "%s - urb shutting down, %d\n", __func__, status); |
1338 | tport->tp_tdev->td_urb_error = 1; | ||
1339 | return; | 1288 | return; |
1340 | default: | 1289 | default: |
1341 | dev_err_console(port, "%s - nonzero urb status, %d\n", | 1290 | dev_err_console(port, "%s - nonzero urb status, %d\n", |
1342 | __func__, status); | 1291 | __func__, status); |
1343 | tport->tp_tdev->td_urb_error = 1; | ||
1344 | } | 1292 | } |
1345 | 1293 | ||
1346 | /* send any buffered data */ | 1294 | /* send any buffered data */ |
@@ -1490,7 +1438,6 @@ static int ti_get_serial_info(struct ti_port *tport, | |||
1490 | ret_serial.type = PORT_16550A; | 1438 | ret_serial.type = PORT_16550A; |
1491 | ret_serial.line = port->minor; | 1439 | ret_serial.line = port->minor; |
1492 | ret_serial.port = port->port_number; | 1440 | ret_serial.port = port->port_number; |
1493 | ret_serial.flags = tport->tp_flags; | ||
1494 | ret_serial.xmit_fifo_size = kfifo_size(&port->write_fifo); | 1441 | ret_serial.xmit_fifo_size = kfifo_size(&port->write_fifo); |
1495 | ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; | 1442 | ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; |
1496 | ret_serial.closing_wait = cwait; | 1443 | ret_serial.closing_wait = cwait; |
@@ -1515,14 +1462,13 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, | |||
1515 | if (cwait != ASYNC_CLOSING_WAIT_NONE) | 1462 | if (cwait != ASYNC_CLOSING_WAIT_NONE) |
1516 | cwait = msecs_to_jiffies(10 * new_serial.closing_wait); | 1463 | cwait = msecs_to_jiffies(10 * new_serial.closing_wait); |
1517 | 1464 | ||
1518 | tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; | ||
1519 | tport->tp_port->port.closing_wait = cwait; | 1465 | tport->tp_port->port.closing_wait = cwait; |
1520 | 1466 | ||
1521 | return 0; | 1467 | return 0; |
1522 | } | 1468 | } |
1523 | 1469 | ||
1524 | 1470 | ||
1525 | static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) | 1471 | static void ti_handle_new_msr(struct ti_port *tport, u8 msr) |
1526 | { | 1472 | { |
1527 | struct async_icount *icount; | 1473 | struct async_icount *icount; |
1528 | struct tty_struct *tty; | 1474 | struct tty_struct *tty; |
@@ -1634,8 +1580,8 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command, | |||
1634 | 1580 | ||
1635 | 1581 | ||
1636 | static int ti_write_byte(struct usb_serial_port *port, | 1582 | static int ti_write_byte(struct usb_serial_port *port, |
1637 | struct ti_device *tdev, unsigned long addr, | 1583 | struct ti_device *tdev, unsigned long addr, |
1638 | __u8 mask, __u8 byte) | 1584 | u8 mask, u8 byte) |
1639 | { | 1585 | { |
1640 | int status; | 1586 | int status; |
1641 | unsigned int size; | 1587 | unsigned int size; |
@@ -1679,11 +1625,10 @@ static int ti_do_download(struct usb_device *dev, int pipe, | |||
1679 | int len; | 1625 | int len; |
1680 | 1626 | ||
1681 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) | 1627 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) |
1682 | cs = (__u8)(cs + buffer[pos]); | 1628 | cs = (u8)(cs + buffer[pos]); |
1683 | 1629 | ||
1684 | header = (struct ti_firmware_header *)buffer; | 1630 | header = (struct ti_firmware_header *)buffer; |
1685 | header->wLength = cpu_to_le16((__u16)(size | 1631 | header->wLength = cpu_to_le16(size - sizeof(*header)); |
1686 | - sizeof(struct ti_firmware_header))); | ||
1687 | header->bCheckSum = cs; | 1632 | header->bCheckSum = cs; |
1688 | 1633 | ||
1689 | dev_dbg(&dev->dev, "%s - downloading firmware\n", __func__); | 1634 | dev_dbg(&dev->dev, "%s - downloading firmware\n", __func__); |
@@ -1701,7 +1646,7 @@ static int ti_download_firmware(struct ti_device *tdev) | |||
1701 | { | 1646 | { |
1702 | int status; | 1647 | int status; |
1703 | int buffer_size; | 1648 | int buffer_size; |
1704 | __u8 *buffer; | 1649 | u8 *buffer; |
1705 | struct usb_device *dev = tdev->td_serial->dev; | 1650 | struct usb_device *dev = tdev->td_serial->dev; |
1706 | unsigned int pipe = usb_sndbulkpipe(dev, | 1651 | unsigned int pipe = usb_sndbulkpipe(dev, |
1707 | tdev->td_serial->port[0]->bulk_out_endpointAddress); | 1652 | tdev->td_serial->port[0]->bulk_out_endpointAddress); |
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 1d8b03c81030..878b4b8761f5 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
@@ -939,10 +939,8 @@ static int alauda_read_data(struct us_data *us, unsigned long address, | |||
939 | 939 | ||
940 | len = min(sectors, blocksize) * (pagesize + 64); | 940 | len = min(sectors, blocksize) * (pagesize + 64); |
941 | buffer = kmalloc(len, GFP_NOIO); | 941 | buffer = kmalloc(len, GFP_NOIO); |
942 | if (buffer == NULL) { | 942 | if (!buffer) |
943 | printk(KERN_WARNING "alauda_read_data: Out of memory\n"); | ||
944 | return USB_STOR_TRANSPORT_ERROR; | 943 | return USB_STOR_TRANSPORT_ERROR; |
945 | } | ||
946 | 944 | ||
947 | /* Figure out the initial LBA and page */ | 945 | /* Figure out the initial LBA and page */ |
948 | lba = address >> blockshift; | 946 | lba = address >> blockshift; |
@@ -1033,18 +1031,15 @@ static int alauda_write_data(struct us_data *us, unsigned long address, | |||
1033 | 1031 | ||
1034 | len = min(sectors, blocksize) * pagesize; | 1032 | len = min(sectors, blocksize) * pagesize; |
1035 | buffer = kmalloc(len, GFP_NOIO); | 1033 | buffer = kmalloc(len, GFP_NOIO); |
1036 | if (buffer == NULL) { | 1034 | if (!buffer) |
1037 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); | ||
1038 | return USB_STOR_TRANSPORT_ERROR; | 1035 | return USB_STOR_TRANSPORT_ERROR; |
1039 | } | ||
1040 | 1036 | ||
1041 | /* | 1037 | /* |
1042 | * We also need a temporary block buffer, where we read in the old data, | 1038 | * We also need a temporary block buffer, where we read in the old data, |
1043 | * overwrite parts with the new data, and manipulate the redundancy data | 1039 | * overwrite parts with the new data, and manipulate the redundancy data |
1044 | */ | 1040 | */ |
1045 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | 1041 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); |
1046 | if (blockbuffer == NULL) { | 1042 | if (!blockbuffer) { |
1047 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); | ||
1048 | kfree(buffer); | 1043 | kfree(buffer); |
1049 | return USB_STOR_TRANSPORT_ERROR; | 1044 | return USB_STOR_TRANSPORT_ERROR; |
1050 | } | 1045 | } |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 33eb923df892..8cd2926fb1fe 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -296,6 +296,14 @@ static int slave_configure(struct scsi_device *sdev) | |||
296 | if (us->fflags & US_FL_BROKEN_FUA) | 296 | if (us->fflags & US_FL_BROKEN_FUA) |
297 | sdev->broken_fua = 1; | 297 | sdev->broken_fua = 1; |
298 | 298 | ||
299 | /* Some even totally fail to indicate a cache */ | ||
300 | if (us->fflags & US_FL_ALWAYS_SYNC) { | ||
301 | /* don't read caching information */ | ||
302 | sdev->skip_ms_page_8 = 1; | ||
303 | sdev->skip_ms_page_3f = 1; | ||
304 | /* assume sync is needed */ | ||
305 | sdev->wce_default_on = 1; | ||
306 | } | ||
299 | } else { | 307 | } else { |
300 | 308 | ||
301 | /* | 309 | /* |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index c5797fa2125e..3aeaa536c44f 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -766,10 +766,8 @@ sddr09_read_data(struct us_data *us, | |||
766 | 766 | ||
767 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 767 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
768 | buffer = kmalloc(len, GFP_NOIO); | 768 | buffer = kmalloc(len, GFP_NOIO); |
769 | if (buffer == NULL) { | 769 | if (!buffer) |
770 | printk(KERN_WARNING "sddr09_read_data: Out of memory\n"); | ||
771 | return -ENOMEM; | 770 | return -ENOMEM; |
772 | } | ||
773 | 771 | ||
774 | // This could be made much more efficient by checking for | 772 | // This could be made much more efficient by checking for |
775 | // contiguous LBA's. Another exercise left to the student. | 773 | // contiguous LBA's. Another exercise left to the student. |
@@ -1004,10 +1002,8 @@ sddr09_write_data(struct us_data *us, | |||
1004 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); | 1002 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); |
1005 | blocklen = (pagelen << info->blockshift); | 1003 | blocklen = (pagelen << info->blockshift); |
1006 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 1004 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
1007 | if (!blockbuffer) { | 1005 | if (!blockbuffer) |
1008 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); | ||
1009 | return -ENOMEM; | 1006 | return -ENOMEM; |
1010 | } | ||
1011 | 1007 | ||
1012 | /* | 1008 | /* |
1013 | * Since we don't write the user data directly to the device, | 1009 | * Since we don't write the user data directly to the device, |
@@ -1017,8 +1013,7 @@ sddr09_write_data(struct us_data *us, | |||
1017 | 1013 | ||
1018 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 1014 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
1019 | buffer = kmalloc(len, GFP_NOIO); | 1015 | buffer = kmalloc(len, GFP_NOIO); |
1020 | if (buffer == NULL) { | 1016 | if (!buffer) { |
1021 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); | ||
1022 | kfree(blockbuffer); | 1017 | kfree(blockbuffer); |
1023 | return -ENOMEM; | 1018 | return -ENOMEM; |
1024 | } | 1019 | } |
@@ -1241,8 +1236,7 @@ sddr09_read_map(struct us_data *us) { | |||
1241 | alloc_blocks = min(numblocks, SDDR09_READ_MAP_BUFSZ >> CONTROL_SHIFT); | 1236 | alloc_blocks = min(numblocks, SDDR09_READ_MAP_BUFSZ >> CONTROL_SHIFT); |
1242 | alloc_len = (alloc_blocks << CONTROL_SHIFT); | 1237 | alloc_len = (alloc_blocks << CONTROL_SHIFT); |
1243 | buffer = kmalloc(alloc_len, GFP_NOIO); | 1238 | buffer = kmalloc(alloc_len, GFP_NOIO); |
1244 | if (buffer == NULL) { | 1239 | if (!buffer) { |
1245 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); | ||
1246 | result = -1; | 1240 | result = -1; |
1247 | goto done; | 1241 | goto done; |
1248 | } | 1242 | } |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index aa3539238848..af3c7eecff91 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -338,6 +338,13 @@ UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100, | |||
338 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 338 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
339 | US_FL_NO_WP_DETECT), | 339 | US_FL_NO_WP_DETECT), |
340 | 340 | ||
341 | /* Reported by Egbert Eich <eich@suse.com> */ | ||
342 | UNUSUAL_DEV( 0x0480, 0xd010, 0x0100, 0x9999, | ||
343 | "Toshiba", | ||
344 | "External USB 3.0", | ||
345 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
346 | US_FL_ALWAYS_SYNC), | ||
347 | |||
341 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ | 348 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ |
342 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, | 349 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, |
343 | "Kyocera", | 350 | "Kyocera", |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index ef2d8cde6ef7..2cba13a532cd 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -498,7 +498,8 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) | |||
498 | US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | | 498 | US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | |
499 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | | 499 | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | |
500 | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | | 500 | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | |
501 | US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS); | 501 | US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS | |
502 | US_FL_ALWAYS_SYNC); | ||
502 | 503 | ||
503 | p = quirks; | 504 | p = quirks; |
504 | while (*p) { | 505 | while (*p) { |
@@ -581,6 +582,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) | |||
581 | case 'w': | 582 | case 'w': |
582 | f |= US_FL_NO_WP_DETECT; | 583 | f |= US_FL_NO_WP_DETECT; |
583 | break; | 584 | break; |
585 | case 'y': | ||
586 | f |= US_FL_ALWAYS_SYNC; | ||
587 | break; | ||
584 | /* Ignore unrecognized flag characters */ | 588 | /* Ignore unrecognized flag characters */ |
585 | } | 589 | } |
586 | } | 590 | } |
@@ -794,10 +798,8 @@ static int usb_stor_acquire_resources(struct us_data *us) | |||
794 | struct task_struct *th; | 798 | struct task_struct *th; |
795 | 799 | ||
796 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); | 800 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); |
797 | if (!us->current_urb) { | 801 | if (!us->current_urb) |
798 | usb_stor_dbg(us, "URB allocation failed\n"); | ||
799 | return -ENOMEM; | 802 | return -ENOMEM; |
800 | } | ||
801 | 803 | ||
802 | /* | 804 | /* |
803 | * Just before we start our control thread, initialize | 805 | * Just before we start our control thread, initialize |
@@ -1070,17 +1072,17 @@ int usb_stor_probe2(struct us_data *us) | |||
1070 | result = usb_stor_acquire_resources(us); | 1072 | result = usb_stor_acquire_resources(us); |
1071 | if (result) | 1073 | if (result) |
1072 | goto BadDevice; | 1074 | goto BadDevice; |
1075 | usb_autopm_get_interface_no_resume(us->pusb_intf); | ||
1073 | snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s", | 1076 | snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s", |
1074 | dev_name(&us->pusb_intf->dev)); | 1077 | dev_name(&us->pusb_intf->dev)); |
1075 | result = scsi_add_host(us_to_host(us), dev); | 1078 | result = scsi_add_host(us_to_host(us), dev); |
1076 | if (result) { | 1079 | if (result) { |
1077 | dev_warn(dev, | 1080 | dev_warn(dev, |
1078 | "Unable to add the scsi host\n"); | 1081 | "Unable to add the scsi host\n"); |
1079 | goto BadDevice; | 1082 | goto HostAddErr; |
1080 | } | 1083 | } |
1081 | 1084 | ||
1082 | /* Submit the delayed_work for SCSI-device scanning */ | 1085 | /* Submit the delayed_work for SCSI-device scanning */ |
1083 | usb_autopm_get_interface_no_resume(us->pusb_intf); | ||
1084 | set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); | 1086 | set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); |
1085 | 1087 | ||
1086 | if (delay_use > 0) | 1088 | if (delay_use > 0) |
@@ -1090,6 +1092,8 @@ int usb_stor_probe2(struct us_data *us) | |||
1090 | return 0; | 1092 | return 0; |
1091 | 1093 | ||
1092 | /* We come here if there are any problems */ | 1094 | /* We come here if there are any problems */ |
1095 | HostAddErr: | ||
1096 | usb_autopm_put_interface_no_suspend(us->pusb_intf); | ||
1093 | BadDevice: | 1097 | BadDevice: |
1094 | usb_stor_dbg(us, "storage_probe() failed\n"); | 1098 | usb_stor_dbg(us, "storage_probe() failed\n"); |
1095 | release_everything(us); | 1099 | release_everything(us); |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 545d09b8081d..5133a0792eb0 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -499,10 +499,8 @@ static int skel_probe(struct usb_interface *interface, | |||
499 | 499 | ||
500 | /* allocate memory for our device state and initialize it */ | 500 | /* allocate memory for our device state and initialize it */ |
501 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 501 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
502 | if (!dev) { | 502 | if (!dev) |
503 | dev_err(&interface->dev, "Out of memory\n"); | ||
504 | goto error; | 503 | goto error; |
505 | } | ||
506 | kref_init(&dev->kref); | 504 | kref_init(&dev->kref); |
507 | sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); | 505 | sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); |
508 | mutex_init(&dev->io_mutex); | 506 | mutex_init(&dev->io_mutex); |
@@ -526,17 +524,11 @@ static int skel_probe(struct usb_interface *interface, | |||
526 | dev->bulk_in_size = buffer_size; | 524 | dev->bulk_in_size = buffer_size; |
527 | dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; | 525 | dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; |
528 | dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | 526 | dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); |
529 | if (!dev->bulk_in_buffer) { | 527 | if (!dev->bulk_in_buffer) |
530 | dev_err(&interface->dev, | ||
531 | "Could not allocate bulk_in_buffer\n"); | ||
532 | goto error; | 528 | goto error; |
533 | } | ||
534 | dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 529 | dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
535 | if (!dev->bulk_in_urb) { | 530 | if (!dev->bulk_in_urb) |
536 | dev_err(&interface->dev, | ||
537 | "Could not allocate bulk_in_urb\n"); | ||
538 | goto error; | 531 | goto error; |
539 | } | ||
540 | } | 532 | } |
541 | 533 | ||
542 | if (!dev->bulk_out_endpointAddr && | 534 | if (!dev->bulk_out_endpointAddr && |
diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 17646b25343f..eeefa29f8aa2 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config USBIP_CORE | 1 | config USBIP_CORE |
2 | tristate "USB/IP support" | 2 | tristate "USB/IP support" |
3 | depends on USB_COMMON && NET | 3 | depends on NET |
4 | select USB_COMMON | ||
4 | ---help--- | 5 | ---help--- |
5 | This enables pushing USB packets over IP to allow remote | 6 | This enables pushing USB packets over IP to allow remote |
6 | machines direct access to USB devices. It provides the | 7 | machines direct access to USB devices. It provides the |
@@ -24,6 +25,27 @@ config USBIP_VHCI_HCD | |||
24 | To compile this driver as a module, choose M here: the | 25 | To compile this driver as a module, choose M here: the |
25 | module will be called vhci-hcd. | 26 | module will be called vhci-hcd. |
26 | 27 | ||
28 | config USBIP_VHCI_HC_PORTS | ||
29 | int "Number of ports per USB/IP virtual host controller" | ||
30 | range 1 31 | ||
31 | default 8 | ||
32 | depends on USBIP_VHCI_HCD | ||
33 | ---help--- | ||
34 | To increase number of ports available for USB/IP virtual | ||
35 | host controller driver, this defines number of ports per | ||
36 | USB/IP virtual host controller. | ||
37 | |||
38 | config USBIP_VHCI_NR_HCS | ||
39 | int "Number of USB/IP virtual host controllers" | ||
40 | range 1 128 | ||
41 | default 1 | ||
42 | depends on USBIP_VHCI_HCD | ||
43 | ---help--- | ||
44 | To increase number of ports available for USB/IP virtual | ||
45 | host controller driver, this defines number of USB/IP | ||
46 | virtual host controllers as if adding physical host | ||
47 | controllers. | ||
48 | |||
27 | config USBIP_HOST | 49 | config USBIP_HOST |
28 | tristate "Host driver" | 50 | tristate "Host driver" |
29 | depends on USBIP_CORE && USB | 51 | depends on USBIP_CORE && USB |
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 2df63e305722..191b176ffedf 100644 --- a/drivers/usb/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c | |||
@@ -461,7 +461,6 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, | |||
461 | priv->urb = usb_alloc_urb(0, GFP_KERNEL); | 461 | priv->urb = usb_alloc_urb(0, GFP_KERNEL); |
462 | 462 | ||
463 | if (!priv->urb) { | 463 | if (!priv->urb) { |
464 | dev_err(&udev->dev, "malloc urb\n"); | ||
465 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | 464 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); |
466 | return; | 465 | return; |
467 | } | 466 | } |
diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index a863a98a91ce..88b71c4e068f 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi |
3 | * Copyright (C) 2015 Nobuo Iwata | ||
3 | * | 4 | * |
4 | * This is free software; you can redistribute it and/or modify | 5 | * This is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -72,13 +73,25 @@ struct vhci_unlink { | |||
72 | }; | 73 | }; |
73 | 74 | ||
74 | /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ | 75 | /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ |
75 | #define VHCI_NPORTS 8 | 76 | #ifdef CONFIG_USBIP_VHCI_HC_PORTS |
77 | #define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS | ||
78 | #else | ||
79 | #define VHCI_HC_PORTS 8 | ||
80 | #endif | ||
81 | |||
82 | #ifdef CONFIG_USBIP_VHCI_NR_HCS | ||
83 | #define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS | ||
84 | #else | ||
85 | #define VHCI_NR_HCS 1 | ||
86 | #endif | ||
87 | |||
88 | #define MAX_STATUS_NAME 16 | ||
76 | 89 | ||
77 | /* for usb_bus.hcpriv */ | 90 | /* for usb_bus.hcpriv */ |
78 | struct vhci_hcd { | 91 | struct vhci_hcd { |
79 | spinlock_t lock; | 92 | spinlock_t lock; |
80 | 93 | ||
81 | u32 port_status[VHCI_NPORTS]; | 94 | u32 port_status[VHCI_HC_PORTS]; |
82 | 95 | ||
83 | unsigned resuming:1; | 96 | unsigned resuming:1; |
84 | unsigned long re_timeout; | 97 | unsigned long re_timeout; |
@@ -90,14 +103,19 @@ struct vhci_hcd { | |||
90 | * wIndex shows the port number and begins from 1. | 103 | * wIndex shows the port number and begins from 1. |
91 | * But, the index of this array begins from 0. | 104 | * But, the index of this array begins from 0. |
92 | */ | 105 | */ |
93 | struct vhci_device vdev[VHCI_NPORTS]; | 106 | struct vhci_device vdev[VHCI_HC_PORTS]; |
94 | }; | 107 | }; |
95 | 108 | ||
96 | extern struct vhci_hcd *the_controller; | 109 | extern int vhci_num_controllers; |
97 | extern const struct attribute_group dev_attr_group; | 110 | extern struct platform_device **vhci_pdevs; |
111 | extern struct attribute_group vhci_attr_group; | ||
98 | 112 | ||
99 | /* vhci_hcd.c */ | 113 | /* vhci_hcd.c */ |
100 | void rh_port_connect(int rhport, enum usb_device_speed speed); | 114 | void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed); |
115 | |||
116 | /* vhci_sysfs.c */ | ||
117 | int vhci_init_attr_group(void); | ||
118 | void vhci_finish_attr_group(void); | ||
101 | 119 | ||
102 | /* vhci_rx.c */ | 120 | /* vhci_rx.c */ |
103 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); | 121 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); |
@@ -106,9 +124,14 @@ int vhci_rx_loop(void *data); | |||
106 | /* vhci_tx.c */ | 124 | /* vhci_tx.c */ |
107 | int vhci_tx_loop(void *data); | 125 | int vhci_tx_loop(void *data); |
108 | 126 | ||
109 | static inline struct vhci_device *port_to_vdev(__u32 port) | 127 | static inline __u32 port_to_rhport(__u32 port) |
128 | { | ||
129 | return port % VHCI_HC_PORTS; | ||
130 | } | ||
131 | |||
132 | static inline int port_to_pdev_nr(__u32 port) | ||
110 | { | 133 | { |
111 | return &the_controller->vdev[port]; | 134 | return port / VHCI_HC_PORTS; |
112 | } | 135 | } |
113 | 136 | ||
114 | static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) | 137 | static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) |
@@ -116,14 +139,25 @@ static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) | |||
116 | return (struct vhci_hcd *) (hcd->hcd_priv); | 139 | return (struct vhci_hcd *) (hcd->hcd_priv); |
117 | } | 140 | } |
118 | 141 | ||
142 | static inline struct device *hcd_dev(struct usb_hcd *hcd) | ||
143 | { | ||
144 | return (hcd)->self.controller; | ||
145 | } | ||
146 | |||
147 | static inline const char *hcd_name(struct usb_hcd *hcd) | ||
148 | { | ||
149 | return (hcd)->self.bus_name; | ||
150 | } | ||
151 | |||
119 | static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) | 152 | static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) |
120 | { | 153 | { |
121 | return container_of((void *) vhci, struct usb_hcd, hcd_priv); | 154 | return container_of((void *) vhci, struct usb_hcd, hcd_priv); |
122 | } | 155 | } |
123 | 156 | ||
124 | static inline struct device *vhci_dev(struct vhci_hcd *vhci) | 157 | static inline struct vhci_hcd *vdev_to_vhci(struct vhci_device *vdev) |
125 | { | 158 | { |
126 | return vhci_to_hcd(vhci)->self.controller; | 159 | return container_of( |
160 | (void *)(vdev - vdev->rhport), struct vhci_hcd, vdev); | ||
127 | } | 161 | } |
128 | 162 | ||
129 | #endif /* __USBIP_VHCI_H */ | 163 | #endif /* __USBIP_VHCI_H */ |
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 2e0450bec1b1..03eccf29ace0 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi |
3 | * Copyright (C) 2015-2016 Nobuo Iwata | ||
3 | * | 4 | * |
4 | * This is free software; you can redistribute it and/or modify | 5 | * This is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -56,7 +57,9 @@ static int vhci_get_frame_number(struct usb_hcd *hcd); | |||
56 | static const char driver_name[] = "vhci_hcd"; | 57 | static const char driver_name[] = "vhci_hcd"; |
57 | static const char driver_desc[] = "USB/IP Virtual Host Controller"; | 58 | static const char driver_desc[] = "USB/IP Virtual Host Controller"; |
58 | 59 | ||
59 | struct vhci_hcd *the_controller; | 60 | int vhci_num_controllers = VHCI_NR_HCS; |
61 | |||
62 | struct platform_device **vhci_pdevs; | ||
60 | 63 | ||
61 | static const char * const bit_desc[] = { | 64 | static const char * const bit_desc[] = { |
62 | "CONNECTION", /*0*/ | 65 | "CONNECTION", /*0*/ |
@@ -119,47 +122,59 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status) | |||
119 | pr_debug("\n"); | 122 | pr_debug("\n"); |
120 | } | 123 | } |
121 | 124 | ||
122 | void rh_port_connect(int rhport, enum usb_device_speed speed) | 125 | void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed) |
123 | { | 126 | { |
127 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
128 | int rhport = vdev->rhport; | ||
129 | u32 status; | ||
124 | unsigned long flags; | 130 | unsigned long flags; |
125 | 131 | ||
126 | usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); | 132 | usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); |
127 | 133 | ||
128 | spin_lock_irqsave(&the_controller->lock, flags); | 134 | spin_lock_irqsave(&vhci->lock, flags); |
135 | |||
136 | status = vhci->port_status[rhport]; | ||
129 | 137 | ||
130 | the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION | 138 | status |= USB_PORT_STAT_CONNECTION | (1 << USB_PORT_FEAT_C_CONNECTION); |
131 | | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
132 | 139 | ||
133 | switch (speed) { | 140 | switch (speed) { |
134 | case USB_SPEED_HIGH: | 141 | case USB_SPEED_HIGH: |
135 | the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED; | 142 | status |= USB_PORT_STAT_HIGH_SPEED; |
136 | break; | 143 | break; |
137 | case USB_SPEED_LOW: | 144 | case USB_SPEED_LOW: |
138 | the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED; | 145 | status |= USB_PORT_STAT_LOW_SPEED; |
139 | break; | 146 | break; |
140 | default: | 147 | default: |
141 | break; | 148 | break; |
142 | } | 149 | } |
143 | 150 | ||
144 | spin_unlock_irqrestore(&the_controller->lock, flags); | 151 | vhci->port_status[rhport] = status; |
152 | |||
153 | spin_unlock_irqrestore(&vhci->lock, flags); | ||
145 | 154 | ||
146 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | 155 | usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); |
147 | } | 156 | } |
148 | 157 | ||
149 | static void rh_port_disconnect(int rhport) | 158 | static void rh_port_disconnect(struct vhci_device *vdev) |
150 | { | 159 | { |
160 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
161 | int rhport = vdev->rhport; | ||
162 | u32 status; | ||
151 | unsigned long flags; | 163 | unsigned long flags; |
152 | 164 | ||
153 | usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); | 165 | usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); |
154 | 166 | ||
155 | spin_lock_irqsave(&the_controller->lock, flags); | 167 | spin_lock_irqsave(&vhci->lock, flags); |
168 | |||
169 | status = vhci->port_status[rhport]; | ||
170 | |||
171 | status &= ~USB_PORT_STAT_CONNECTION; | ||
172 | status |= (1 << USB_PORT_FEAT_C_CONNECTION); | ||
156 | 173 | ||
157 | the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; | 174 | vhci->port_status[rhport] = status; |
158 | the_controller->port_status[rhport] |= | ||
159 | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
160 | 175 | ||
161 | spin_unlock_irqrestore(&the_controller->lock, flags); | 176 | spin_unlock_irqrestore(&vhci->lock, flags); |
162 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | 177 | usb_hcd_poll_rh_status(vhci_to_hcd(vhci)); |
163 | } | 178 | } |
164 | 179 | ||
165 | #define PORT_C_MASK \ | 180 | #define PORT_C_MASK \ |
@@ -188,7 +203,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) | |||
188 | int changed = 0; | 203 | int changed = 0; |
189 | unsigned long flags; | 204 | unsigned long flags; |
190 | 205 | ||
191 | retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); | 206 | retval = DIV_ROUND_UP(VHCI_HC_PORTS + 1, 8); |
192 | memset(buf, 0, retval); | 207 | memset(buf, 0, retval); |
193 | 208 | ||
194 | vhci = hcd_to_vhci(hcd); | 209 | vhci = hcd_to_vhci(hcd); |
@@ -200,7 +215,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) | |||
200 | } | 215 | } |
201 | 216 | ||
202 | /* check pseudo status register for each port */ | 217 | /* check pseudo status register for each port */ |
203 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | 218 | for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { |
204 | if ((vhci->port_status[rhport] & PORT_C_MASK)) { | 219 | if ((vhci->port_status[rhport] & PORT_C_MASK)) { |
205 | /* The status of a port has been changed, */ | 220 | /* The status of a port has been changed, */ |
206 | usbip_dbg_vhci_rh("port %d status changed\n", rhport); | 221 | usbip_dbg_vhci_rh("port %d status changed\n", rhport); |
@@ -225,7 +240,7 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) | |||
225 | desc->bDescLength = 9; | 240 | desc->bDescLength = 9; |
226 | desc->wHubCharacteristics = cpu_to_le16( | 241 | desc->wHubCharacteristics = cpu_to_le16( |
227 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); | 242 | HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM); |
228 | desc->bNbrPorts = VHCI_NPORTS; | 243 | desc->bNbrPorts = VHCI_HC_PORTS; |
229 | desc->u.hs.DeviceRemovable[0] = 0xff; | 244 | desc->u.hs.DeviceRemovable[0] = 0xff; |
230 | desc->u.hs.DeviceRemovable[1] = 0xff; | 245 | desc->u.hs.DeviceRemovable[1] = 0xff; |
231 | } | 246 | } |
@@ -238,7 +253,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
238 | int rhport; | 253 | int rhport; |
239 | unsigned long flags; | 254 | unsigned long flags; |
240 | 255 | ||
241 | u32 prev_port_status[VHCI_NPORTS]; | 256 | u32 prev_port_status[VHCI_HC_PORTS]; |
242 | 257 | ||
243 | if (!HCD_HW_ACCESSIBLE(hcd)) | 258 | if (!HCD_HW_ACCESSIBLE(hcd)) |
244 | return -ETIMEDOUT; | 259 | return -ETIMEDOUT; |
@@ -249,7 +264,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
249 | */ | 264 | */ |
250 | usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, | 265 | usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, |
251 | wIndex); | 266 | wIndex); |
252 | if (wIndex > VHCI_NPORTS) | 267 | if (wIndex > VHCI_HC_PORTS) |
253 | pr_err("invalid port number %d\n", wIndex); | 268 | pr_err("invalid port number %d\n", wIndex); |
254 | rhport = ((__u8)(wIndex & 0x00ff)) - 1; | 269 | rhport = ((__u8)(wIndex & 0x00ff)) - 1; |
255 | 270 | ||
@@ -315,7 +330,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
315 | break; | 330 | break; |
316 | case GetPortStatus: | 331 | case GetPortStatus: |
317 | usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); | 332 | usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); |
318 | if (wIndex > VHCI_NPORTS || wIndex < 1) { | 333 | if (wIndex > VHCI_HC_PORTS || wIndex < 1) { |
319 | pr_err("invalid port number %d\n", wIndex); | 334 | pr_err("invalid port number %d\n", wIndex); |
320 | retval = -EPIPE; | 335 | retval = -EPIPE; |
321 | } | 336 | } |
@@ -416,14 +431,27 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
416 | 431 | ||
417 | static struct vhci_device *get_vdev(struct usb_device *udev) | 432 | static struct vhci_device *get_vdev(struct usb_device *udev) |
418 | { | 433 | { |
419 | int i; | 434 | struct platform_device *pdev; |
435 | struct usb_hcd *hcd; | ||
436 | struct vhci_hcd *vhci; | ||
437 | int pdev_nr, rhport; | ||
420 | 438 | ||
421 | if (!udev) | 439 | if (!udev) |
422 | return NULL; | 440 | return NULL; |
423 | 441 | ||
424 | for (i = 0; i < VHCI_NPORTS; i++) | 442 | for (pdev_nr = 0; pdev_nr < vhci_num_controllers; pdev_nr++) { |
425 | if (the_controller->vdev[i].udev == udev) | 443 | pdev = *(vhci_pdevs + pdev_nr); |
426 | return port_to_vdev(i); | 444 | if (pdev == NULL) |
445 | continue; | ||
446 | hcd = platform_get_drvdata(pdev); | ||
447 | if (hcd == NULL) | ||
448 | continue; | ||
449 | vhci = hcd_to_vhci(hcd); | ||
450 | for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { | ||
451 | if (vhci->vdev[rhport].udev == udev) | ||
452 | return &vhci->vdev[rhport]; | ||
453 | } | ||
454 | } | ||
427 | 455 | ||
428 | return NULL; | 456 | return NULL; |
429 | } | 457 | } |
@@ -432,6 +460,7 @@ static void vhci_tx_urb(struct urb *urb) | |||
432 | { | 460 | { |
433 | struct vhci_device *vdev = get_vdev(urb->dev); | 461 | struct vhci_device *vdev = get_vdev(urb->dev); |
434 | struct vhci_priv *priv; | 462 | struct vhci_priv *priv; |
463 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
435 | unsigned long flags; | 464 | unsigned long flags; |
436 | 465 | ||
437 | if (!vdev) { | 466 | if (!vdev) { |
@@ -447,7 +476,7 @@ static void vhci_tx_urb(struct urb *urb) | |||
447 | 476 | ||
448 | spin_lock_irqsave(&vdev->priv_lock, flags); | 477 | spin_lock_irqsave(&vdev->priv_lock, flags); |
449 | 478 | ||
450 | priv->seqnum = atomic_inc_return(&the_controller->seqnum); | 479 | priv->seqnum = atomic_inc_return(&vhci->seqnum); |
451 | if (priv->seqnum == 0xffff) | 480 | if (priv->seqnum == 0xffff) |
452 | dev_info(&urb->dev->dev, "seqnum max\n"); | 481 | dev_info(&urb->dev->dev, "seqnum max\n"); |
453 | 482 | ||
@@ -465,7 +494,9 @@ static void vhci_tx_urb(struct urb *urb) | |||
465 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | 494 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, |
466 | gfp_t mem_flags) | 495 | gfp_t mem_flags) |
467 | { | 496 | { |
497 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
468 | struct device *dev = &urb->dev->dev; | 498 | struct device *dev = &urb->dev->dev; |
499 | u8 portnum = urb->dev->portnum; | ||
469 | int ret = 0; | 500 | int ret = 0; |
470 | struct vhci_device *vdev; | 501 | struct vhci_device *vdev; |
471 | unsigned long flags; | 502 | unsigned long flags; |
@@ -473,26 +504,30 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
473 | usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", | 504 | usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", |
474 | hcd, urb, mem_flags); | 505 | hcd, urb, mem_flags); |
475 | 506 | ||
507 | if (portnum > VHCI_HC_PORTS) { | ||
508 | pr_err("invalid port number %d\n", portnum); | ||
509 | return -ENODEV; | ||
510 | } | ||
511 | vdev = &vhci->vdev[portnum-1]; | ||
512 | |||
476 | /* patch to usb_sg_init() is in 2.5.60 */ | 513 | /* patch to usb_sg_init() is in 2.5.60 */ |
477 | BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); | 514 | BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); |
478 | 515 | ||
479 | spin_lock_irqsave(&the_controller->lock, flags); | 516 | spin_lock_irqsave(&vhci->lock, flags); |
480 | 517 | ||
481 | if (urb->status != -EINPROGRESS) { | 518 | if (urb->status != -EINPROGRESS) { |
482 | dev_err(dev, "URB already unlinked!, status %d\n", urb->status); | 519 | dev_err(dev, "URB already unlinked!, status %d\n", urb->status); |
483 | spin_unlock_irqrestore(&the_controller->lock, flags); | 520 | spin_unlock_irqrestore(&vhci->lock, flags); |
484 | return urb->status; | 521 | return urb->status; |
485 | } | 522 | } |
486 | 523 | ||
487 | vdev = port_to_vdev(urb->dev->portnum-1); | ||
488 | |||
489 | /* refuse enqueue for dead connection */ | 524 | /* refuse enqueue for dead connection */ |
490 | spin_lock(&vdev->ud.lock); | 525 | spin_lock(&vdev->ud.lock); |
491 | if (vdev->ud.status == VDEV_ST_NULL || | 526 | if (vdev->ud.status == VDEV_ST_NULL || |
492 | vdev->ud.status == VDEV_ST_ERROR) { | 527 | vdev->ud.status == VDEV_ST_ERROR) { |
493 | dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); | 528 | dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); |
494 | spin_unlock(&vdev->ud.lock); | 529 | spin_unlock(&vdev->ud.lock); |
495 | spin_unlock_irqrestore(&the_controller->lock, flags); | 530 | spin_unlock_irqrestore(&vhci->lock, flags); |
496 | return -ENODEV; | 531 | return -ENODEV; |
497 | } | 532 | } |
498 | spin_unlock(&vdev->ud.lock); | 533 | spin_unlock(&vdev->ud.lock); |
@@ -565,17 +600,16 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
565 | 600 | ||
566 | out: | 601 | out: |
567 | vhci_tx_urb(urb); | 602 | vhci_tx_urb(urb); |
568 | spin_unlock_irqrestore(&the_controller->lock, flags); | 603 | spin_unlock_irqrestore(&vhci->lock, flags); |
569 | 604 | ||
570 | return 0; | 605 | return 0; |
571 | 606 | ||
572 | no_need_xmit: | 607 | no_need_xmit: |
573 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 608 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
574 | no_need_unlink: | 609 | no_need_unlink: |
575 | spin_unlock_irqrestore(&the_controller->lock, flags); | 610 | spin_unlock_irqrestore(&vhci->lock, flags); |
576 | if (!ret) | 611 | if (!ret) |
577 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), | 612 | usb_hcd_giveback_urb(hcd, urb, urb->status); |
578 | urb, urb->status); | ||
579 | return ret; | 613 | return ret; |
580 | } | 614 | } |
581 | 615 | ||
@@ -627,19 +661,20 @@ no_need_unlink: | |||
627 | */ | 661 | */ |
628 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | 662 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
629 | { | 663 | { |
664 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
630 | struct vhci_priv *priv; | 665 | struct vhci_priv *priv; |
631 | struct vhci_device *vdev; | 666 | struct vhci_device *vdev; |
632 | unsigned long flags; | 667 | unsigned long flags; |
633 | 668 | ||
634 | pr_info("dequeue a urb %p\n", urb); | 669 | pr_info("dequeue a urb %p\n", urb); |
635 | 670 | ||
636 | spin_lock_irqsave(&the_controller->lock, flags); | 671 | spin_lock_irqsave(&vhci->lock, flags); |
637 | 672 | ||
638 | priv = urb->hcpriv; | 673 | priv = urb->hcpriv; |
639 | if (!priv) { | 674 | if (!priv) { |
640 | /* URB was never linked! or will be soon given back by | 675 | /* URB was never linked! or will be soon given back by |
641 | * vhci_rx. */ | 676 | * vhci_rx. */ |
642 | spin_unlock_irqrestore(&the_controller->lock, flags); | 677 | spin_unlock_irqrestore(&vhci->lock, flags); |
643 | return -EIDRM; | 678 | return -EIDRM; |
644 | } | 679 | } |
645 | 680 | ||
@@ -648,7 +683,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
648 | 683 | ||
649 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | 684 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); |
650 | if (ret) { | 685 | if (ret) { |
651 | spin_unlock_irqrestore(&the_controller->lock, flags); | 686 | spin_unlock_irqrestore(&vhci->lock, flags); |
652 | return ret; | 687 | return ret; |
653 | } | 688 | } |
654 | } | 689 | } |
@@ -676,10 +711,9 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
676 | 711 | ||
677 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 712 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
678 | 713 | ||
679 | spin_unlock_irqrestore(&the_controller->lock, flags); | 714 | spin_unlock_irqrestore(&vhci->lock, flags); |
680 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | 715 | usb_hcd_giveback_urb(vhci_to_hcd(vhci), urb, urb->status); |
681 | urb->status); | 716 | spin_lock_irqsave(&vhci->lock, flags); |
682 | spin_lock_irqsave(&the_controller->lock, flags); | ||
683 | 717 | ||
684 | } else { | 718 | } else { |
685 | /* tcp connection is alive */ | 719 | /* tcp connection is alive */ |
@@ -691,12 +725,12 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
691 | unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); | 725 | unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); |
692 | if (!unlink) { | 726 | if (!unlink) { |
693 | spin_unlock(&vdev->priv_lock); | 727 | spin_unlock(&vdev->priv_lock); |
694 | spin_unlock_irqrestore(&the_controller->lock, flags); | 728 | spin_unlock_irqrestore(&vhci->lock, flags); |
695 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); | 729 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); |
696 | return -ENOMEM; | 730 | return -ENOMEM; |
697 | } | 731 | } |
698 | 732 | ||
699 | unlink->seqnum = atomic_inc_return(&the_controller->seqnum); | 733 | unlink->seqnum = atomic_inc_return(&vhci->seqnum); |
700 | if (unlink->seqnum == 0xffff) | 734 | if (unlink->seqnum == 0xffff) |
701 | pr_info("seqnum max\n"); | 735 | pr_info("seqnum max\n"); |
702 | 736 | ||
@@ -712,7 +746,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
712 | spin_unlock(&vdev->priv_lock); | 746 | spin_unlock(&vdev->priv_lock); |
713 | } | 747 | } |
714 | 748 | ||
715 | spin_unlock_irqrestore(&the_controller->lock, flags); | 749 | spin_unlock_irqrestore(&vhci->lock, flags); |
716 | 750 | ||
717 | usbip_dbg_vhci_hc("leave\n"); | 751 | usbip_dbg_vhci_hc("leave\n"); |
718 | return 0; | 752 | return 0; |
@@ -720,10 +754,12 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
720 | 754 | ||
721 | static void vhci_device_unlink_cleanup(struct vhci_device *vdev) | 755 | static void vhci_device_unlink_cleanup(struct vhci_device *vdev) |
722 | { | 756 | { |
757 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
758 | struct usb_hcd *hcd = vhci_to_hcd(vhci); | ||
723 | struct vhci_unlink *unlink, *tmp; | 759 | struct vhci_unlink *unlink, *tmp; |
724 | unsigned long flags; | 760 | unsigned long flags; |
725 | 761 | ||
726 | spin_lock_irqsave(&the_controller->lock, flags); | 762 | spin_lock_irqsave(&vhci->lock, flags); |
727 | spin_lock(&vdev->priv_lock); | 763 | spin_lock(&vdev->priv_lock); |
728 | 764 | ||
729 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { | 765 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { |
@@ -752,24 +788,23 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) | |||
752 | 788 | ||
753 | urb->status = -ENODEV; | 789 | urb->status = -ENODEV; |
754 | 790 | ||
755 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | 791 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
756 | 792 | ||
757 | list_del(&unlink->list); | 793 | list_del(&unlink->list); |
758 | 794 | ||
759 | spin_unlock(&vdev->priv_lock); | 795 | spin_unlock(&vdev->priv_lock); |
760 | spin_unlock_irqrestore(&the_controller->lock, flags); | 796 | spin_unlock_irqrestore(&vhci->lock, flags); |
761 | 797 | ||
762 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | 798 | usb_hcd_giveback_urb(hcd, urb, urb->status); |
763 | urb->status); | ||
764 | 799 | ||
765 | spin_lock_irqsave(&the_controller->lock, flags); | 800 | spin_lock_irqsave(&vhci->lock, flags); |
766 | spin_lock(&vdev->priv_lock); | 801 | spin_lock(&vdev->priv_lock); |
767 | 802 | ||
768 | kfree(unlink); | 803 | kfree(unlink); |
769 | } | 804 | } |
770 | 805 | ||
771 | spin_unlock(&vdev->priv_lock); | 806 | spin_unlock(&vdev->priv_lock); |
772 | spin_unlock_irqrestore(&the_controller->lock, flags); | 807 | spin_unlock_irqrestore(&vhci->lock, flags); |
773 | } | 808 | } |
774 | 809 | ||
775 | /* | 810 | /* |
@@ -827,7 +862,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) | |||
827 | * is actually given back by vhci_rx after receiving its return pdu. | 862 | * is actually given back by vhci_rx after receiving its return pdu. |
828 | * | 863 | * |
829 | */ | 864 | */ |
830 | rh_port_disconnect(vdev->rhport); | 865 | rh_port_disconnect(vdev); |
831 | 866 | ||
832 | pr_info("disconnect device\n"); | 867 | pr_info("disconnect device\n"); |
833 | } | 868 | } |
@@ -866,7 +901,7 @@ static void vhci_device_unusable(struct usbip_device *ud) | |||
866 | 901 | ||
867 | static void vhci_device_init(struct vhci_device *vdev) | 902 | static void vhci_device_init(struct vhci_device *vdev) |
868 | { | 903 | { |
869 | memset(vdev, 0, sizeof(*vdev)); | 904 | memset(vdev, 0, sizeof(struct vhci_device)); |
870 | 905 | ||
871 | vdev->ud.side = USBIP_VHCI; | 906 | vdev->ud.side = USBIP_VHCI; |
872 | vdev->ud.status = VDEV_ST_NULL; | 907 | vdev->ud.status = VDEV_ST_NULL; |
@@ -887,17 +922,34 @@ static void vhci_device_init(struct vhci_device *vdev) | |||
887 | usbip_start_eh(&vdev->ud); | 922 | usbip_start_eh(&vdev->ud); |
888 | } | 923 | } |
889 | 924 | ||
925 | static int hcd_name_to_id(const char *name) | ||
926 | { | ||
927 | char *c; | ||
928 | long val; | ||
929 | int ret; | ||
930 | |||
931 | c = strchr(name, '.'); | ||
932 | if (c == NULL) | ||
933 | return 0; | ||
934 | |||
935 | ret = kstrtol(c+1, 10, &val); | ||
936 | if (ret < 0) | ||
937 | return ret; | ||
938 | |||
939 | return val; | ||
940 | } | ||
941 | |||
890 | static int vhci_start(struct usb_hcd *hcd) | 942 | static int vhci_start(struct usb_hcd *hcd) |
891 | { | 943 | { |
892 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | 944 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); |
893 | int rhport; | 945 | int id, rhport; |
894 | int err = 0; | 946 | int err = 0; |
895 | 947 | ||
896 | usbip_dbg_vhci_hc("enter vhci_start\n"); | 948 | usbip_dbg_vhci_hc("enter vhci_start\n"); |
897 | 949 | ||
898 | /* initialize private data of usb_hcd */ | 950 | /* initialize private data of usb_hcd */ |
899 | 951 | ||
900 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | 952 | for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { |
901 | struct vhci_device *vdev = &vhci->vdev[rhport]; | 953 | struct vhci_device *vdev = &vhci->vdev[rhport]; |
902 | 954 | ||
903 | vhci_device_init(vdev); | 955 | vhci_device_init(vdev); |
@@ -910,11 +962,26 @@ static int vhci_start(struct usb_hcd *hcd) | |||
910 | hcd->power_budget = 0; /* no limit */ | 962 | hcd->power_budget = 0; /* no limit */ |
911 | hcd->uses_new_polling = 1; | 963 | hcd->uses_new_polling = 1; |
912 | 964 | ||
965 | id = hcd_name_to_id(hcd_name(hcd)); | ||
966 | if (id < 0) { | ||
967 | pr_err("invalid vhci name %s\n", hcd_name(hcd)); | ||
968 | return -EINVAL; | ||
969 | } | ||
970 | |||
913 | /* vhci_hcd is now ready to be controlled through sysfs */ | 971 | /* vhci_hcd is now ready to be controlled through sysfs */ |
914 | err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | 972 | if (id == 0) { |
915 | if (err) { | 973 | err = vhci_init_attr_group(); |
916 | pr_err("create sysfs files\n"); | 974 | if (err) { |
917 | return err; | 975 | pr_err("init attr group\n"); |
976 | return err; | ||
977 | } | ||
978 | err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); | ||
979 | if (err) { | ||
980 | pr_err("create sysfs files\n"); | ||
981 | vhci_finish_attr_group(); | ||
982 | return err; | ||
983 | } | ||
984 | pr_info("created sysfs %s\n", hcd_name(hcd)); | ||
918 | } | 985 | } |
919 | 986 | ||
920 | return 0; | 987 | return 0; |
@@ -923,15 +990,19 @@ static int vhci_start(struct usb_hcd *hcd) | |||
923 | static void vhci_stop(struct usb_hcd *hcd) | 990 | static void vhci_stop(struct usb_hcd *hcd) |
924 | { | 991 | { |
925 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | 992 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); |
926 | int rhport = 0; | 993 | int id, rhport; |
927 | 994 | ||
928 | usbip_dbg_vhci_hc("stop VHCI controller\n"); | 995 | usbip_dbg_vhci_hc("stop VHCI controller\n"); |
929 | 996 | ||
930 | /* 1. remove the userland interface of vhci_hcd */ | 997 | /* 1. remove the userland interface of vhci_hcd */ |
931 | sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | 998 | id = hcd_name_to_id(hcd_name(hcd)); |
999 | if (id == 0) { | ||
1000 | sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); | ||
1001 | vhci_finish_attr_group(); | ||
1002 | } | ||
932 | 1003 | ||
933 | /* 2. shutdown all the ports of vhci_hcd */ | 1004 | /* 2. shutdown all the ports of vhci_hcd */ |
934 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | 1005 | for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) { |
935 | struct vhci_device *vdev = &vhci->vdev[rhport]; | 1006 | struct vhci_device *vdev = &vhci->vdev[rhport]; |
936 | 1007 | ||
937 | usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); | 1008 | usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); |
@@ -1025,9 +1096,6 @@ static int vhci_hcd_probe(struct platform_device *pdev) | |||
1025 | } | 1096 | } |
1026 | hcd->has_tt = 1; | 1097 | hcd->has_tt = 1; |
1027 | 1098 | ||
1028 | /* this is private data for vhci_hcd */ | ||
1029 | the_controller = hcd_to_vhci(hcd); | ||
1030 | |||
1031 | /* | 1099 | /* |
1032 | * Finish generic HCD structure initialization and register. | 1100 | * Finish generic HCD structure initialization and register. |
1033 | * Call the driver's reset() and start() routines. | 1101 | * Call the driver's reset() and start() routines. |
@@ -1036,7 +1104,6 @@ static int vhci_hcd_probe(struct platform_device *pdev) | |||
1036 | if (ret != 0) { | 1104 | if (ret != 0) { |
1037 | pr_err("usb_add_hcd failed %d\n", ret); | 1105 | pr_err("usb_add_hcd failed %d\n", ret); |
1038 | usb_put_hcd(hcd); | 1106 | usb_put_hcd(hcd); |
1039 | the_controller = NULL; | ||
1040 | return ret; | 1107 | return ret; |
1041 | } | 1108 | } |
1042 | 1109 | ||
@@ -1059,7 +1126,6 @@ static int vhci_hcd_remove(struct platform_device *pdev) | |||
1059 | */ | 1126 | */ |
1060 | usb_remove_hcd(hcd); | 1127 | usb_remove_hcd(hcd); |
1061 | usb_put_hcd(hcd); | 1128 | usb_put_hcd(hcd); |
1062 | the_controller = NULL; | ||
1063 | 1129 | ||
1064 | return 0; | 1130 | return 0; |
1065 | } | 1131 | } |
@@ -1070,21 +1136,24 @@ static int vhci_hcd_remove(struct platform_device *pdev) | |||
1070 | static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state) | 1136 | static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state) |
1071 | { | 1137 | { |
1072 | struct usb_hcd *hcd; | 1138 | struct usb_hcd *hcd; |
1073 | int rhport = 0; | 1139 | struct vhci_hcd *vhci; |
1140 | int rhport; | ||
1074 | int connected = 0; | 1141 | int connected = 0; |
1075 | int ret = 0; | 1142 | int ret = 0; |
1076 | unsigned long flags; | 1143 | unsigned long flags; |
1077 | 1144 | ||
1078 | hcd = platform_get_drvdata(pdev); | 1145 | hcd = platform_get_drvdata(pdev); |
1146 | if (!hcd) | ||
1147 | return 0; | ||
1148 | vhci = hcd_to_vhci(hcd); | ||
1079 | 1149 | ||
1080 | spin_lock_irqsave(&the_controller->lock, flags); | 1150 | spin_lock_irqsave(&vhci->lock, flags); |
1081 | 1151 | ||
1082 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) | 1152 | for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) |
1083 | if (the_controller->port_status[rhport] & | 1153 | if (vhci->port_status[rhport] & USB_PORT_STAT_CONNECTION) |
1084 | USB_PORT_STAT_CONNECTION) | ||
1085 | connected += 1; | 1154 | connected += 1; |
1086 | 1155 | ||
1087 | spin_unlock_irqrestore(&the_controller->lock, flags); | 1156 | spin_unlock_irqrestore(&vhci->lock, flags); |
1088 | 1157 | ||
1089 | if (connected > 0) { | 1158 | if (connected > 0) { |
1090 | dev_info(&pdev->dev, | 1159 | dev_info(&pdev->dev, |
@@ -1106,6 +1175,8 @@ static int vhci_hcd_resume(struct platform_device *pdev) | |||
1106 | dev_dbg(&pdev->dev, "%s\n", __func__); | 1175 | dev_dbg(&pdev->dev, "%s\n", __func__); |
1107 | 1176 | ||
1108 | hcd = platform_get_drvdata(pdev); | 1177 | hcd = platform_get_drvdata(pdev); |
1178 | if (!hcd) | ||
1179 | return 0; | ||
1109 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 1180 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
1110 | usb_hcd_poll_rh_status(hcd); | 1181 | usb_hcd_poll_rh_status(hcd); |
1111 | 1182 | ||
@@ -1129,52 +1200,78 @@ static struct platform_driver vhci_driver = { | |||
1129 | }, | 1200 | }, |
1130 | }; | 1201 | }; |
1131 | 1202 | ||
1132 | /* | 1203 | static int add_platform_device(int id) |
1133 | * The VHCI 'device' is 'virtual'; not a real plug&play hardware. | ||
1134 | * We need to add this virtual device as a platform device arbitrarily: | ||
1135 | * 1. platform_device_register() | ||
1136 | */ | ||
1137 | static void the_pdev_release(struct device *dev) | ||
1138 | { | 1204 | { |
1205 | struct platform_device *pdev; | ||
1206 | int dev_nr; | ||
1207 | |||
1208 | if (id == 0) | ||
1209 | dev_nr = -1; | ||
1210 | else | ||
1211 | dev_nr = id; | ||
1212 | |||
1213 | pdev = platform_device_register_simple(driver_name, dev_nr, NULL, 0); | ||
1214 | if (IS_ERR(pdev)) | ||
1215 | return PTR_ERR(pdev); | ||
1216 | |||
1217 | *(vhci_pdevs + id) = pdev; | ||
1218 | return 0; | ||
1139 | } | 1219 | } |
1140 | 1220 | ||
1141 | static struct platform_device the_pdev = { | 1221 | static void del_platform_devices(void) |
1142 | /* should be the same name as driver_name */ | 1222 | { |
1143 | .name = driver_name, | 1223 | struct platform_device *pdev; |
1144 | .id = -1, | 1224 | int i; |
1145 | .dev = { | 1225 | |
1146 | .release = the_pdev_release, | 1226 | for (i = 0; i < vhci_num_controllers; i++) { |
1147 | }, | 1227 | pdev = *(vhci_pdevs + i); |
1148 | }; | 1228 | if (pdev != NULL) |
1229 | platform_device_unregister(pdev); | ||
1230 | *(vhci_pdevs + i) = NULL; | ||
1231 | } | ||
1232 | sysfs_remove_link(&platform_bus.kobj, driver_name); | ||
1233 | } | ||
1149 | 1234 | ||
1150 | static int __init vhci_hcd_init(void) | 1235 | static int __init vhci_hcd_init(void) |
1151 | { | 1236 | { |
1152 | int ret; | 1237 | int i, ret; |
1153 | 1238 | ||
1154 | if (usb_disabled()) | 1239 | if (usb_disabled()) |
1155 | return -ENODEV; | 1240 | return -ENODEV; |
1156 | 1241 | ||
1242 | if (vhci_num_controllers < 1) | ||
1243 | vhci_num_controllers = 1; | ||
1244 | |||
1245 | vhci_pdevs = kcalloc(vhci_num_controllers, sizeof(void *), GFP_KERNEL); | ||
1246 | if (vhci_pdevs == NULL) | ||
1247 | return -ENOMEM; | ||
1248 | |||
1157 | ret = platform_driver_register(&vhci_driver); | 1249 | ret = platform_driver_register(&vhci_driver); |
1158 | if (ret) | 1250 | if (ret) |
1159 | goto err_driver_register; | 1251 | goto err_driver_register; |
1160 | 1252 | ||
1161 | ret = platform_device_register(&the_pdev); | 1253 | for (i = 0; i < vhci_num_controllers; i++) { |
1162 | if (ret) | 1254 | ret = add_platform_device(i); |
1163 | goto err_platform_device_register; | 1255 | if (ret) |
1256 | goto err_platform_device_register; | ||
1257 | } | ||
1164 | 1258 | ||
1165 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | 1259 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); |
1166 | return ret; | 1260 | return ret; |
1167 | 1261 | ||
1168 | err_platform_device_register: | 1262 | err_platform_device_register: |
1263 | del_platform_devices(); | ||
1169 | platform_driver_unregister(&vhci_driver); | 1264 | platform_driver_unregister(&vhci_driver); |
1170 | err_driver_register: | 1265 | err_driver_register: |
1266 | kfree(vhci_pdevs); | ||
1171 | return ret; | 1267 | return ret; |
1172 | } | 1268 | } |
1173 | 1269 | ||
1174 | static void __exit vhci_hcd_exit(void) | 1270 | static void __exit vhci_hcd_exit(void) |
1175 | { | 1271 | { |
1176 | platform_device_unregister(&the_pdev); | 1272 | del_platform_devices(); |
1177 | platform_driver_unregister(&vhci_driver); | 1273 | platform_driver_unregister(&vhci_driver); |
1274 | kfree(vhci_pdevs); | ||
1178 | } | 1275 | } |
1179 | 1276 | ||
1180 | module_init(vhci_hcd_init); | 1277 | module_init(vhci_hcd_init); |
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index d656e0edc3d5..fc2d319e2360 100644 --- a/drivers/usb/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c | |||
@@ -70,6 +70,7 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) | |||
70 | static void vhci_recv_ret_submit(struct vhci_device *vdev, | 70 | static void vhci_recv_ret_submit(struct vhci_device *vdev, |
71 | struct usbip_header *pdu) | 71 | struct usbip_header *pdu) |
72 | { | 72 | { |
73 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
73 | struct usbip_device *ud = &vdev->ud; | 74 | struct usbip_device *ud = &vdev->ud; |
74 | struct urb *urb; | 75 | struct urb *urb; |
75 | unsigned long flags; | 76 | unsigned long flags; |
@@ -81,7 +82,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
81 | if (!urb) { | 82 | if (!urb) { |
82 | pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); | 83 | pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); |
83 | pr_info("max seqnum %d\n", | 84 | pr_info("max seqnum %d\n", |
84 | atomic_read(&the_controller->seqnum)); | 85 | atomic_read(&vhci->seqnum)); |
85 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | 86 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); |
86 | return; | 87 | return; |
87 | } | 88 | } |
@@ -105,11 +106,11 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
105 | 106 | ||
106 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | 107 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); |
107 | 108 | ||
108 | spin_lock_irqsave(&the_controller->lock, flags); | 109 | spin_lock_irqsave(&vhci->lock, flags); |
109 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | 110 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(vhci), urb); |
110 | spin_unlock_irqrestore(&the_controller->lock, flags); | 111 | spin_unlock_irqrestore(&vhci->lock, flags); |
111 | 112 | ||
112 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | 113 | usb_hcd_giveback_urb(vhci_to_hcd(vhci), urb, urb->status); |
113 | 114 | ||
114 | usbip_dbg_vhci_rx("Leave\n"); | 115 | usbip_dbg_vhci_rx("Leave\n"); |
115 | } | 116 | } |
@@ -142,6 +143,7 @@ static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev, | |||
142 | static void vhci_recv_ret_unlink(struct vhci_device *vdev, | 143 | static void vhci_recv_ret_unlink(struct vhci_device *vdev, |
143 | struct usbip_header *pdu) | 144 | struct usbip_header *pdu) |
144 | { | 145 | { |
146 | struct vhci_hcd *vhci = vdev_to_vhci(vdev); | ||
145 | struct vhci_unlink *unlink; | 147 | struct vhci_unlink *unlink; |
146 | struct urb *urb; | 148 | struct urb *urb; |
147 | unsigned long flags; | 149 | unsigned long flags; |
@@ -174,12 +176,11 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, | |||
174 | urb->status = pdu->u.ret_unlink.status; | 176 | urb->status = pdu->u.ret_unlink.status; |
175 | pr_info("urb->status %d\n", urb->status); | 177 | pr_info("urb->status %d\n", urb->status); |
176 | 178 | ||
177 | spin_lock_irqsave(&the_controller->lock, flags); | 179 | spin_lock_irqsave(&vhci->lock, flags); |
178 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | 180 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(vhci), urb); |
179 | spin_unlock_irqrestore(&the_controller->lock, flags); | 181 | spin_unlock_irqrestore(&vhci->lock, flags); |
180 | 182 | ||
181 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | 183 | usb_hcd_giveback_urb(vhci_to_hcd(vhci), urb, urb->status); |
182 | urb->status); | ||
183 | } | 184 | } |
184 | 185 | ||
185 | kfree(unlink); | 186 | kfree(unlink); |
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 5b5462eb1665..c404017c1b5a 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi | 2 | * Copyright (C) 2003-2008 Takahiro Hirofuchi |
3 | * Copyright (C) 2015-2016 Nobuo Iwata | ||
3 | * | 4 | * |
4 | * This is free software; you can redistribute it and/or modify | 5 | * This is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -20,6 +21,8 @@ | |||
20 | #include <linux/kthread.h> | 21 | #include <linux/kthread.h> |
21 | #include <linux/file.h> | 22 | #include <linux/file.h> |
22 | #include <linux/net.h> | 23 | #include <linux/net.h> |
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
23 | 26 | ||
24 | #include "usbip_common.h" | 27 | #include "usbip_common.h" |
25 | #include "vhci.h" | 28 | #include "vhci.h" |
@@ -27,106 +30,190 @@ | |||
27 | /* TODO: refine locking ?*/ | 30 | /* TODO: refine locking ?*/ |
28 | 31 | ||
29 | /* Sysfs entry to show port status */ | 32 | /* Sysfs entry to show port status */ |
30 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, | 33 | static ssize_t status_show_vhci(int pdev_nr, char *out) |
31 | char *out) | ||
32 | { | 34 | { |
35 | struct platform_device *pdev = *(vhci_pdevs + pdev_nr); | ||
36 | struct vhci_hcd *vhci; | ||
33 | char *s = out; | 37 | char *s = out; |
34 | int i = 0; | 38 | int i = 0; |
35 | unsigned long flags; | 39 | unsigned long flags; |
36 | 40 | ||
37 | BUG_ON(!the_controller || !out); | 41 | if (!pdev || !out) { |
42 | usbip_dbg_vhci_sysfs("show status error\n"); | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | vhci = hcd_to_vhci(platform_get_drvdata(pdev)); | ||
38 | 47 | ||
39 | spin_lock_irqsave(&the_controller->lock, flags); | 48 | spin_lock_irqsave(&vhci->lock, flags); |
40 | 49 | ||
41 | /* | 50 | /* |
42 | * output example: | 51 | * output example: |
43 | * prt sta spd dev socket local_busid | 52 | * port sta spd dev socket local_busid |
44 | * 000 004 000 000 c5a7bb80 1-2.3 | 53 | * 0000 004 000 00000000 c5a7bb80 1-2.3 |
45 | * 001 004 000 000 d8cee980 2-3.4 | 54 | * 0001 004 000 00000000 d8cee980 2-3.4 |
46 | * | 55 | * |
47 | * IP address can be retrieved from a socket pointer address by looking | 56 | * IP address can be retrieved from a socket pointer address by looking |
48 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | 57 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a |
49 | * port number and its peer IP address. | 58 | * port number and its peer IP address. |
50 | */ | 59 | */ |
51 | out += sprintf(out, | 60 | for (i = 0; i < VHCI_HC_PORTS; i++) { |
52 | "prt sta spd bus dev socket local_busid\n"); | 61 | struct vhci_device *vdev = &vhci->vdev[i]; |
53 | |||
54 | for (i = 0; i < VHCI_NPORTS; i++) { | ||
55 | struct vhci_device *vdev = port_to_vdev(i); | ||
56 | 62 | ||
57 | spin_lock(&vdev->ud.lock); | 63 | spin_lock(&vdev->ud.lock); |
58 | out += sprintf(out, "%03u %03u ", i, vdev->ud.status); | 64 | out += sprintf(out, "%04u %03u ", |
65 | (pdev_nr * VHCI_HC_PORTS) + i, | ||
66 | vdev->ud.status); | ||
59 | 67 | ||
60 | if (vdev->ud.status == VDEV_ST_USED) { | 68 | if (vdev->ud.status == VDEV_ST_USED) { |
61 | out += sprintf(out, "%03u %08x ", | 69 | out += sprintf(out, "%03u %08x ", |
62 | vdev->speed, vdev->devid); | 70 | vdev->speed, vdev->devid); |
63 | out += sprintf(out, "%16p ", vdev->ud.tcp_socket); | 71 | out += sprintf(out, "%16p %s", |
64 | out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); | 72 | vdev->ud.tcp_socket, |
73 | dev_name(&vdev->udev->dev)); | ||
65 | 74 | ||
66 | } else { | 75 | } else { |
67 | out += sprintf(out, "000 000 000 0000000000000000 0-0"); | 76 | out += sprintf(out, "000 00000000 "); |
77 | out += sprintf(out, "0000000000000000 0-0"); | ||
68 | } | 78 | } |
69 | 79 | ||
70 | out += sprintf(out, "\n"); | 80 | out += sprintf(out, "\n"); |
71 | spin_unlock(&vdev->ud.lock); | 81 | spin_unlock(&vdev->ud.lock); |
72 | } | 82 | } |
73 | 83 | ||
74 | spin_unlock_irqrestore(&the_controller->lock, flags); | 84 | spin_unlock_irqrestore(&vhci->lock, flags); |
85 | |||
86 | return out - s; | ||
87 | } | ||
88 | |||
89 | static ssize_t status_show_not_ready(int pdev_nr, char *out) | ||
90 | { | ||
91 | char *s = out; | ||
92 | int i = 0; | ||
93 | |||
94 | for (i = 0; i < VHCI_HC_PORTS; i++) { | ||
95 | out += sprintf(out, "%04u %03u ", | ||
96 | (pdev_nr * VHCI_HC_PORTS) + i, | ||
97 | VDEV_ST_NOTASSIGNED); | ||
98 | out += sprintf(out, "000 00000000 0000000000000000 0-0"); | ||
99 | out += sprintf(out, "\n"); | ||
100 | } | ||
101 | return out - s; | ||
102 | } | ||
103 | |||
104 | static int status_name_to_id(const char *name) | ||
105 | { | ||
106 | char *c; | ||
107 | long val; | ||
108 | int ret; | ||
109 | |||
110 | c = strchr(name, '.'); | ||
111 | if (c == NULL) | ||
112 | return 0; | ||
75 | 113 | ||
114 | ret = kstrtol(c+1, 10, &val); | ||
115 | if (ret < 0) | ||
116 | return ret; | ||
117 | |||
118 | return val; | ||
119 | } | ||
120 | |||
121 | static ssize_t status_show(struct device *dev, | ||
122 | struct device_attribute *attr, char *out) | ||
123 | { | ||
124 | char *s = out; | ||
125 | int pdev_nr; | ||
126 | |||
127 | out += sprintf(out, | ||
128 | "port sta spd dev socket local_busid\n"); | ||
129 | |||
130 | pdev_nr = status_name_to_id(attr->attr.name); | ||
131 | if (pdev_nr < 0) | ||
132 | out += status_show_not_ready(pdev_nr, out); | ||
133 | else | ||
134 | out += status_show_vhci(pdev_nr, out); | ||
135 | |||
136 | return out - s; | ||
137 | } | ||
138 | |||
139 | static ssize_t nports_show(struct device *dev, struct device_attribute *attr, | ||
140 | char *out) | ||
141 | { | ||
142 | char *s = out; | ||
143 | |||
144 | out += sprintf(out, "%d\n", VHCI_HC_PORTS * vhci_num_controllers); | ||
76 | return out - s; | 145 | return out - s; |
77 | } | 146 | } |
78 | static DEVICE_ATTR_RO(status); | 147 | static DEVICE_ATTR_RO(nports); |
79 | 148 | ||
80 | /* Sysfs entry to shutdown a virtual connection */ | 149 | /* Sysfs entry to shutdown a virtual connection */ |
81 | static int vhci_port_disconnect(__u32 rhport) | 150 | static int vhci_port_disconnect(struct vhci_hcd *vhci, __u32 rhport) |
82 | { | 151 | { |
83 | struct vhci_device *vdev; | 152 | struct vhci_device *vdev = &vhci->vdev[rhport]; |
84 | unsigned long flags; | 153 | unsigned long flags; |
85 | 154 | ||
86 | usbip_dbg_vhci_sysfs("enter\n"); | 155 | usbip_dbg_vhci_sysfs("enter\n"); |
87 | 156 | ||
88 | /* lock */ | 157 | /* lock */ |
89 | spin_lock_irqsave(&the_controller->lock, flags); | 158 | spin_lock_irqsave(&vhci->lock, flags); |
90 | |||
91 | vdev = port_to_vdev(rhport); | ||
92 | |||
93 | spin_lock(&vdev->ud.lock); | 159 | spin_lock(&vdev->ud.lock); |
160 | |||
94 | if (vdev->ud.status == VDEV_ST_NULL) { | 161 | if (vdev->ud.status == VDEV_ST_NULL) { |
95 | pr_err("not connected %d\n", vdev->ud.status); | 162 | pr_err("not connected %d\n", vdev->ud.status); |
96 | 163 | ||
97 | /* unlock */ | 164 | /* unlock */ |
98 | spin_unlock(&vdev->ud.lock); | 165 | spin_unlock(&vdev->ud.lock); |
99 | spin_unlock_irqrestore(&the_controller->lock, flags); | 166 | spin_unlock_irqrestore(&vhci->lock, flags); |
100 | 167 | ||
101 | return -EINVAL; | 168 | return -EINVAL; |
102 | } | 169 | } |
103 | 170 | ||
104 | /* unlock */ | 171 | /* unlock */ |
105 | spin_unlock(&vdev->ud.lock); | 172 | spin_unlock(&vdev->ud.lock); |
106 | spin_unlock_irqrestore(&the_controller->lock, flags); | 173 | spin_unlock_irqrestore(&vhci->lock, flags); |
107 | 174 | ||
108 | usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); | 175 | usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); |
109 | 176 | ||
110 | return 0; | 177 | return 0; |
111 | } | 178 | } |
112 | 179 | ||
180 | static int valid_port(__u32 pdev_nr, __u32 rhport) | ||
181 | { | ||
182 | if (pdev_nr >= vhci_num_controllers) { | ||
183 | pr_err("pdev %u\n", pdev_nr); | ||
184 | return 0; | ||
185 | } | ||
186 | if (rhport >= VHCI_HC_PORTS) { | ||
187 | pr_err("rhport %u\n", rhport); | ||
188 | return 0; | ||
189 | } | ||
190 | return 1; | ||
191 | } | ||
192 | |||
113 | static ssize_t store_detach(struct device *dev, struct device_attribute *attr, | 193 | static ssize_t store_detach(struct device *dev, struct device_attribute *attr, |
114 | const char *buf, size_t count) | 194 | const char *buf, size_t count) |
115 | { | 195 | { |
116 | int err; | 196 | __u32 port = 0, pdev_nr = 0, rhport = 0; |
117 | __u32 rhport = 0; | 197 | struct usb_hcd *hcd; |
198 | int ret; | ||
118 | 199 | ||
119 | if (sscanf(buf, "%u", &rhport) != 1) | 200 | if (kstrtoint(buf, 10, &port) < 0) |
120 | return -EINVAL; | 201 | return -EINVAL; |
121 | 202 | ||
122 | /* check rhport */ | 203 | pdev_nr = port_to_pdev_nr(port); |
123 | if (rhport >= VHCI_NPORTS) { | 204 | rhport = port_to_rhport(port); |
124 | dev_err(dev, "invalid port %u\n", rhport); | 205 | |
206 | if (!valid_port(pdev_nr, rhport)) | ||
125 | return -EINVAL; | 207 | return -EINVAL; |
208 | |||
209 | hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); | ||
210 | if (hcd == NULL) { | ||
211 | dev_err(dev, "port is not ready %u\n", port); | ||
212 | return -EAGAIN; | ||
126 | } | 213 | } |
127 | 214 | ||
128 | err = vhci_port_disconnect(rhport); | 215 | ret = vhci_port_disconnect(hcd_to_vhci(hcd), rhport); |
129 | if (err < 0) | 216 | if (ret < 0) |
130 | return -EINVAL; | 217 | return -EINVAL; |
131 | 218 | ||
132 | usbip_dbg_vhci_sysfs("Leave\n"); | 219 | usbip_dbg_vhci_sysfs("Leave\n"); |
@@ -135,16 +222,12 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, | |||
135 | } | 222 | } |
136 | static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); | 223 | static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); |
137 | 224 | ||
138 | /* Sysfs entry to establish a virtual connection */ | 225 | static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed) |
139 | static int valid_args(__u32 rhport, enum usb_device_speed speed) | ||
140 | { | 226 | { |
141 | /* check rhport */ | 227 | if (!valid_port(pdev_nr, rhport)) { |
142 | if (rhport >= VHCI_NPORTS) { | 228 | return 0; |
143 | pr_err("port %u\n", rhport); | ||
144 | return -EINVAL; | ||
145 | } | 229 | } |
146 | 230 | ||
147 | /* check speed */ | ||
148 | switch (speed) { | 231 | switch (speed) { |
149 | case USB_SPEED_LOW: | 232 | case USB_SPEED_LOW: |
150 | case USB_SPEED_FULL: | 233 | case USB_SPEED_FULL: |
@@ -154,12 +237,13 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed) | |||
154 | default: | 237 | default: |
155 | pr_err("Failed attach request for unsupported USB speed: %s\n", | 238 | pr_err("Failed attach request for unsupported USB speed: %s\n", |
156 | usb_speed_string(speed)); | 239 | usb_speed_string(speed)); |
157 | return -EINVAL; | 240 | return 0; |
158 | } | 241 | } |
159 | 242 | ||
160 | return 0; | 243 | return 1; |
161 | } | 244 | } |
162 | 245 | ||
246 | /* Sysfs entry to establish a virtual connection */ | ||
163 | /* | 247 | /* |
164 | * To start a new USB/IP attachment, a userland program needs to setup a TCP | 248 | * To start a new USB/IP attachment, a userland program needs to setup a TCP |
165 | * connection and then write its socket descriptor with remote device | 249 | * connection and then write its socket descriptor with remote device |
@@ -174,10 +258,12 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed) | |||
174 | static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | 258 | static ssize_t store_attach(struct device *dev, struct device_attribute *attr, |
175 | const char *buf, size_t count) | 259 | const char *buf, size_t count) |
176 | { | 260 | { |
177 | struct vhci_device *vdev; | ||
178 | struct socket *socket; | 261 | struct socket *socket; |
179 | int sockfd = 0; | 262 | int sockfd = 0; |
180 | __u32 rhport = 0, devid = 0, speed = 0; | 263 | __u32 port = 0, pdev_nr = 0, rhport = 0, devid = 0, speed = 0; |
264 | struct usb_hcd *hcd; | ||
265 | struct vhci_hcd *vhci; | ||
266 | struct vhci_device *vdev; | ||
181 | int err; | 267 | int err; |
182 | unsigned long flags; | 268 | unsigned long flags; |
183 | 269 | ||
@@ -187,16 +273,28 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
187 | * @devid: unique device identifier in a remote host | 273 | * @devid: unique device identifier in a remote host |
188 | * @speed: usb device speed in a remote host | 274 | * @speed: usb device speed in a remote host |
189 | */ | 275 | */ |
190 | if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4) | 276 | if (sscanf(buf, "%u %u %u %u", &port, &sockfd, &devid, &speed) != 4) |
191 | return -EINVAL; | 277 | return -EINVAL; |
278 | pdev_nr = port_to_pdev_nr(port); | ||
279 | rhport = port_to_rhport(port); | ||
192 | 280 | ||
193 | usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n", | 281 | usbip_dbg_vhci_sysfs("port(%u) pdev(%d) rhport(%u)\n", |
194 | rhport, sockfd, devid, speed); | 282 | port, pdev_nr, rhport); |
283 | usbip_dbg_vhci_sysfs("sockfd(%u) devid(%u) speed(%u)\n", | ||
284 | sockfd, devid, speed); | ||
195 | 285 | ||
196 | /* check received parameters */ | 286 | /* check received parameters */ |
197 | if (valid_args(rhport, speed) < 0) | 287 | if (!valid_args(pdev_nr, rhport, speed)) |
198 | return -EINVAL; | 288 | return -EINVAL; |
199 | 289 | ||
290 | hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr)); | ||
291 | if (hcd == NULL) { | ||
292 | dev_err(dev, "port %d is not ready\n", port); | ||
293 | return -EAGAIN; | ||
294 | } | ||
295 | vhci = hcd_to_vhci(hcd); | ||
296 | vdev = &vhci->vdev[rhport]; | ||
297 | |||
200 | /* Extract socket from fd. */ | 298 | /* Extract socket from fd. */ |
201 | socket = sockfd_lookup(sockfd, &err); | 299 | socket = sockfd_lookup(sockfd, &err); |
202 | if (!socket) | 300 | if (!socket) |
@@ -205,14 +303,13 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
205 | /* now need lock until setting vdev status as used */ | 303 | /* now need lock until setting vdev status as used */ |
206 | 304 | ||
207 | /* begin a lock */ | 305 | /* begin a lock */ |
208 | spin_lock_irqsave(&the_controller->lock, flags); | 306 | spin_lock_irqsave(&vhci->lock, flags); |
209 | vdev = port_to_vdev(rhport); | ||
210 | spin_lock(&vdev->ud.lock); | 307 | spin_lock(&vdev->ud.lock); |
211 | 308 | ||
212 | if (vdev->ud.status != VDEV_ST_NULL) { | 309 | if (vdev->ud.status != VDEV_ST_NULL) { |
213 | /* end of the lock */ | 310 | /* end of the lock */ |
214 | spin_unlock(&vdev->ud.lock); | 311 | spin_unlock(&vdev->ud.lock); |
215 | spin_unlock_irqrestore(&the_controller->lock, flags); | 312 | spin_unlock_irqrestore(&vhci->lock, flags); |
216 | 313 | ||
217 | sockfd_put(socket); | 314 | sockfd_put(socket); |
218 | 315 | ||
@@ -220,9 +317,10 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
220 | return -EINVAL; | 317 | return -EINVAL; |
221 | } | 318 | } |
222 | 319 | ||
223 | dev_info(dev, | 320 | dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", |
224 | "rhport(%u) sockfd(%d) devid(%u) speed(%u) speed_str(%s)\n", | 321 | pdev_nr, rhport, sockfd); |
225 | rhport, sockfd, devid, speed, usb_speed_string(speed)); | 322 | dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n", |
323 | devid, speed, usb_speed_string(speed)); | ||
226 | 324 | ||
227 | vdev->devid = devid; | 325 | vdev->devid = devid; |
228 | vdev->speed = speed; | 326 | vdev->speed = speed; |
@@ -230,26 +328,92 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
230 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | 328 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
231 | 329 | ||
232 | spin_unlock(&vdev->ud.lock); | 330 | spin_unlock(&vdev->ud.lock); |
233 | spin_unlock_irqrestore(&the_controller->lock, flags); | 331 | spin_unlock_irqrestore(&vhci->lock, flags); |
234 | /* end the lock */ | 332 | /* end the lock */ |
235 | 333 | ||
236 | vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | 334 | vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); |
237 | vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | 335 | vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); |
238 | 336 | ||
239 | rh_port_connect(rhport, speed); | 337 | rh_port_connect(vdev, speed); |
240 | 338 | ||
241 | return count; | 339 | return count; |
242 | } | 340 | } |
243 | static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach); | 341 | static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach); |
244 | 342 | ||
245 | static struct attribute *dev_attrs[] = { | 343 | #define MAX_STATUS_NAME 16 |
246 | &dev_attr_status.attr, | 344 | |
247 | &dev_attr_detach.attr, | 345 | struct status_attr { |
248 | &dev_attr_attach.attr, | 346 | struct device_attribute attr; |
249 | &dev_attr_usbip_debug.attr, | 347 | char name[MAX_STATUS_NAME+1]; |
250 | NULL, | ||
251 | }; | 348 | }; |
252 | 349 | ||
253 | const struct attribute_group dev_attr_group = { | 350 | static struct status_attr *status_attrs; |
254 | .attrs = dev_attrs, | 351 | |
352 | static void set_status_attr(int id) | ||
353 | { | ||
354 | struct status_attr *status; | ||
355 | |||
356 | status = status_attrs + id; | ||
357 | if (id == 0) | ||
358 | strcpy(status->name, "status"); | ||
359 | else | ||
360 | snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id); | ||
361 | status->attr.attr.name = status->name; | ||
362 | status->attr.attr.mode = S_IRUGO; | ||
363 | status->attr.show = status_show; | ||
364 | } | ||
365 | |||
366 | static int init_status_attrs(void) | ||
367 | { | ||
368 | int id; | ||
369 | |||
370 | status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr), | ||
371 | GFP_KERNEL); | ||
372 | if (status_attrs == NULL) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | for (id = 0; id < vhci_num_controllers; id++) | ||
376 | set_status_attr(id); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void finish_status_attrs(void) | ||
382 | { | ||
383 | kfree(status_attrs); | ||
384 | } | ||
385 | |||
386 | struct attribute_group vhci_attr_group = { | ||
387 | .attrs = NULL, | ||
255 | }; | 388 | }; |
389 | |||
390 | int vhci_init_attr_group(void) | ||
391 | { | ||
392 | struct attribute **attrs; | ||
393 | int ret, i; | ||
394 | |||
395 | attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *), | ||
396 | GFP_KERNEL); | ||
397 | if (attrs == NULL) | ||
398 | return -ENOMEM; | ||
399 | |||
400 | ret = init_status_attrs(); | ||
401 | if (ret) { | ||
402 | kfree(attrs); | ||
403 | return ret; | ||
404 | } | ||
405 | *attrs = &dev_attr_nports.attr; | ||
406 | *(attrs + 1) = &dev_attr_detach.attr; | ||
407 | *(attrs + 2) = &dev_attr_attach.attr; | ||
408 | *(attrs + 3) = &dev_attr_usbip_debug.attr; | ||
409 | for (i = 0; i < vhci_num_controllers; i++) | ||
410 | *(attrs + i + 4) = &((status_attrs + i)->attr.attr); | ||
411 | vhci_attr_group.attrs = attrs; | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | void vhci_finish_attr_group(void) | ||
416 | { | ||
417 | finish_status_attrs(); | ||
418 | kfree(vhci_attr_group.attrs); | ||
419 | } | ||
diff --git a/drivers/usb/usbip/vudc_dev.c b/drivers/usb/usbip/vudc_dev.c index 8994a13819ab..7091848df6c8 100644 --- a/drivers/usb/usbip/vudc_dev.c +++ b/drivers/usb/usbip/vudc_dev.c | |||
@@ -450,7 +450,7 @@ static void vudc_shutdown(struct usbip_device *ud) | |||
450 | if (ud->tcp_socket) | 450 | if (ud->tcp_socket) |
451 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | 451 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); |
452 | 452 | ||
453 | if (ud->tcp_tx) { | 453 | if (ud->tcp_rx) { |
454 | kthread_stop_put(ud->tcp_rx); | 454 | kthread_stop_put(ud->tcp_rx); |
455 | ud->tcp_rx = NULL; | 455 | ud->tcp_rx = NULL; |
456 | } | 456 | } |
diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c index 344bd9473475..e429b59f6f8a 100644 --- a/drivers/usb/usbip/vudc_rx.c +++ b/drivers/usb/usbip/vudc_rx.c | |||
@@ -142,7 +142,7 @@ static int v_recv_cmd_submit(struct vudc *udc, | |||
142 | urb_p->urb->status = -EINPROGRESS; | 142 | urb_p->urb->status = -EINPROGRESS; |
143 | 143 | ||
144 | /* FIXME: more pipe setup to please usbip_common */ | 144 | /* FIXME: more pipe setup to please usbip_common */ |
145 | urb_p->urb->pipe &= ~(11 << 30); | 145 | urb_p->urb->pipe &= ~(3 << 30); |
146 | switch (urb_p->ep->type) { | 146 | switch (urb_p->ep->type) { |
147 | case USB_ENDPOINT_XFER_BULK: | 147 | case USB_ENDPOINT_XFER_BULK: |
148 | urb_p->urb->pipe |= (PIPE_BULK << 30); | 148 | urb_p->urb->pipe |= (PIPE_BULK << 30); |
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index da1b872918b5..fb70cbef0671 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
@@ -610,8 +610,7 @@ static int cbaf_probe(struct usb_interface *iface, | |||
610 | cbaf->usb_iface = usb_get_intf(iface); | 610 | cbaf->usb_iface = usb_get_intf(iface); |
611 | result = cbaf_check(cbaf); | 611 | result = cbaf_check(cbaf); |
612 | if (result < 0) { | 612 | if (result < 0) { |
613 | dev_err(dev, "This device is not WUSB-CBAF compliant" | 613 | dev_err(dev, "This device is not WUSB-CBAF compliant and is not supported yet.\n"); |
614 | "and is not supported yet.\n"); | ||
615 | goto error_check; | 614 | goto error_check; |
616 | } | 615 | } |
617 | 616 | ||
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 33acd1599e99..79b2b628066d 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c | |||
@@ -229,10 +229,8 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, | |||
229 | zero_padding = sizeof(struct aes_ccm_block) - zero_padding; | 229 | zero_padding = sizeof(struct aes_ccm_block) - zero_padding; |
230 | dst_size = blen + sizeof(b0) + sizeof(b1) + zero_padding; | 230 | dst_size = blen + sizeof(b0) + sizeof(b1) + zero_padding; |
231 | dst_buf = kzalloc(dst_size, GFP_KERNEL); | 231 | dst_buf = kzalloc(dst_size, GFP_KERNEL); |
232 | if (dst_buf == NULL) { | 232 | if (!dst_buf) |
233 | printk(KERN_ERR "E: can't alloc destination buffer\n"); | ||
234 | goto error_dst_buf; | 233 | goto error_dst_buf; |
235 | } | ||
236 | 234 | ||
237 | memset(iv, 0, sizeof(iv)); | 235 | memset(iv, 0, sizeof(iv)); |
238 | 236 | ||
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index b66faaf3e842..8c9421b69da0 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c | |||
@@ -374,10 +374,8 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
374 | struct wusb_keydvt_out keydvt_out; | 374 | struct wusb_keydvt_out keydvt_out; |
375 | 375 | ||
376 | hs = kcalloc(3, sizeof(hs[0]), GFP_KERNEL); | 376 | hs = kcalloc(3, sizeof(hs[0]), GFP_KERNEL); |
377 | if (hs == NULL) { | 377 | if (!hs) |
378 | dev_err(dev, "can't allocate handshake data\n"); | ||
379 | goto error_kzalloc; | 378 | goto error_kzalloc; |
380 | } | ||
381 | 379 | ||
382 | /* We need to turn encryption before beginning the 4way | 380 | /* We need to turn encryption before beginning the 4way |
383 | * hshake (WUSB1.0[.3.2.2]) */ | 381 | * hshake (WUSB1.0[.3.2.2]) */ |
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c index 60a10d21947d..ed4622279c63 100644 --- a/drivers/usb/wusbcore/wa-nep.c +++ b/drivers/usb/wusbcore/wa-nep.c | |||
@@ -271,16 +271,11 @@ int wa_nep_create(struct wahc *wa, struct usb_interface *iface) | |||
271 | epd = &iface->cur_altsetting->endpoint[0].desc; | 271 | epd = &iface->cur_altsetting->endpoint[0].desc; |
272 | wa->nep_buffer_size = 1024; | 272 | wa->nep_buffer_size = 1024; |
273 | wa->nep_buffer = kmalloc(wa->nep_buffer_size, GFP_KERNEL); | 273 | wa->nep_buffer = kmalloc(wa->nep_buffer_size, GFP_KERNEL); |
274 | if (wa->nep_buffer == NULL) { | 274 | if (!wa->nep_buffer) |
275 | dev_err(dev, | ||
276 | "Unable to allocate notification's read buffer\n"); | ||
277 | goto error_nep_buffer; | 275 | goto error_nep_buffer; |
278 | } | ||
279 | wa->nep_urb = usb_alloc_urb(0, GFP_KERNEL); | 276 | wa->nep_urb = usb_alloc_urb(0, GFP_KERNEL); |
280 | if (wa->nep_urb == NULL) { | 277 | if (wa->nep_urb == NULL) |
281 | dev_err(dev, "Unable to allocate notification URB\n"); | ||
282 | goto error_urb_alloc; | 278 | goto error_urb_alloc; |
283 | } | ||
284 | usb_fill_int_urb(wa->nep_urb, usb_dev, | 279 | usb_fill_int_urb(wa->nep_urb, usb_dev, |
285 | usb_rcvintpipe(usb_dev, epd->bEndpointAddress), | 280 | usb_rcvintpipe(usb_dev, epd->bEndpointAddress), |
286 | wa->nep_buffer, wa->nep_buffer_size, | 281 | wa->nep_buffer, wa->nep_buffer_size, |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 69af4fd9e072..167fcc71f5f6 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -2865,10 +2865,8 @@ int wa_dti_start(struct wahc *wa) | |||
2865 | goto out; | 2865 | goto out; |
2866 | 2866 | ||
2867 | wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL); | 2867 | wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL); |
2868 | if (wa->dti_urb == NULL) { | 2868 | if (wa->dti_urb == NULL) |
2869 | dev_err(dev, "Can't allocate DTI URB\n"); | ||
2870 | goto error_dti_urb_alloc; | 2869 | goto error_dti_urb_alloc; |
2871 | } | ||
2872 | usb_fill_bulk_urb( | 2870 | usb_fill_bulk_urb( |
2873 | wa->dti_urb, wa->usb_dev, | 2871 | wa->dti_urb, wa->usb_dev, |
2874 | usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress), | 2872 | usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress), |
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 0257f35cfb9d..0aa6c3c29d17 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c | |||
@@ -701,10 +701,8 @@ static int hwarc_neep_init(struct uwb_rc *rc) | |||
701 | goto error_rd_buffer; | 701 | goto error_rd_buffer; |
702 | } | 702 | } |
703 | hwarc->neep_urb = usb_alloc_urb(0, GFP_KERNEL); | 703 | hwarc->neep_urb = usb_alloc_urb(0, GFP_KERNEL); |
704 | if (hwarc->neep_urb == NULL) { | 704 | if (hwarc->neep_urb == NULL) |
705 | dev_err(dev, "Unable to allocate notification URB\n"); | ||
706 | goto error_urb_alloc; | 705 | goto error_urb_alloc; |
707 | } | ||
708 | usb_fill_int_urb(hwarc->neep_urb, usb_dev, | 706 | usb_fill_int_urb(hwarc->neep_urb, usb_dev, |
709 | usb_rcvintpipe(usb_dev, epd->bEndpointAddress), | 707 | usb_rcvintpipe(usb_dev, epd->bEndpointAddress), |
710 | hwarc->rd_buffer, PAGE_SIZE, | 708 | hwarc->rd_buffer, PAGE_SIZE, |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 68952d9ccf83..99ebf6ea3de6 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
@@ -666,10 +666,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, | |||
666 | 666 | ||
667 | /* allocate the urb's */ | 667 | /* allocate the urb's */ |
668 | usb_pcwd->intr_urb = usb_alloc_urb(0, GFP_KERNEL); | 668 | usb_pcwd->intr_urb = usb_alloc_urb(0, GFP_KERNEL); |
669 | if (!usb_pcwd->intr_urb) { | 669 | if (!usb_pcwd->intr_urb) |
670 | pr_err("Out of memory\n"); | ||
671 | goto error; | 670 | goto error; |
672 | } | ||
673 | 671 | ||
674 | /* initialise the intr urb's */ | 672 | /* initialise the intr urb's */ |
675 | usb_fill_int_urb(usb_pcwd->intr_urb, udev, pipe, | 673 | usb_fill_int_urb(usb_pcwd->intr_urb, udev, pipe, |
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index ebd5c1fcdea4..4901fb358b07 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ | 10 | #define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ |
11 | #define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ | 11 | #define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ |
12 | #define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ | 12 | #define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ |
13 | #define BCMA_CLKCTLST_HQCLKREQ 0x00000040 /* HQ Clock */ | ||
13 | #define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */ | 14 | #define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */ |
14 | #define BCMA_CLKCTLST_EXTRESREQ_SHIFT 8 | 15 | #define BCMA_CLKCTLST_EXTRESREQ_SHIFT 8 |
15 | #define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */ | 16 | #define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */ |
diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 61004413dc64..b871c0cb1f02 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h | |||
@@ -29,6 +29,15 @@ | |||
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Define the type of supported external connectors | ||
33 | */ | ||
34 | #define EXTCON_TYPE_USB BIT(0) /* USB connector */ | ||
35 | #define EXTCON_TYPE_CHG BIT(1) /* Charger connector */ | ||
36 | #define EXTCON_TYPE_JACK BIT(2) /* Jack connector */ | ||
37 | #define EXTCON_TYPE_DISP BIT(3) /* Display connector */ | ||
38 | #define EXTCON_TYPE_MISC BIT(4) /* Miscellaneous connector */ | ||
39 | |||
40 | /* | ||
32 | * Define the unique id of supported external connectors | 41 | * Define the unique id of supported external connectors |
33 | */ | 42 | */ |
34 | #define EXTCON_NONE 0 | 43 | #define EXTCON_NONE 0 |
@@ -44,6 +53,7 @@ | |||
44 | #define EXTCON_CHG_USB_ACA 8 /* Accessory Charger Adapter */ | 53 | #define EXTCON_CHG_USB_ACA 8 /* Accessory Charger Adapter */ |
45 | #define EXTCON_CHG_USB_FAST 9 | 54 | #define EXTCON_CHG_USB_FAST 9 |
46 | #define EXTCON_CHG_USB_SLOW 10 | 55 | #define EXTCON_CHG_USB_SLOW 10 |
56 | #define EXTCON_CHG_WPT 11 /* Wireless Power Transfer */ | ||
47 | 57 | ||
48 | /* Jack external connector */ | 58 | /* Jack external connector */ |
49 | #define EXTCON_JACK_MICROPHONE 20 | 59 | #define EXTCON_JACK_MICROPHONE 20 |
@@ -60,6 +70,8 @@ | |||
60 | #define EXTCON_DISP_MHL 41 /* Mobile High-Definition Link */ | 70 | #define EXTCON_DISP_MHL 41 /* Mobile High-Definition Link */ |
61 | #define EXTCON_DISP_DVI 42 /* Digital Visual Interface */ | 71 | #define EXTCON_DISP_DVI 42 /* Digital Visual Interface */ |
62 | #define EXTCON_DISP_VGA 43 /* Video Graphics Array */ | 72 | #define EXTCON_DISP_VGA 43 /* Video Graphics Array */ |
73 | #define EXTCON_DISP_DP 44 /* Display Port */ | ||
74 | #define EXTCON_DISP_HMD 45 /* Head-Mounted Display */ | ||
63 | 75 | ||
64 | /* Miscellaneous external connector */ | 76 | /* Miscellaneous external connector */ |
65 | #define EXTCON_DOCK 60 | 77 | #define EXTCON_DOCK 60 |
@@ -68,6 +80,85 @@ | |||
68 | 80 | ||
69 | #define EXTCON_NUM 63 | 81 | #define EXTCON_NUM 63 |
70 | 82 | ||
83 | /* | ||
84 | * Define the property of supported external connectors. | ||
85 | * | ||
86 | * When adding the new extcon property, they *must* have | ||
87 | * the type/value/default information. Also, you *have to* | ||
88 | * modify the EXTCON_PROP_[type]_START/END definitions | ||
89 | * which mean the range of the supported properties | ||
90 | * for each extcon type. | ||
91 | * | ||
92 | * The naming style of property | ||
93 | * : EXTCON_PROP_[type]_[property name] | ||
94 | * | ||
95 | * EXTCON_PROP_USB_[property name] : USB property | ||
96 | * EXTCON_PROP_CHG_[property name] : Charger property | ||
97 | * EXTCON_PROP_JACK_[property name] : Jack property | ||
98 | * EXTCON_PROP_DISP_[property name] : Display property | ||
99 | */ | ||
100 | |||
101 | /* | ||
102 | * Properties of EXTCON_TYPE_USB. | ||
103 | * | ||
104 | * - EXTCON_PROP_USB_VBUS | ||
105 | * @type: integer (intval) | ||
106 | * @value: 0 (low) or 1 (high) | ||
107 | * @default: 0 (low) | ||
108 | * - EXTCON_PROP_USB_TYPEC_POLARITY | ||
109 | * @type: integer (intval) | ||
110 | * @value: 0 (normal) or 1 (flip) | ||
111 | * @default: 0 (normal) | ||
112 | * - EXTCON_PROP_USB_SS (SuperSpeed) | ||
113 | * @type: integer (intval) | ||
114 | * @value: 0 (USB/USB2) or 1 (USB3) | ||
115 | * @default: 0 (USB/USB2) | ||
116 | * | ||
117 | */ | ||
118 | #define EXTCON_PROP_USB_VBUS 0 | ||
119 | #define EXTCON_PROP_USB_TYPEC_POLARITY 1 | ||
120 | #define EXTCON_PROP_USB_SS 2 | ||
121 | |||
122 | #define EXTCON_PROP_USB_MIN 0 | ||
123 | #define EXTCON_PROP_USB_MAX 2 | ||
124 | #define EXTCON_PROP_USB_CNT (EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1) | ||
125 | |||
126 | /* Properties of EXTCON_TYPE_CHG. */ | ||
127 | #define EXTCON_PROP_CHG_MIN 50 | ||
128 | #define EXTCON_PROP_CHG_MAX 50 | ||
129 | #define EXTCON_PROP_CHG_CNT (EXTCON_PROP_CHG_MAX - EXTCON_PROP_CHG_MIN + 1) | ||
130 | |||
131 | /* Properties of EXTCON_TYPE_JACK. */ | ||
132 | #define EXTCON_PROP_JACK_MIN 100 | ||
133 | #define EXTCON_PROP_JACK_MAX 100 | ||
134 | #define EXTCON_PROP_JACK_CNT (EXTCON_PROP_JACK_MAX - EXTCON_PROP_JACK_MIN + 1) | ||
135 | |||
136 | /* | ||
137 | * Properties of EXTCON_TYPE_DISP. | ||
138 | * | ||
139 | * - EXTCON_PROP_DISP_HPD (Hot Plug Detect) | ||
140 | * @type: integer (intval) | ||
141 | * @value: 0 (no hpd) or 1 (hpd) | ||
142 | * @default: 0 (no hpd) | ||
143 | * | ||
144 | */ | ||
145 | #define EXTCON_PROP_DISP_HPD 150 | ||
146 | |||
147 | /* Properties of EXTCON_TYPE_DISP. */ | ||
148 | #define EXTCON_PROP_DISP_MIN 150 | ||
149 | #define EXTCON_PROP_DISP_MAX 151 | ||
150 | #define EXTCON_PROP_DISP_CNT (EXTCON_PROP_DISP_MAX - EXTCON_PROP_DISP_MIN + 1) | ||
151 | |||
152 | /* | ||
153 | * Define the type of property's value. | ||
154 | * | ||
155 | * Define the property's value as union type. Because each property | ||
156 | * would need the different data type to store it. | ||
157 | */ | ||
158 | union extcon_property_value { | ||
159 | int intval; /* type : integer (intval) */ | ||
160 | }; | ||
161 | |||
71 | struct extcon_cable; | 162 | struct extcon_cable; |
72 | 163 | ||
73 | /** | 164 | /** |
@@ -150,26 +241,42 @@ extern struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, | |||
150 | extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev); | 241 | extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev); |
151 | 242 | ||
152 | /* | 243 | /* |
153 | * get/set/update_state access the 32b encoded state value, which represents | 244 | * get/set_state access each bit of the 32b encoded state value. |
154 | * states of all possible cables of the multistate port. For example, if one | 245 | * They are used to access the status of each cable based on the cable id. |
155 | * calls extcon_set_state(edev, 0x7), it may mean that all the three cables | ||
156 | * are attached to the port. | ||
157 | */ | 246 | */ |
158 | static inline u32 extcon_get_state(struct extcon_dev *edev) | 247 | extern int extcon_get_state(struct extcon_dev *edev, unsigned int id); |
159 | { | 248 | extern int extcon_set_state(struct extcon_dev *edev, unsigned int id, |
160 | return edev->state; | 249 | bool cable_state); |
161 | } | 250 | extern int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, |
251 | bool cable_state); | ||
252 | /* | ||
253 | * Synchronize the state and property data for a specific external connector. | ||
254 | */ | ||
255 | extern int extcon_sync(struct extcon_dev *edev, unsigned int id); | ||
162 | 256 | ||
163 | extern int extcon_set_state(struct extcon_dev *edev, u32 state); | 257 | /* |
164 | extern int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state); | 258 | * get/set_property access the property value of each external connector. |
259 | * They are used to access the property of each cable based on the property id. | ||
260 | */ | ||
261 | extern int extcon_get_property(struct extcon_dev *edev, unsigned int id, | ||
262 | unsigned int prop, | ||
263 | union extcon_property_value *prop_val); | ||
264 | extern int extcon_set_property(struct extcon_dev *edev, unsigned int id, | ||
265 | unsigned int prop, | ||
266 | union extcon_property_value prop_val); | ||
267 | extern int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, | ||
268 | unsigned int prop, | ||
269 | union extcon_property_value prop_val); | ||
165 | 270 | ||
166 | /* | 271 | /* |
167 | * get/set_cable_state access each bit of the 32b encoded state value. | 272 | * get/set_property_capability set the capability of the property for each |
168 | * They are used to access the status of each cable based on the cable id. | 273 | * external connector. They are used to set the capability of the property |
274 | * of each external connector based on the id and property. | ||
169 | */ | 275 | */ |
170 | extern int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id); | 276 | extern int extcon_get_property_capability(struct extcon_dev *edev, |
171 | extern int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, | 277 | unsigned int id, unsigned int prop); |
172 | bool cable_state); | 278 | extern int extcon_set_property_capability(struct extcon_dev *edev, |
279 | unsigned int id, unsigned int prop); | ||
173 | 280 | ||
174 | /* | 281 | /* |
175 | * Following APIs are to monitor every action of a notifier. | 282 | * Following APIs are to monitor every action of a notifier. |
@@ -232,30 +339,57 @@ static inline struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, | |||
232 | 339 | ||
233 | static inline void devm_extcon_dev_free(struct extcon_dev *edev) { } | 340 | static inline void devm_extcon_dev_free(struct extcon_dev *edev) { } |
234 | 341 | ||
235 | static inline u32 extcon_get_state(struct extcon_dev *edev) | 342 | |
343 | static inline int extcon_get_state(struct extcon_dev *edev, unsigned int id) | ||
344 | { | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static inline int extcon_set_state(struct extcon_dev *edev, unsigned int id, | ||
349 | bool cable_state) | ||
350 | { | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static inline int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, | ||
355 | bool cable_state) | ||
236 | { | 356 | { |
237 | return 0; | 357 | return 0; |
238 | } | 358 | } |
239 | 359 | ||
240 | static inline int extcon_set_state(struct extcon_dev *edev, u32 state) | 360 | static inline int extcon_sync(struct extcon_dev *edev, unsigned int id) |
241 | { | 361 | { |
242 | return 0; | 362 | return 0; |
243 | } | 363 | } |
244 | 364 | ||
245 | static inline int extcon_update_state(struct extcon_dev *edev, u32 mask, | 365 | static inline int extcon_get_property(struct extcon_dev *edev, unsigned int id, |
246 | u32 state) | 366 | unsigned int prop, |
367 | union extcon_property_value *prop_val) | ||
368 | { | ||
369 | return 0; | ||
370 | } | ||
371 | static inline int extcon_set_property(struct extcon_dev *edev, unsigned int id, | ||
372 | unsigned int prop, | ||
373 | union extcon_property_value prop_val) | ||
247 | { | 374 | { |
248 | return 0; | 375 | return 0; |
249 | } | 376 | } |
250 | 377 | ||
251 | static inline int extcon_get_cable_state_(struct extcon_dev *edev, | 378 | static inline int extcon_set_property_sync(struct extcon_dev *edev, |
252 | unsigned int id) | 379 | unsigned int id, unsigned int prop, |
380 | union extcon_property_value prop_val) | ||
253 | { | 381 | { |
254 | return 0; | 382 | return 0; |
255 | } | 383 | } |
256 | 384 | ||
257 | static inline int extcon_set_cable_state_(struct extcon_dev *edev, | 385 | static inline int extcon_get_property_capability(struct extcon_dev *edev, |
258 | unsigned int id, bool cable_state) | 386 | unsigned int id, unsigned int prop) |
387 | { | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static inline int extcon_set_property_capability(struct extcon_dev *edev, | ||
392 | unsigned int id, unsigned int prop) | ||
259 | { | 393 | { |
260 | return 0; | 394 | return 0; |
261 | } | 395 | } |
@@ -320,4 +454,15 @@ static inline int extcon_unregister_interest(struct extcon_specific_cable_nb | |||
320 | { | 454 | { |
321 | return -EINVAL; | 455 | return -EINVAL; |
322 | } | 456 | } |
457 | |||
458 | static inline int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id) | ||
459 | { | ||
460 | return extcon_get_state(edev, id); | ||
461 | } | ||
462 | |||
463 | static inline int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, | ||
464 | bool cable_state) | ||
465 | { | ||
466 | return extcon_set_state_sync(edev, id, cable_state); | ||
467 | } | ||
323 | #endif /* __LINUX_EXTCON_H__ */ | 468 | #endif /* __LINUX_EXTCON_H__ */ |
diff --git a/include/linux/extcon/extcon-adc-jack.h b/include/linux/extcon/extcon-adc-jack.h index ac85f2061351..a0e03b13b449 100644 --- a/include/linux/extcon/extcon-adc-jack.h +++ b/include/linux/extcon/extcon-adc-jack.h | |||
@@ -20,8 +20,8 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * struct adc_jack_cond - condition to use an extcon state | 22 | * struct adc_jack_cond - condition to use an extcon state |
23 | * @state: the corresponding extcon state (if 0, this struct | ||
24 | * denotes the last adc_jack_cond element among the array) | 23 | * denotes the last adc_jack_cond element among the array) |
24 | * @id: the unique id of each external connector | ||
25 | * @min_adc: min adc value for this condition | 25 | * @min_adc: min adc value for this condition |
26 | * @max_adc: max adc value for this condition | 26 | * @max_adc: max adc value for this condition |
27 | * | 27 | * |
@@ -33,7 +33,7 @@ | |||
33 | * because when no adc_jack_cond is met, state = 0 is automatically chosen. | 33 | * because when no adc_jack_cond is met, state = 0 is automatically chosen. |
34 | */ | 34 | */ |
35 | struct adc_jack_cond { | 35 | struct adc_jack_cond { |
36 | u32 state; /* extcon state value. 0 if invalid */ | 36 | unsigned int id; |
37 | u32 min_adc; | 37 | u32 min_adc; |
38 | u32 max_adc; | 38 | u32 max_adc; |
39 | }; | 39 | }; |
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index f08b67238b58..ee1bed7dbfc6 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h | |||
@@ -36,6 +36,7 @@ enum phy_mode { | |||
36 | * @power_on: powering on the phy | 36 | * @power_on: powering on the phy |
37 | * @power_off: powering off the phy | 37 | * @power_off: powering off the phy |
38 | * @set_mode: set the mode of the phy | 38 | * @set_mode: set the mode of the phy |
39 | * @reset: resetting the phy | ||
39 | * @owner: the module owner containing the ops | 40 | * @owner: the module owner containing the ops |
40 | */ | 41 | */ |
41 | struct phy_ops { | 42 | struct phy_ops { |
@@ -44,6 +45,7 @@ struct phy_ops { | |||
44 | int (*power_on)(struct phy *phy); | 45 | int (*power_on)(struct phy *phy); |
45 | int (*power_off)(struct phy *phy); | 46 | int (*power_off)(struct phy *phy); |
46 | int (*set_mode)(struct phy *phy, enum phy_mode mode); | 47 | int (*set_mode)(struct phy *phy, enum phy_mode mode); |
48 | int (*reset)(struct phy *phy); | ||
47 | struct module *owner; | 49 | struct module *owner; |
48 | }; | 50 | }; |
49 | 51 | ||
@@ -136,6 +138,7 @@ int phy_exit(struct phy *phy); | |||
136 | int phy_power_on(struct phy *phy); | 138 | int phy_power_on(struct phy *phy); |
137 | int phy_power_off(struct phy *phy); | 139 | int phy_power_off(struct phy *phy); |
138 | int phy_set_mode(struct phy *phy, enum phy_mode mode); | 140 | int phy_set_mode(struct phy *phy, enum phy_mode mode); |
141 | int phy_reset(struct phy *phy); | ||
139 | static inline int phy_get_bus_width(struct phy *phy) | 142 | static inline int phy_get_bus_width(struct phy *phy) |
140 | { | 143 | { |
141 | return phy->attrs.bus_width; | 144 | return phy->attrs.bus_width; |
diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h index 388f6e08b9d4..a7af21a55248 100644 --- a/include/linux/ulpi/driver.h +++ b/include/linux/ulpi/driver.h | |||
@@ -15,7 +15,7 @@ struct ulpi_ops; | |||
15 | */ | 15 | */ |
16 | struct ulpi { | 16 | struct ulpi { |
17 | struct ulpi_device_id id; | 17 | struct ulpi_device_id id; |
18 | struct ulpi_ops *ops; | 18 | const struct ulpi_ops *ops; |
19 | struct device dev; | 19 | struct device dev; |
20 | }; | 20 | }; |
21 | 21 | ||
@@ -47,7 +47,11 @@ struct ulpi_driver { | |||
47 | 47 | ||
48 | #define to_ulpi_driver(d) container_of(d, struct ulpi_driver, driver) | 48 | #define to_ulpi_driver(d) container_of(d, struct ulpi_driver, driver) |
49 | 49 | ||
50 | int ulpi_register_driver(struct ulpi_driver *drv); | 50 | /* |
51 | * use a macro to avoid include chaining to get THIS_MODULE | ||
52 | */ | ||
53 | #define ulpi_register_driver(drv) __ulpi_register_driver(drv, THIS_MODULE) | ||
54 | int __ulpi_register_driver(struct ulpi_driver *drv, struct module *module); | ||
51 | void ulpi_unregister_driver(struct ulpi_driver *drv); | 55 | void ulpi_unregister_driver(struct ulpi_driver *drv); |
52 | 56 | ||
53 | #define module_ulpi_driver(__ulpi_driver) \ | 57 | #define module_ulpi_driver(__ulpi_driver) \ |
diff --git a/include/linux/ulpi/interface.h b/include/linux/ulpi/interface.h index 4de8ab491038..a2011a919eb6 100644 --- a/include/linux/ulpi/interface.h +++ b/include/linux/ulpi/interface.h | |||
@@ -4,20 +4,19 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | struct ulpi; | 6 | struct ulpi; |
7 | struct device; | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * struct ulpi_ops - ULPI register access | 10 | * struct ulpi_ops - ULPI register access |
10 | * @dev: the interface provider | ||
11 | * @read: read operation for ULPI register access | 11 | * @read: read operation for ULPI register access |
12 | * @write: write operation for ULPI register access | 12 | * @write: write operation for ULPI register access |
13 | */ | 13 | */ |
14 | struct ulpi_ops { | 14 | struct ulpi_ops { |
15 | struct device *dev; | 15 | int (*read)(struct device *dev, u8 addr); |
16 | int (*read)(struct ulpi_ops *ops, u8 addr); | 16 | int (*write)(struct device *dev, u8 addr, u8 val); |
17 | int (*write)(struct ulpi_ops *ops, u8 addr, u8 val); | ||
18 | }; | 17 | }; |
19 | 18 | ||
20 | struct ulpi *ulpi_register_interface(struct device *, struct ulpi_ops *); | 19 | struct ulpi *ulpi_register_interface(struct device *, const struct ulpi_ops *); |
21 | void ulpi_unregister_interface(struct ulpi *); | 20 | void ulpi_unregister_interface(struct ulpi *); |
22 | 21 | ||
23 | #endif /* __LINUX_ULPI_INTERFACE_H */ | 22 | #endif /* __LINUX_ULPI_INTERFACE_H */ |
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 2b81b24eb5aa..4616a49a1c2e 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
@@ -220,7 +220,8 @@ struct usb_function { | |||
220 | int (*setup)(struct usb_function *, | 220 | int (*setup)(struct usb_function *, |
221 | const struct usb_ctrlrequest *); | 221 | const struct usb_ctrlrequest *); |
222 | bool (*req_match)(struct usb_function *, | 222 | bool (*req_match)(struct usb_function *, |
223 | const struct usb_ctrlrequest *); | 223 | const struct usb_ctrlrequest *, |
224 | bool config0); | ||
224 | void (*suspend)(struct usb_function *); | 225 | void (*suspend)(struct usb_function *); |
225 | void (*resume)(struct usb_function *); | 226 | void (*resume)(struct usb_function *); |
226 | 227 | ||
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 612dbdfa388e..8e81f9eb95e4 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -346,6 +346,8 @@ struct usb_gadget_ops { | |||
346 | * or B-Peripheral wants to take host role. | 346 | * or B-Peripheral wants to take host role. |
347 | * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to | 347 | * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to |
348 | * MaxPacketSize. | 348 | * MaxPacketSize. |
349 | * @quirk_avoids_skb_reserve: udc/platform wants to avoid skb_reserve() in | ||
350 | * u_ether.c to improve performance. | ||
349 | * @is_selfpowered: if the gadget is self-powered. | 351 | * @is_selfpowered: if the gadget is self-powered. |
350 | * @deactivated: True if gadget is deactivated - in deactivated state it cannot | 352 | * @deactivated: True if gadget is deactivated - in deactivated state it cannot |
351 | * be connected. | 353 | * be connected. |
@@ -398,6 +400,7 @@ struct usb_gadget { | |||
398 | unsigned quirk_altset_not_supp:1; | 400 | unsigned quirk_altset_not_supp:1; |
399 | unsigned quirk_stall_not_supp:1; | 401 | unsigned quirk_stall_not_supp:1; |
400 | unsigned quirk_zlp_not_supp:1; | 402 | unsigned quirk_zlp_not_supp:1; |
403 | unsigned quirk_avoids_skb_reserve:1; | ||
401 | unsigned is_selfpowered:1; | 404 | unsigned is_selfpowered:1; |
402 | unsigned deactivated:1; | 405 | unsigned deactivated:1; |
403 | unsigned connected:1; | 406 | unsigned connected:1; |
@@ -418,8 +421,20 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) | |||
418 | list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) | 421 | list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) |
419 | 422 | ||
420 | /** | 423 | /** |
424 | * usb_ep_align - returns @len aligned to ep's maxpacketsize. | ||
425 | * @ep: the endpoint whose maxpacketsize is used to align @len | ||
426 | * @len: buffer size's length to align to @ep's maxpacketsize | ||
427 | * | ||
428 | * This helper is used to align buffer's size to an ep's maxpacketsize. | ||
429 | */ | ||
430 | static inline size_t usb_ep_align(struct usb_ep *ep, size_t len) | ||
431 | { | ||
432 | return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize)); | ||
433 | } | ||
434 | |||
435 | /** | ||
421 | * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget | 436 | * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget |
422 | * requires quirk_ep_out_aligned_size, otherwise reguens len. | 437 | * requires quirk_ep_out_aligned_size, otherwise returns len. |
423 | * @g: controller to check for quirk | 438 | * @g: controller to check for quirk |
424 | * @ep: the endpoint whose maxpacketsize is used to align @len | 439 | * @ep: the endpoint whose maxpacketsize is used to align @len |
425 | * @len: buffer size's length to align to @ep's maxpacketsize | 440 | * @len: buffer size's length to align to @ep's maxpacketsize |
@@ -430,8 +445,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) | |||
430 | static inline size_t | 445 | static inline size_t |
431 | usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len) | 446 | usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len) |
432 | { | 447 | { |
433 | return !g->quirk_ep_out_aligned_size ? len : | 448 | return g->quirk_ep_out_aligned_size ? usb_ep_align(ep, len) : len; |
434 | round_up(len, (size_t)ep->desc->wMaxPacketSize); | ||
435 | } | 449 | } |
436 | 450 | ||
437 | /** | 451 | /** |
@@ -463,6 +477,16 @@ static inline int gadget_is_zlp_supported(struct usb_gadget *g) | |||
463 | } | 477 | } |
464 | 478 | ||
465 | /** | 479 | /** |
480 | * gadget_avoids_skb_reserve - return true iff the hardware would like to avoid | ||
481 | * skb_reserve to improve performance. | ||
482 | * @g: controller to check for quirk | ||
483 | */ | ||
484 | static inline int gadget_avoids_skb_reserve(struct usb_gadget *g) | ||
485 | { | ||
486 | return g->quirk_avoids_skb_reserve; | ||
487 | } | ||
488 | |||
489 | /** | ||
466 | * gadget_is_dualspeed - return true iff the hardware handles high speed | 490 | * gadget_is_dualspeed - return true iff the hardware handles high speed |
467 | * @g: controller that might support both high and full speeds | 491 | * @g: controller that might support both high and full speeds |
468 | */ | 492 | */ |
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 245f57dbbb61..0aae1b2ee931 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h | |||
@@ -81,6 +81,8 @@ | |||
81 | /* Sets max_sectors to 240 */ \ | 81 | /* Sets max_sectors to 240 */ \ |
82 | US_FLAG(NO_REPORT_LUNS, 0x10000000) \ | 82 | US_FLAG(NO_REPORT_LUNS, 0x10000000) \ |
83 | /* Cannot handle REPORT_LUNS */ \ | 83 | /* Cannot handle REPORT_LUNS */ \ |
84 | US_FLAG(ALWAYS_SYNC, 0x20000000) \ | ||
85 | /* lies about caching, so always sync */ \ | ||
84 | 86 | ||
85 | #define US_FLAG(name, value) US_FL_##name = value , | 87 | #define US_FLAG(name, value) US_FL_##name = value , |
86 | enum { US_DO_ALL_FLAGS }; | 88 | enum { US_DO_ALL_FLAGS }; |
diff --git a/include/soc/at91/atmel-sfr.h b/include/soc/at91/atmel-sfr.h index 2f9bb984a4df..506ea8ffda19 100644 --- a/include/soc/at91/atmel-sfr.h +++ b/include/soc/at91/atmel-sfr.h | |||
@@ -13,6 +13,20 @@ | |||
13 | #ifndef _LINUX_MFD_SYSCON_ATMEL_SFR_H | 13 | #ifndef _LINUX_MFD_SYSCON_ATMEL_SFR_H |
14 | #define _LINUX_MFD_SYSCON_ATMEL_SFR_H | 14 | #define _LINUX_MFD_SYSCON_ATMEL_SFR_H |
15 | 15 | ||
16 | #define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */ | ||
17 | /* 0x08 ~ 0x0c: Reserved */ | ||
18 | #define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */ | ||
19 | #define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */ | ||
16 | #define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */ | 20 | #define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */ |
17 | 21 | ||
22 | /* Field definitions */ | ||
23 | #define AT91_OHCIICR_SUSPEND_A BIT(8) | ||
24 | #define AT91_OHCIICR_SUSPEND_B BIT(9) | ||
25 | #define AT91_OHCIICR_SUSPEND_C BIT(10) | ||
26 | |||
27 | #define AT91_OHCIICR_USB_SUSPEND (AT91_OHCIICR_SUSPEND_A | \ | ||
28 | AT91_OHCIICR_SUSPEND_B | \ | ||
29 | AT91_OHCIICR_SUSPEND_C) | ||
30 | |||
31 | |||
18 | #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */ | 32 | #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */ |
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index 108dd7997014..acc63697a0cc 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h | |||
@@ -21,6 +21,8 @@ enum functionfs_flags { | |||
21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, | 21 | FUNCTIONFS_HAS_MS_OS_DESC = 8, |
22 | FUNCTIONFS_VIRTUAL_ADDR = 16, | 22 | FUNCTIONFS_VIRTUAL_ADDR = 16, |
23 | FUNCTIONFS_EVENTFD = 32, | 23 | FUNCTIONFS_EVENTFD = 32, |
24 | FUNCTIONFS_ALL_CTRL_RECIP = 64, | ||
25 | FUNCTIONFS_CONFIG0_SETUP = 128, | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | /* Descriptor of an non-audio endpoint */ | 28 | /* Descriptor of an non-audio endpoint */ |