diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 20:06:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-01 20:06:09 -0400 |
commit | 3e75c6de1ac33fe3500f44573d9212dc82c99f59 (patch) | |
tree | ef10932e204ba8a9885051b06d4524d284207d61 | |
parent | cb1595563880a81dab6eab9a5ecb4520d2e76077 (diff) | |
parent | 940ab8f1ef9369da5b58a1bec6820bfd4a7b9042 (diff) |
Merge tag 'usb-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg KH:
"Here's the big USB pull request for 3.15-rc1.
The normal set of patches, lots of controller driver updates, and a
smattering of individual USB driver updates as well.
All have been in linux-next for a while"
* tag 'usb-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (249 commits)
xhci: Transition maintainership to Mathias Nyman.
USB: disable reset-resume when USB_QUIRK_RESET is set
USB: unbind all interfaces before rebinding any
usb: phy: Add ulpi IDs for SMSC USB3320 and TI TUSB1210
usb: gadget: tcm_usb_gadget: stop format strings
usb: gadget: f_fs: add missing spinlock and mutex unlock
usb: gadget: composite: switch over to ERR_CAST()
usb: gadget: inode: switch over to memdup_user()
usb: gadget: f_subset: switch over to PTR_RET
usb: gadget: lpc32xx_udc: fix wrong clk_put() sequence
USB: keyspan: remove dead debugging code
USB: serial: add missing newlines to dev_<level> messages.
USB: serial: add missing braces
USB: serial: continue to write on errors
USB: serial: continue to read on errors
USB: serial: make bulk_out_size a lower limit
USB: cypress_m8: fix potential scheduling while atomic
devicetree: bindings: document lsi,zevio-usb
usb: chipidea: add support for USB OTG controller on LSI Zevio SoCs
usb: chipidea: imx: Use dev_name() for ci_hdrc name to distinguish USBs
...
156 files changed, 9148 insertions, 2183 deletions
diff --git a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt new file mode 100644 index 000000000000..5f3a65a9dd88 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt | |||
@@ -0,0 +1,79 @@ | |||
1 | * APM X-Gene 15Gbps Multi-purpose PHY nodes | ||
2 | |||
3 | PHY nodes are defined to describe on-chip 15Gbps Multi-purpose PHY. Each | ||
4 | PHY (pair of lanes) has its own node. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : Shall be "apm,xgene-phy". | ||
8 | - reg : PHY memory resource is the SDS PHY access resource. | ||
9 | - #phy-cells : Shall be 1 as it expects one argument for setting | ||
10 | the mode of the PHY. Possible values are 0 (SATA), | ||
11 | 1 (SGMII), 2 (PCIe), 3 (USB), and 4 (XFI). | ||
12 | |||
13 | Optional properties: | ||
14 | - status : Shall be "ok" if enabled or "disabled" if disabled. | ||
15 | Default is "ok". | ||
16 | - clocks : Reference to the clock entry. | ||
17 | - apm,tx-eye-tuning : Manual control to fine tune the capture of the serial | ||
18 | bit lines from the automatic calibrated position. | ||
19 | Two set of 3-tuple setting for each (up to 3) | ||
20 | supported link speed on the host. Range from 0 to | ||
21 | 127 in unit of one bit period. Default is 10. | ||
22 | - apm,tx-eye-direction : Eye tuning manual control direction. 0 means sample | ||
23 | data earlier than the nominal sampling point. 1 means | ||
24 | sample data later than the nominal sampling point. | ||
25 | Two set of 3-tuple setting for each (up to 3) | ||
26 | supported link speed on the host. Default is 0. | ||
27 | - apm,tx-boost-gain : Frequency boost AC (LSB 3-bit) and DC (2-bit) | ||
28 | gain control. Two set of 3-tuple setting for each | ||
29 | (up to 3) supported link speed on the host. Range is | ||
30 | between 0 to 31 in unit of dB. Default is 3. | ||
31 | - apm,tx-amplitude : Amplitude control. Two set of 3-tuple setting for | ||
32 | each (up to 3) supported link speed on the host. | ||
33 | Range is between 0 to 199500 in unit of uV. | ||
34 | Default is 199500 uV. | ||
35 | - apm,tx-pre-cursor1 : 1st pre-cursor emphasis taps control. Two set of | ||
36 | 3-tuple setting for each (up to 3) supported link | ||
37 | speed on the host. Range is 0 to 273000 in unit of | ||
38 | uV. Default is 0. | ||
39 | - apm,tx-pre-cursor2 : 2st pre-cursor emphasis taps control. Two set of | ||
40 | 3-tuple setting for each (up to 3) supported link | ||
41 | speed on the host. Range is 0 to 127400 in unit uV. | ||
42 | Default is 0x0. | ||
43 | - apm,tx-post-cursor : Post-cursor emphasis taps control. Two set of | ||
44 | 3-tuple setting for Gen1, Gen2, and Gen3. Range is | ||
45 | between 0 to 0x1f in unit of 18.2mV. Default is 0xf. | ||
46 | - apm,tx-speed : Tx operating speed. One set of 3-tuple for each | ||
47 | supported link speed on the host. | ||
48 | 0 = 1-2Gbps | ||
49 | 1 = 2-4Gbps (1st tuple default) | ||
50 | 2 = 4-8Gbps | ||
51 | 3 = 8-15Gbps (2nd tuple default) | ||
52 | 4 = 2.5-4Gbps | ||
53 | 5 = 4-5Gbps | ||
54 | 6 = 5-6Gbps | ||
55 | 7 = 6-16Gbps (3rd tuple default) | ||
56 | |||
57 | NOTE: PHY override parameters are board specific setting. | ||
58 | |||
59 | Example: | ||
60 | phy1: phy@1f21a000 { | ||
61 | compatible = "apm,xgene-phy"; | ||
62 | reg = <0x0 0x1f21a000 0x0 0x100>; | ||
63 | #phy-cells = <1>; | ||
64 | status = "disabled"; | ||
65 | }; | ||
66 | |||
67 | phy2: phy@1f22a000 { | ||
68 | compatible = "apm,xgene-phy"; | ||
69 | reg = <0x0 0x1f22a000 0x0 0x100>; | ||
70 | #phy-cells = <1>; | ||
71 | status = "ok"; | ||
72 | }; | ||
73 | |||
74 | phy3: phy@1f23a000 { | ||
75 | compatible = "apm,xgene-phy"; | ||
76 | reg = <0x0 0x1f23a000 0x0 0x100>; | ||
77 | #phy-cells = <1>; | ||
78 | status = "ok"; | ||
79 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index c0fccaa1671e..28f9edb8f19c 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt | |||
@@ -20,3 +20,57 @@ Required properties: | |||
20 | - compatible : should be "samsung,exynos5250-dp-video-phy"; | 20 | - compatible : should be "samsung,exynos5250-dp-video-phy"; |
21 | - reg : offset and length of the Display Port PHY register set; | 21 | - reg : offset and length of the Display Port PHY register set; |
22 | - #phy-cells : from the generic PHY bindings, must be 0; | 22 | - #phy-cells : from the generic PHY bindings, must be 0; |
23 | |||
24 | Samsung S5P/EXYNOS SoC series USB PHY | ||
25 | ------------------------------------------------- | ||
26 | |||
27 | Required properties: | ||
28 | - compatible : should be one of the listed compatibles: | ||
29 | - "samsung,exynos4210-usb2-phy" | ||
30 | - "samsung,exynos4x12-usb2-phy" | ||
31 | - "samsung,exynos5250-usb2-phy" | ||
32 | - reg : a list of registers used by phy driver | ||
33 | - first and obligatory is the location of phy modules registers | ||
34 | - samsung,sysreg-phandle - handle to syscon used to control the system registers | ||
35 | - samsung,pmureg-phandle - handle to syscon used to control PMU registers | ||
36 | - #phy-cells : from the generic phy bindings, must be 1; | ||
37 | - clocks and clock-names: | ||
38 | - the "phy" clock is required by the phy module, used as a gate | ||
39 | - the "ref" clock is used to get the rate of the clock provided to the | ||
40 | PHY module | ||
41 | |||
42 | The first phandle argument in the PHY specifier identifies the PHY, its | ||
43 | meaning is compatible dependent. For the currently supported SoCs (Exynos 4210 | ||
44 | and Exynos 4212) it is as follows: | ||
45 | 0 - USB device ("device"), | ||
46 | 1 - USB host ("host"), | ||
47 | 2 - HSIC0 ("hsic0"), | ||
48 | 3 - HSIC1 ("hsic1"), | ||
49 | |||
50 | Exynos 4210 and Exynos 4212 use mode switching and require that mode switch | ||
51 | register is supplied. | ||
52 | |||
53 | Example: | ||
54 | |||
55 | For Exynos 4412 (compatible with Exynos 4212): | ||
56 | |||
57 | usbphy: phy@125b0000 { | ||
58 | compatible = "samsung,exynos4x12-usb2-phy"; | ||
59 | reg = <0x125b0000 0x100>; | ||
60 | clocks = <&clock 305>, <&clock 2>; | ||
61 | clock-names = "phy", "ref"; | ||
62 | status = "okay"; | ||
63 | #phy-cells = <1>; | ||
64 | samsung,sysreg-phandle = <&sys_reg>; | ||
65 | samsung,pmureg-phandle = <&pmu_reg>; | ||
66 | }; | ||
67 | |||
68 | Then the PHY can be used in other nodes such as: | ||
69 | |||
70 | phy-consumer@12340000 { | ||
71 | phys = <&usbphy 2>; | ||
72 | phy-names = "phy"; | ||
73 | }; | ||
74 | |||
75 | Refer to DT bindings documentation of particular PHY consumer devices for more | ||
76 | information about required PHYs and the way of specification. | ||
diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt new file mode 100644 index 000000000000..a82361b62015 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | Allwinner sun4i USB PHY | ||
2 | ----------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible : should be one of "allwinner,sun4i-a10-usb-phy", | ||
6 | "allwinner,sun5i-a13-usb-phy" or "allwinner,sun7i-a20-usb-phy" | ||
7 | - reg : a list of offset + length pairs | ||
8 | - reg-names : "phy_ctrl", "pmu1" and for sun4i or sun7i "pmu2" | ||
9 | - #phy-cells : from the generic phy bindings, must be 1 | ||
10 | - clocks : phandle + clock specifier for the phy clock | ||
11 | - clock-names : "usb_phy" | ||
12 | - resets : a list of phandle + reset specifier pairs | ||
13 | - reset-names : "usb0_reset", "usb1_reset" and for sun4i or sun7i "usb2_reset" | ||
14 | |||
15 | Example: | ||
16 | usbphy: phy@0x01c13400 { | ||
17 | #phy-cells = <1>; | ||
18 | compatible = "allwinner,sun4i-a10-usb-phy"; | ||
19 | /* phy base regs, phy1 pmu reg, phy2 pmu reg */ | ||
20 | reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>; | ||
21 | reg-names = "phy_ctrl", "pmu1", "pmu2"; | ||
22 | clocks = <&usb_clk 8>; | ||
23 | clock-names = "usb_phy"; | ||
24 | resets = <&usb_clk 1>, <&usb_clk 2>; | ||
25 | reset-names = "usb1_reset", "usb2_reset"; | ||
26 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt new file mode 100644 index 000000000000..788fb0fa3762 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt | |||
@@ -0,0 +1,86 @@ | |||
1 | TI PHY: DT DOCUMENTATION FOR PHYs in TI PLATFORMs | ||
2 | |||
3 | OMAP CONTROL PHY | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: Should be one of | ||
7 | "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. | ||
8 | "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register | ||
9 | e.g. USB2_PHY on OMAP5. | ||
10 | "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control | ||
11 | e.g. USB3 PHY and SATA PHY on OMAP5. | ||
12 | "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on | ||
13 | DRA7 platform. | ||
14 | "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on | ||
15 | AM437 platform. | ||
16 | - reg : Address and length of the register set for the device. It contains | ||
17 | the address of "otghs_control" for control-phy-otghs or "power" register | ||
18 | for other types. | ||
19 | - reg-names: should be "otghs_control" control-phy-otghs and "power" for | ||
20 | other types. | ||
21 | |||
22 | omap_control_usb: omap-control-usb@4a002300 { | ||
23 | compatible = "ti,control-phy-otghs"; | ||
24 | reg = <0x4a00233c 0x4>; | ||
25 | reg-names = "otghs_control"; | ||
26 | }; | ||
27 | |||
28 | OMAP USB2 PHY | ||
29 | |||
30 | Required properties: | ||
31 | - compatible: Should be "ti,omap-usb2" | ||
32 | - reg : Address and length of the register set for the device. | ||
33 | - #phy-cells: determine the number of cells that should be given in the | ||
34 | phandle while referencing this phy. | ||
35 | |||
36 | Optional properties: | ||
37 | - ctrl-module : phandle of the control module used by PHY driver to power on | ||
38 | the PHY. | ||
39 | |||
40 | This is usually a subnode of ocp2scp to which it is connected. | ||
41 | |||
42 | usb2phy@4a0ad080 { | ||
43 | compatible = "ti,omap-usb2"; | ||
44 | reg = <0x4a0ad080 0x58>; | ||
45 | ctrl-module = <&omap_control_usb>; | ||
46 | #phy-cells = <0>; | ||
47 | }; | ||
48 | |||
49 | TI PIPE3 PHY | ||
50 | |||
51 | Required properties: | ||
52 | - compatible: Should be "ti,phy-usb3" or "ti,phy-pipe3-sata". | ||
53 | "ti,omap-usb3" is deprecated. | ||
54 | - reg : Address and length of the register set for the device. | ||
55 | - reg-names: The names of the register addresses corresponding to the registers | ||
56 | filled in "reg". | ||
57 | - #phy-cells: determine the number of cells that should be given in the | ||
58 | phandle while referencing this phy. | ||
59 | - clocks: a list of phandles and clock-specifier pairs, one for each entry in | ||
60 | clock-names. | ||
61 | - clock-names: should include: | ||
62 | * "wkupclk" - wakeup clock. | ||
63 | * "sysclk" - system clock. | ||
64 | * "refclk" - reference clock. | ||
65 | |||
66 | Optional properties: | ||
67 | - ctrl-module : phandle of the control module used by PHY driver to power on | ||
68 | the PHY. | ||
69 | |||
70 | This is usually a subnode of ocp2scp to which it is connected. | ||
71 | |||
72 | usb3phy@4a084400 { | ||
73 | compatible = "ti,phy-usb3"; | ||
74 | reg = <0x4a084400 0x80>, | ||
75 | <0x4a084800 0x64>, | ||
76 | <0x4a084c00 0x40>; | ||
77 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; | ||
78 | ctrl-module = <&omap_control_usb>; | ||
79 | #phy-cells = <0>; | ||
80 | clocks = <&usb_phy_cm_clk32k>, | ||
81 | <&sys_clkin>, | ||
82 | <&usb_otg_ss_refclk960m>; | ||
83 | clock-names = "wkupclk", | ||
84 | "sysclk", | ||
85 | "refclk"; | ||
86 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt index b4b5b7906c88..a6a32cb7f777 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt | |||
@@ -18,6 +18,7 @@ Optional properties: | |||
18 | - vbus-supply: regulator for vbus | 18 | - vbus-supply: regulator for vbus |
19 | - disable-over-current: disable over current detect | 19 | - disable-over-current: disable over current detect |
20 | - external-vbus-divider: enables off-chip resistor divider for Vbus | 20 | - external-vbus-divider: enables off-chip resistor divider for Vbus |
21 | - maximum-speed: limit the maximum connection speed to "full-speed". | ||
21 | 22 | ||
22 | Examples: | 23 | Examples: |
23 | usb@02184000 { /* USB OTG */ | 24 | usb@02184000 { /* USB OTG */ |
@@ -28,4 +29,5 @@ usb@02184000 { /* USB OTG */ | |||
28 | fsl,usbmisc = <&usbmisc 0>; | 29 | fsl,usbmisc = <&usbmisc 0>; |
29 | disable-over-current; | 30 | disable-over-current; |
30 | external-vbus-divider; | 31 | external-vbus-divider; |
32 | maximum-speed = "full-speed"; | ||
31 | }; | 33 | }; |
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt new file mode 100644 index 000000000000..abbcb2aea38c --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | * LSI Zevio USB OTG Controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "lsi,zevio-usb" | ||
5 | - reg: Should contain registers location and length | ||
6 | - interrupts: Should contain controller interrupt | ||
7 | |||
8 | Optional properties: | ||
9 | - vbus-supply: regulator for vbus | ||
10 | |||
11 | Examples: | ||
12 | usb0: usb@b0000000 { | ||
13 | reg = <0xb0000000 0x1000>; | ||
14 | compatible = "lsi,zevio-usb"; | ||
15 | interrupts = <8>; | ||
16 | vbus-supply = <&vbus_reg>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index e807635f9e1c..471366d6a129 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt | |||
@@ -6,11 +6,13 @@ Required properties: | |||
6 | - compatible: must be "snps,dwc3" | 6 | - compatible: must be "snps,dwc3" |
7 | - reg : Address and length of the register set for the device | 7 | - reg : Address and length of the register set for the device |
8 | - interrupts: Interrupts used by the dwc3 controller. | 8 | - interrupts: Interrupts used by the dwc3 controller. |
9 | |||
10 | Optional properties: | ||
9 | - usb-phy : array of phandle for the PHY device. The first element | 11 | - usb-phy : array of phandle for the PHY device. The first element |
10 | in the array is expected to be a handle to the USB2/HS PHY and | 12 | in the array is expected to be a handle to the USB2/HS PHY and |
11 | the second element is expected to be a handle to the USB3/SS PHY | 13 | the second element is expected to be a handle to the USB3/SS PHY |
12 | 14 | - phys: from the *Generic PHY* bindings | |
13 | Optional properties: | 15 | - phy-names: from the *Generic PHY* bindings |
14 | - tx-fifo-resize: determines if the FIFO *has* to be reallocated. | 16 | - tx-fifo-resize: determines if the FIFO *has* to be reallocated. |
15 | 17 | ||
16 | This is usually a subnode to DWC3 glue to which it is connected. | 18 | This is usually a subnode to DWC3 glue to which it is connected. |
diff --git a/Documentation/devicetree/bindings/usb/mxs-phy.txt b/Documentation/devicetree/bindings/usb/mxs-phy.txt index 5835b27146ea..cef181a9d8bd 100644 --- a/Documentation/devicetree/bindings/usb/mxs-phy.txt +++ b/Documentation/devicetree/bindings/usb/mxs-phy.txt | |||
@@ -1,13 +1,19 @@ | |||
1 | * Freescale MXS USB Phy Device | 1 | * Freescale MXS USB Phy Device |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: Should be "fsl,imx23-usbphy" | 4 | - compatible: should contain: |
5 | * "fsl,imx23-usbphy" for imx23 and imx28 | ||
6 | * "fsl,imx6q-usbphy" for imx6dq and imx6dl | ||
7 | * "fsl,imx6sl-usbphy" for imx6sl | ||
8 | "fsl,imx23-usbphy" is still a fallback for other strings | ||
5 | - reg: Should contain registers location and length | 9 | - reg: Should contain registers location and length |
6 | - interrupts: Should contain phy interrupt | 10 | - interrupts: Should contain phy interrupt |
11 | - fsl,anatop: phandle for anatop register, it is only for imx6 SoC series | ||
7 | 12 | ||
8 | Example: | 13 | Example: |
9 | usbphy1: usbphy@020c9000 { | 14 | usbphy1: usbphy@020c9000 { |
10 | compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; | 15 | compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; |
11 | reg = <0x020c9000 0x1000>; | 16 | reg = <0x020c9000 0x1000>; |
12 | interrupts = <0 44 0x04>; | 17 | interrupts = <0 44 0x04>; |
18 | fsl,anatop = <&anatop>; | ||
13 | }; | 19 | }; |
diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index c495135115cb..38b2faec4199 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt | |||
@@ -76,27 +76,3 @@ omap_dwc3 { | |||
76 | ranges; | 76 | ranges; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | OMAP CONTROL USB | ||
80 | |||
81 | Required properties: | ||
82 | - compatible: Should be one of | ||
83 | "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. | ||
84 | "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register | ||
85 | e.g. USB2_PHY on OMAP5. | ||
86 | "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control | ||
87 | e.g. USB3 PHY and SATA PHY on OMAP5. | ||
88 | "ti,control-phy-dra7usb2" - if it has power down register like USB2 PHY on | ||
89 | DRA7 platform. | ||
90 | "ti,control-phy-am437usb2" - if it has power down register like USB2 PHY on | ||
91 | AM437 platform. | ||
92 | - reg : Address and length of the register set for the device. It contains | ||
93 | the address of "otghs_control" for control-phy-otghs or "power" register | ||
94 | for other types. | ||
95 | - reg-names: should be "otghs_control" control-phy-otghs and "power" for | ||
96 | other types. | ||
97 | |||
98 | omap_control_usb: omap-control-usb@4a002300 { | ||
99 | compatible = "ti,control-phy-otghs"; | ||
100 | reg = <0x4a00233c 0x4>; | ||
101 | reg-names = "otghs_control"; | ||
102 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index fa18612f757b..ff151ec084c4 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt | |||
@@ -1,19 +1,20 @@ | |||
1 | USB EHCI controllers | 1 | USB EHCI controllers |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible : should be "usb-ehci". | 4 | - compatible : should be "generic-ehci". |
5 | - reg : should contain at least address and length of the standard EHCI | 5 | - reg : should contain at least address and length of the standard EHCI |
6 | register set for the device. Optional platform-dependent registers | 6 | register set for the device. Optional platform-dependent registers |
7 | (debug-port or other) can be also specified here, but only after | 7 | (debug-port or other) can be also specified here, but only after |
8 | definition of standard EHCI registers. | 8 | definition of standard EHCI registers. |
9 | - interrupts : one EHCI interrupt should be described here. | 9 | - interrupts : one EHCI interrupt should be described here. |
10 | If device registers are implemented in big endian mode, the device | 10 | |
11 | node should have "big-endian-regs" property. | 11 | Optional properties: |
12 | If controller implementation operates with big endian descriptors, | 12 | - big-endian-regs : boolean, set this for hcds with big-endian registers |
13 | "big-endian-desc" property should be specified. | 13 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors |
14 | If both big endian registers and descriptors are used by the controller | 14 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc |
15 | implementation, "big-endian" property can be specified instead of having | 15 | - clocks : a list of phandle + clock specifier pairs |
16 | both "big-endian-regs" and "big-endian-desc". | 16 | - phys : phandle + phy specifier pair |
17 | - phy-names : "usb" | ||
17 | 18 | ||
18 | Example (Sequoia 440EPx): | 19 | Example (Sequoia 440EPx): |
19 | ehci@e0000300 { | 20 | ehci@e0000300 { |
@@ -23,3 +24,13 @@ Example (Sequoia 440EPx): | |||
23 | reg = <0 e0000300 90 0 e0000390 70>; | 24 | reg = <0 e0000300 90 0 e0000390 70>; |
24 | big-endian; | 25 | big-endian; |
25 | }; | 26 | }; |
27 | |||
28 | Example (Allwinner sun4i A10 SoC): | ||
29 | ehci0: usb@01c14000 { | ||
30 | compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; | ||
31 | reg = <0x01c14000 0x100>; | ||
32 | interrupts = <39>; | ||
33 | clocks = <&ahb_gates 1>; | ||
34 | phys = <&usbphy 1>; | ||
35 | phy-names = "usb"; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt new file mode 100644 index 000000000000..45f67d91e888 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | USB OHCI controllers | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "generic-ohci" | ||
5 | - reg : ohci controller register range (address and length) | ||
6 | - interrupts : ohci controller interrupt | ||
7 | |||
8 | Optional properties: | ||
9 | - big-endian-regs : boolean, set this for hcds with big-endian registers | ||
10 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors | ||
11 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc | ||
12 | - clocks : a list of phandle + clock specifier pairs | ||
13 | - phys : phandle + phy specifier pair | ||
14 | - phy-names : "usb" | ||
15 | |||
16 | Example: | ||
17 | |||
18 | ohci0: usb@01c14400 { | ||
19 | compatible = "allwinner,sun4i-a10-ohci", "generic-ohci"; | ||
20 | reg = <0x01c14400 0x100>; | ||
21 | interrupts = <64>; | ||
22 | clocks = <&usb_clk 6>, <&ahb_gates 2>; | ||
23 | phys = <&usbphy 1>; | ||
24 | phy-names = "usb"; | ||
25 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt deleted file mode 100644 index c0245c888982..000000000000 --- a/Documentation/devicetree/bindings/usb/usb-phy.txt +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | USB PHY | ||
2 | |||
3 | OMAP USB2 PHY | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: Should be "ti,omap-usb2" | ||
7 | - reg : Address and length of the register set for the device. | ||
8 | - #phy-cells: determine the number of cells that should be given in the | ||
9 | phandle while referencing this phy. | ||
10 | |||
11 | Optional properties: | ||
12 | - ctrl-module : phandle of the control module used by PHY driver to power on | ||
13 | the PHY. | ||
14 | |||
15 | This is usually a subnode of ocp2scp to which it is connected. | ||
16 | |||
17 | usb2phy@4a0ad080 { | ||
18 | compatible = "ti,omap-usb2"; | ||
19 | reg = <0x4a0ad080 0x58>; | ||
20 | ctrl-module = <&omap_control_usb>; | ||
21 | #phy-cells = <0>; | ||
22 | }; | ||
23 | |||
24 | OMAP USB3 PHY | ||
25 | |||
26 | Required properties: | ||
27 | - compatible: Should be "ti,omap-usb3" | ||
28 | - reg : Address and length of the register set for the device. | ||
29 | - reg-names: The names of the register addresses corresponding to the registers | ||
30 | filled in "reg". | ||
31 | - #phy-cells: determine the number of cells that should be given in the | ||
32 | phandle while referencing this phy. | ||
33 | |||
34 | Optional properties: | ||
35 | - ctrl-module : phandle of the control module used by PHY driver to power on | ||
36 | the PHY. | ||
37 | |||
38 | This is usually a subnode of ocp2scp to which it is connected. | ||
39 | |||
40 | usb3phy@4a084400 { | ||
41 | compatible = "ti,omap-usb3"; | ||
42 | reg = <0x4a084400 0x80>, | ||
43 | <0x4a084800 0x64>, | ||
44 | <0x4a084c00 0x40>; | ||
45 | reg-names = "phy_rx", "phy_tx", "pll_ctrl"; | ||
46 | ctrl-module = <&omap_control_usb>; | ||
47 | #phy-cells = <0>; | ||
48 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/platform-uhci.txt b/Documentation/devicetree/bindings/usb/usb-uhci.txt index a4fb0719d157..298133416c97 100644 --- a/Documentation/devicetree/bindings/usb/platform-uhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-uhci.txt | |||
@@ -2,14 +2,14 @@ Generic Platform UHCI Controller | |||
2 | ----------------------------------------------------- | 2 | ----------------------------------------------------- |
3 | 3 | ||
4 | Required properties: | 4 | Required properties: |
5 | - compatible : "platform-uhci" | 5 | - compatible : "generic-uhci" (deprecated: "platform-uhci") |
6 | - reg : Should contain 1 register ranges(address and length) | 6 | - reg : Should contain 1 register ranges(address and length) |
7 | - interrupts : UHCI controller interrupt | 7 | - interrupts : UHCI controller interrupt |
8 | 8 | ||
9 | Example: | 9 | Example: |
10 | 10 | ||
11 | uhci@d8007b00 { | 11 | uhci@d8007b00 { |
12 | compatible = "platform-uhci"; | 12 | compatible = "generic-uhci"; |
13 | reg = <0xd8007b00 0x200>; | 13 | reg = <0xd8007b00 0x200>; |
14 | interrupts = <43>; | 14 | interrupts = <43>; |
15 | }; | 15 | }; |
diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt index 5752df0e17a2..90f8f607d125 100644 --- a/Documentation/devicetree/bindings/usb/usb-xhci.txt +++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt | |||
@@ -1,14 +1,14 @@ | |||
1 | USB xHCI controllers | 1 | USB xHCI controllers |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: should be "xhci-platform". | 4 | - compatible: should be "generic-xhci" (deprecated: "xhci-platform"). |
5 | - reg: should contain address and length of the standard XHCI | 5 | - reg: should contain address and length of the standard XHCI |
6 | register set for the device. | 6 | register set for the device. |
7 | - interrupts: one XHCI interrupt should be described here. | 7 | - interrupts: one XHCI interrupt should be described here. |
8 | 8 | ||
9 | Example: | 9 | Example: |
10 | usb@f0931000 { | 10 | usb@f0931000 { |
11 | compatible = "xhci-platform"; | 11 | compatible = "generic-xhci"; |
12 | reg = <0xf0931000 0x8c8>; | 12 | reg = <0xf0931000 0x8c8>; |
13 | interrupts = <0x0 0x4e 0x0>; | 13 | interrupts = <0x0 0x4e 0x0>; |
14 | }; | 14 | }; |
diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt deleted file mode 100644 index 17b3ad1d97e7..000000000000 --- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | VIA/Wondermedia VT8500 EHCI Controller | ||
2 | ----------------------------------------------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible : "via,vt8500-ehci" | ||
6 | - reg : Should contain 1 register ranges(address and length) | ||
7 | - interrupts : ehci controller interrupt | ||
8 | |||
9 | Example: | ||
10 | |||
11 | ehci@d8007900 { | ||
12 | compatible = "via,vt8500-ehci"; | ||
13 | reg = <0xd8007900 0x200>; | ||
14 | interrupts = <43>; | ||
15 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt deleted file mode 100644 index 5fb8fd6e250c..000000000000 --- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | VIA VT8500 and Wondermedia WM8xxx SoC USB controllers. | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci". | ||
5 | - reg: Address range of the ehci registers. size should be 0x200 | ||
6 | - interrupts: Should contain the ehci interrupt. | ||
7 | |||
8 | usb: ehci@D8007100 { | ||
9 | compatible = "wm,prizm-ehci", "usb-ehci"; | ||
10 | reg = <0xD8007100 0x200>; | ||
11 | interrupts = <1>; | ||
12 | }; | ||
diff --git a/Documentation/phy/samsung-usb2.txt b/Documentation/phy/samsung-usb2.txt new file mode 100644 index 000000000000..ed12d437189d --- /dev/null +++ b/Documentation/phy/samsung-usb2.txt | |||
@@ -0,0 +1,135 @@ | |||
1 | .------------------------------------------------------------------------------+ | ||
2 | | Samsung USB 2.0 PHY adaptation layer | | ||
3 | +-----------------------------------------------------------------------------+' | ||
4 | |||
5 | | 1. Description | ||
6 | +---------------- | ||
7 | |||
8 | The architecture of the USB 2.0 PHY module in Samsung SoCs is similar | ||
9 | among many SoCs. In spite of the similarities it proved difficult to | ||
10 | create a one driver that would fit all these PHY controllers. Often | ||
11 | the differences were minor and were found in particular bits of the | ||
12 | registers of the PHY. In some rare cases the order of register writes or | ||
13 | the PHY powering up process had to be altered. This adaptation layer is | ||
14 | a compromise between having separate drivers and having a single driver | ||
15 | with added support for many special cases. | ||
16 | |||
17 | | 2. Files description | ||
18 | +---------------------- | ||
19 | |||
20 | - phy-samsung-usb2.c | ||
21 | This is the main file of the adaptation layer. This file contains | ||
22 | the probe function and provides two callbacks to the Generic PHY | ||
23 | Framework. This two callbacks are used to power on and power off the | ||
24 | phy. They carry out the common work that has to be done on all version | ||
25 | of the PHY module. Depending on which SoC was chosen they execute SoC | ||
26 | specific callbacks. The specific SoC version is selected by choosing | ||
27 | the appropriate compatible string. In addition, this file contains | ||
28 | struct of_device_id definitions for particular SoCs. | ||
29 | |||
30 | - phy-samsung-usb2.h | ||
31 | This is the include file. It declares the structures used by this | ||
32 | driver. In addition it should contain extern declarations for | ||
33 | structures that describe particular SoCs. | ||
34 | |||
35 | | 3. Supporting SoCs | ||
36 | +-------------------- | ||
37 | |||
38 | To support a new SoC a new file should be added to the drivers/phy | ||
39 | directory. Each SoC's configuration is stored in an instance of the | ||
40 | struct samsung_usb2_phy_config. | ||
41 | |||
42 | struct samsung_usb2_phy_config { | ||
43 | const struct samsung_usb2_common_phy *phys; | ||
44 | int (*rate_to_clk)(unsigned long, u32 *); | ||
45 | unsigned int num_phys; | ||
46 | bool has_mode_switch; | ||
47 | }; | ||
48 | |||
49 | The num_phys is the number of phys handled by the driver. *phys is an | ||
50 | array that contains the configuration for each phy. The has_mode_switch | ||
51 | property is a boolean flag that determines whether the SoC has USB host | ||
52 | and device on a single pair of pins. If so, a special register has to | ||
53 | be modified to change the internal routing of these pins between a USB | ||
54 | device or host module. | ||
55 | |||
56 | For example the configuration for Exynos 4210 is following: | ||
57 | |||
58 | const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = { | ||
59 | .has_mode_switch = 0, | ||
60 | .num_phys = EXYNOS4210_NUM_PHYS, | ||
61 | .phys = exynos4210_phys, | ||
62 | .rate_to_clk = exynos4210_rate_to_clk, | ||
63 | } | ||
64 | |||
65 | - int (*rate_to_clk)(unsigned long, u32 *) | ||
66 | The rate_to_clk callback is to convert the rate of the clock | ||
67 | used as the reference clock for the PHY module to the value | ||
68 | that should be written in the hardware register. | ||
69 | |||
70 | The exynos4210_phys configuration array is as follows: | ||
71 | |||
72 | static const struct samsung_usb2_common_phy exynos4210_phys[] = { | ||
73 | { | ||
74 | .label = "device", | ||
75 | .id = EXYNOS4210_DEVICE, | ||
76 | .power_on = exynos4210_power_on, | ||
77 | .power_off = exynos4210_power_off, | ||
78 | }, | ||
79 | { | ||
80 | .label = "host", | ||
81 | .id = EXYNOS4210_HOST, | ||
82 | .power_on = exynos4210_power_on, | ||
83 | .power_off = exynos4210_power_off, | ||
84 | }, | ||
85 | { | ||
86 | .label = "hsic0", | ||
87 | .id = EXYNOS4210_HSIC0, | ||
88 | .power_on = exynos4210_power_on, | ||
89 | .power_off = exynos4210_power_off, | ||
90 | }, | ||
91 | { | ||
92 | .label = "hsic1", | ||
93 | .id = EXYNOS4210_HSIC1, | ||
94 | .power_on = exynos4210_power_on, | ||
95 | .power_off = exynos4210_power_off, | ||
96 | }, | ||
97 | {}, | ||
98 | }; | ||
99 | |||
100 | - int (*power_on)(struct samsung_usb2_phy_instance *); | ||
101 | - int (*power_off)(struct samsung_usb2_phy_instance *); | ||
102 | These two callbacks are used to power on and power off the phy | ||
103 | by modifying appropriate registers. | ||
104 | |||
105 | Final change to the driver is adding appropriate compatible value to the | ||
106 | phy-samsung-usb2.c file. In case of Exynos 4210 the following lines were | ||
107 | added to the struct of_device_id samsung_usb2_phy_of_match[] array: | ||
108 | |||
109 | #ifdef CONFIG_PHY_EXYNOS4210_USB2 | ||
110 | { | ||
111 | .compatible = "samsung,exynos4210-usb2-phy", | ||
112 | .data = &exynos4210_usb2_phy_config, | ||
113 | }, | ||
114 | #endif | ||
115 | |||
116 | To add further flexibility to the driver the Kconfig file enables to | ||
117 | include support for selected SoCs in the compiled driver. The Kconfig | ||
118 | entry for Exynos 4210 is following: | ||
119 | |||
120 | config PHY_EXYNOS4210_USB2 | ||
121 | bool "Support for Exynos 4210" | ||
122 | depends on PHY_SAMSUNG_USB2 | ||
123 | depends on CPU_EXYNOS4210 | ||
124 | help | ||
125 | Enable USB PHY support for Exynos 4210. This option requires that | ||
126 | Samsung USB 2.0 PHY driver is enabled and means that support for this | ||
127 | particular SoC is compiled in the driver. In case of Exynos 4210 four | ||
128 | phys are available - device, host, HSCI0 and HSCI1. | ||
129 | |||
130 | The newly created file that supports the new SoC has to be also added to the | ||
131 | Makefile. In case of Exynos 4210 the added line is following: | ||
132 | |||
133 | obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o | ||
134 | |||
135 | After completing these steps the support for the new SoC should be ready. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 48a88402c25d..7fe5977e80db 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9130,8 +9130,7 @@ S: Maintained | |||
9130 | F: drivers/net/wireless/ath/ar5523/ | 9130 | F: drivers/net/wireless/ath/ar5523/ |
9131 | 9131 | ||
9132 | USB ATTACHED SCSI | 9132 | USB ATTACHED SCSI |
9133 | M: Matthew Wilcox <willy@linux.intel.com> | 9133 | M: Hans de Goede <hdegoede@redhat.com> |
9134 | M: Sarah Sharp <sarah.a.sharp@linux.intel.com> | ||
9135 | M: Gerd Hoffmann <kraxel@redhat.com> | 9134 | M: Gerd Hoffmann <kraxel@redhat.com> |
9136 | L: linux-usb@vger.kernel.org | 9135 | L: linux-usb@vger.kernel.org |
9137 | L: linux-scsi@vger.kernel.org | 9136 | L: linux-scsi@vger.kernel.org |
@@ -9357,7 +9356,7 @@ S: Maintained | |||
9357 | F: drivers/net/wireless/rndis_wlan.c | 9356 | F: drivers/net/wireless/rndis_wlan.c |
9358 | 9357 | ||
9359 | USB XHCI DRIVER | 9358 | USB XHCI DRIVER |
9360 | M: Sarah Sharp <sarah.a.sharp@linux.intel.com> | 9359 | M: Mathias Nyman <mathias.nyman@intel.com> |
9361 | L: linux-usb@vger.kernel.org | 9360 | L: linux-usb@vger.kernel.org |
9362 | S: Supported | 9361 | S: Supported |
9363 | F: drivers/usb/host/xhci* | 9362 | F: drivers/usb/host/xhci* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15949459611f..b76ae4185a3b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -534,7 +534,6 @@ config ARCH_DOVE | |||
534 | select PINCTRL | 534 | select PINCTRL |
535 | select PINCTRL_DOVE | 535 | select PINCTRL_DOVE |
536 | select PLAT_ORION_LEGACY | 536 | select PLAT_ORION_LEGACY |
537 | select USB_ARCH_HAS_EHCI | ||
538 | help | 537 | help |
539 | Support for the Marvell Dove SoC 88AP510 | 538 | Support for the Marvell Dove SoC 88AP510 |
540 | 539 | ||
@@ -633,7 +632,6 @@ config ARCH_LPC32XX | |||
633 | select GENERIC_CLOCKEVENTS | 632 | select GENERIC_CLOCKEVENTS |
634 | select HAVE_IDE | 633 | select HAVE_IDE |
635 | select HAVE_PWM | 634 | select HAVE_PWM |
636 | select USB_ARCH_HAS_OHCI | ||
637 | select USE_OF | 635 | select USE_OF |
638 | help | 636 | help |
639 | Support for the NXP LPC32XX family of processors | 637 | Support for the NXP LPC32XX family of processors |
@@ -770,7 +768,6 @@ config ARCH_S3C64XX | |||
770 | select SAMSUNG_ATAGS | 768 | select SAMSUNG_ATAGS |
771 | select SAMSUNG_WAKEMASK | 769 | select SAMSUNG_WAKEMASK |
772 | select SAMSUNG_WDT_RESET | 770 | select SAMSUNG_WDT_RESET |
773 | select USB_ARCH_HAS_OHCI | ||
774 | help | 771 | help |
775 | Samsung S3C64XX series based systems | 772 | Samsung S3C64XX series based systems |
776 | 773 | ||
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 4c414af75ef0..8d197dcdd2c0 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig | |||
@@ -36,7 +36,6 @@ config ARCH_EXYNOS5 | |||
36 | select HAVE_ARM_SCU if SMP | 36 | select HAVE_ARM_SCU if SMP |
37 | select HAVE_SMP | 37 | select HAVE_SMP |
38 | select PINCTRL | 38 | select PINCTRL |
39 | select USB_ARCH_HAS_XHCI | ||
40 | help | 39 | help |
41 | Samsung EXYNOS5 (Cortex-A15) SoC based systems | 40 | Samsung EXYNOS5 (Cortex-A15) SoC based systems |
42 | 41 | ||
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 0af7ca02314d..6fb91fb604a0 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -21,7 +21,6 @@ config ARCH_OMAP3 | |||
21 | select PM_OPP if PM | 21 | select PM_OPP if PM |
22 | select PM_RUNTIME if CPU_IDLE | 22 | select PM_RUNTIME if CPU_IDLE |
23 | select SOC_HAS_OMAP2_SDRC | 23 | select SOC_HAS_OMAP2_SDRC |
24 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | ||
25 | 24 | ||
26 | config ARCH_OMAP4 | 25 | config ARCH_OMAP4 |
27 | bool "TI OMAP4" | 26 | bool "TI OMAP4" |
@@ -42,7 +41,6 @@ config ARCH_OMAP4 | |||
42 | select PL310_ERRATA_727915 | 41 | select PL310_ERRATA_727915 |
43 | select PM_OPP if PM | 42 | select PM_OPP if PM |
44 | select PM_RUNTIME if CPU_IDLE | 43 | select PM_RUNTIME if CPU_IDLE |
45 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | ||
46 | select ARM_ERRATA_754322 | 44 | select ARM_ERRATA_754322 |
47 | select ARM_ERRATA_775420 | 45 | select ARM_ERRATA_775420 |
48 | 46 | ||
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index f6db7dcae3f4..3b8c87461d67 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -114,8 +114,6 @@ config ARCH_R8A7778 | |||
114 | select CPU_V7 | 114 | select CPU_V7 |
115 | select SH_CLK_CPG | 115 | select SH_CLK_CPG |
116 | select ARM_GIC | 116 | select ARM_GIC |
117 | select USB_ARCH_HAS_EHCI | ||
118 | select USB_ARCH_HAS_OHCI | ||
119 | select SYS_SUPPORTS_SH_TMU | 117 | select SYS_SUPPORTS_SH_TMU |
120 | 118 | ||
121 | config ARCH_R8A7779 | 119 | config ARCH_R8A7779 |
@@ -124,8 +122,6 @@ config ARCH_R8A7779 | |||
124 | select ARM_GIC | 122 | select ARM_GIC |
125 | select CPU_V7 | 123 | select CPU_V7 |
126 | select SH_CLK_CPG | 124 | select SH_CLK_CPG |
127 | select USB_ARCH_HAS_EHCI | ||
128 | select USB_ARCH_HAS_OHCI | ||
129 | select RENESAS_INTC_IRQPIN | 125 | select RENESAS_INTC_IRQPIN |
130 | select SYS_SUPPORTS_SH_TMU | 126 | select SYS_SUPPORTS_SH_TMU |
131 | 127 | ||
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index b1232d8be6f5..4926bd11f190 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -19,7 +19,6 @@ config ARCH_TEGRA | |||
19 | select RESET_CONTROLLER | 19 | select RESET_CONTROLLER |
20 | select SOC_BUS | 20 | select SOC_BUS |
21 | select SPARSE_IRQ | 21 | select SPARSE_IRQ |
22 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | ||
23 | select USB_ULPI if USB_PHY | 22 | select USB_ULPI if USB_PHY |
24 | select USB_ULPI_VIEWPORT if USB_PHY | 23 | select USB_ULPI_VIEWPORT if USB_PHY |
25 | select USE_OF | 24 | select USE_OF |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 95fa1f1d5c8b..cb1da372346c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -67,8 +67,6 @@ config MIPS_ALCHEMY | |||
67 | select SYS_SUPPORTS_APM_EMULATION | 67 | select SYS_SUPPORTS_APM_EMULATION |
68 | select ARCH_REQUIRE_GPIOLIB | 68 | select ARCH_REQUIRE_GPIOLIB |
69 | select SYS_SUPPORTS_ZBOOT | 69 | select SYS_SUPPORTS_ZBOOT |
70 | select USB_ARCH_HAS_OHCI | ||
71 | select USB_ARCH_HAS_EHCI | ||
72 | 70 | ||
73 | config AR7 | 71 | config AR7 |
74 | bool "Texas Instruments AR7" | 72 | bool "Texas Instruments AR7" |
@@ -360,7 +358,6 @@ config MIPS_SEAD3 | |||
360 | select SYS_SUPPORTS_LITTLE_ENDIAN | 358 | select SYS_SUPPORTS_LITTLE_ENDIAN |
361 | select SYS_SUPPORTS_SMARTMIPS | 359 | select SYS_SUPPORTS_SMARTMIPS |
362 | select SYS_SUPPORTS_MICROMIPS | 360 | select SYS_SUPPORTS_MICROMIPS |
363 | select USB_ARCH_HAS_EHCI | ||
364 | select USB_EHCI_BIG_ENDIAN_DESC | 361 | select USB_EHCI_BIG_ENDIAN_DESC |
365 | select USB_EHCI_BIG_ENDIAN_MMIO | 362 | select USB_EHCI_BIG_ENDIAN_MMIO |
366 | select USE_OF | 363 | select USE_OF |
@@ -718,8 +715,6 @@ config CAVIUM_OCTEON_SOC | |||
718 | select SWAP_IO_SPACE | 715 | select SWAP_IO_SPACE |
719 | select HW_HAS_PCI | 716 | select HW_HAS_PCI |
720 | select ZONE_DMA32 | 717 | select ZONE_DMA32 |
721 | select USB_ARCH_HAS_OHCI | ||
722 | select USB_ARCH_HAS_EHCI | ||
723 | select HOLES_IN_ZONE | 718 | select HOLES_IN_ZONE |
724 | select ARCH_REQUIRE_GPIOLIB | 719 | select ARCH_REQUIRE_GPIOLIB |
725 | help | 720 | help |
@@ -756,8 +751,6 @@ config NLM_XLR_BOARD | |||
756 | select ZONE_DMA32 if 64BIT | 751 | select ZONE_DMA32 if 64BIT |
757 | select SYNC_R4K | 752 | select SYNC_R4K |
758 | select SYS_HAS_EARLY_PRINTK | 753 | select SYS_HAS_EARLY_PRINTK |
759 | select USB_ARCH_HAS_OHCI if USB_SUPPORT | ||
760 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | ||
761 | select SYS_SUPPORTS_ZBOOT | 754 | select SYS_SUPPORTS_ZBOOT |
762 | select SYS_SUPPORTS_ZBOOT_UART16550 | 755 | select SYS_SUPPORTS_ZBOOT_UART16550 |
763 | help | 756 | help |
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 3995e31a73e2..dfc60209dc63 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig | |||
@@ -74,34 +74,26 @@ config ATH79_MACH_UBNT_XM | |||
74 | endmenu | 74 | endmenu |
75 | 75 | ||
76 | config SOC_AR71XX | 76 | config SOC_AR71XX |
77 | select USB_ARCH_HAS_EHCI | ||
78 | select USB_ARCH_HAS_OHCI | ||
79 | select HW_HAS_PCI | 77 | select HW_HAS_PCI |
80 | def_bool n | 78 | def_bool n |
81 | 79 | ||
82 | config SOC_AR724X | 80 | config SOC_AR724X |
83 | select USB_ARCH_HAS_EHCI | ||
84 | select USB_ARCH_HAS_OHCI | ||
85 | select HW_HAS_PCI | 81 | select HW_HAS_PCI |
86 | select PCI_AR724X if PCI | 82 | select PCI_AR724X if PCI |
87 | def_bool n | 83 | def_bool n |
88 | 84 | ||
89 | config SOC_AR913X | 85 | config SOC_AR913X |
90 | select USB_ARCH_HAS_EHCI | ||
91 | def_bool n | 86 | def_bool n |
92 | 87 | ||
93 | config SOC_AR933X | 88 | config SOC_AR933X |
94 | select USB_ARCH_HAS_EHCI | ||
95 | def_bool n | 89 | def_bool n |
96 | 90 | ||
97 | config SOC_AR934X | 91 | config SOC_AR934X |
98 | select USB_ARCH_HAS_EHCI | ||
99 | select HW_HAS_PCI | 92 | select HW_HAS_PCI |
100 | select PCI_AR724X if PCI | 93 | select PCI_AR724X if PCI |
101 | def_bool n | 94 | def_bool n |
102 | 95 | ||
103 | config SOC_QCA955X | 96 | config SOC_QCA955X |
104 | select USB_ARCH_HAS_EHCI | ||
105 | select HW_HAS_PCI | 97 | select HW_HAS_PCI |
106 | select PCI_AR724X if PCI | 98 | select PCI_AR724X if PCI |
107 | def_bool n | 99 | def_bool n |
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 1bfd1c17b3c2..4a296655f446 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig | |||
@@ -20,19 +20,13 @@ choice | |||
20 | config SOC_RT305X | 20 | config SOC_RT305X |
21 | bool "RT305x" | 21 | bool "RT305x" |
22 | select USB_ARCH_HAS_HCD | 22 | select USB_ARCH_HAS_HCD |
23 | select USB_ARCH_HAS_OHCI | ||
24 | select USB_ARCH_HAS_EHCI | ||
25 | 23 | ||
26 | config SOC_RT3883 | 24 | config SOC_RT3883 |
27 | bool "RT3883" | 25 | bool "RT3883" |
28 | select USB_ARCH_HAS_OHCI | ||
29 | select USB_ARCH_HAS_EHCI | ||
30 | select HW_HAS_PCI | 26 | select HW_HAS_PCI |
31 | 27 | ||
32 | config SOC_MT7620 | 28 | config SOC_MT7620 |
33 | bool "MT7620" | 29 | bool "MT7620" |
34 | select USB_ARCH_HAS_OHCI | ||
35 | select USB_ARCH_HAS_EHCI | ||
36 | 30 | ||
37 | endchoice | 31 | endchoice |
38 | 32 | ||
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index d6c7506ec7d9..dc1a264ec6e6 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -265,7 +265,6 @@ config 440EP | |||
265 | select PPC_FPU | 265 | select PPC_FPU |
266 | select IBM440EP_ERR42 | 266 | select IBM440EP_ERR42 |
267 | select IBM_EMAC_ZMII | 267 | select IBM_EMAC_ZMII |
268 | select USB_ARCH_HAS_OHCI | ||
269 | 268 | ||
270 | config 440EPX | 269 | config 440EPX |
271 | bool | 270 | bool |
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index e87c19473973..56f274064d6c 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig | |||
@@ -2,10 +2,8 @@ config PPC_PS3 | |||
2 | bool "Sony PS3" | 2 | bool "Sony PS3" |
3 | depends on PPC64 && PPC_BOOK3S | 3 | depends on PPC64 && PPC_BOOK3S |
4 | select PPC_CELL | 4 | select PPC_CELL |
5 | select USB_ARCH_HAS_OHCI | ||
6 | select USB_OHCI_LITTLE_ENDIAN | 5 | select USB_OHCI_LITTLE_ENDIAN |
7 | select USB_OHCI_BIG_ENDIAN_MMIO | 6 | select USB_OHCI_BIG_ENDIAN_MMIO |
8 | select USB_ARCH_HAS_EHCI | ||
9 | select USB_EHCI_BIG_ENDIAN_MMIO | 7 | select USB_EHCI_BIG_ENDIAN_MMIO |
10 | select PPC_PCI_CHOICE | 8 | select PPC_PCI_CHOICE |
11 | help | 9 | help |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 364d204298fa..1399383315a3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -347,7 +347,6 @@ config CPU_SUBTYPE_SH7720 | |||
347 | select CPU_HAS_DSP | 347 | select CPU_HAS_DSP |
348 | select SYS_SUPPORTS_SH_CMT | 348 | select SYS_SUPPORTS_SH_CMT |
349 | select ARCH_WANT_OPTIONAL_GPIOLIB | 349 | select ARCH_WANT_OPTIONAL_GPIOLIB |
350 | select USB_ARCH_HAS_OHCI | ||
351 | select USB_OHCI_SH if USB_OHCI_HCD | 350 | select USB_OHCI_SH if USB_OHCI_HCD |
352 | select PINCTRL | 351 | select PINCTRL |
353 | help | 352 | help |
@@ -358,7 +357,6 @@ config CPU_SUBTYPE_SH7721 | |||
358 | select CPU_SH3 | 357 | select CPU_SH3 |
359 | select CPU_HAS_DSP | 358 | select CPU_HAS_DSP |
360 | select SYS_SUPPORTS_SH_CMT | 359 | select SYS_SUPPORTS_SH_CMT |
361 | select USB_ARCH_HAS_OHCI | ||
362 | select USB_OHCI_SH if USB_OHCI_HCD | 360 | select USB_OHCI_SH if USB_OHCI_HCD |
363 | help | 361 | help |
364 | Select SH7721 if you have a SH3-DSP SH7721 CPU. | 362 | Select SH7721 if you have a SH3-DSP SH7721 CPU. |
@@ -436,8 +434,6 @@ config CPU_SUBTYPE_SH7734 | |||
436 | select CPU_SH4A | 434 | select CPU_SH4A |
437 | select CPU_SHX2 | 435 | select CPU_SHX2 |
438 | select ARCH_WANT_OPTIONAL_GPIOLIB | 436 | select ARCH_WANT_OPTIONAL_GPIOLIB |
439 | select USB_ARCH_HAS_OHCI | ||
440 | select USB_ARCH_HAS_EHCI | ||
441 | select PINCTRL | 437 | select PINCTRL |
442 | help | 438 | help |
443 | Select SH7734 if you have a SH4A SH7734 CPU. | 439 | Select SH7734 if you have a SH4A SH7734 CPU. |
@@ -447,8 +443,6 @@ config CPU_SUBTYPE_SH7757 | |||
447 | select CPU_SH4A | 443 | select CPU_SH4A |
448 | select CPU_SHX2 | 444 | select CPU_SHX2 |
449 | select ARCH_WANT_OPTIONAL_GPIOLIB | 445 | select ARCH_WANT_OPTIONAL_GPIOLIB |
450 | select USB_ARCH_HAS_OHCI | ||
451 | select USB_ARCH_HAS_EHCI | ||
452 | select PINCTRL | 446 | select PINCTRL |
453 | help | 447 | help |
454 | Select SH7757 if you have a SH4A SH7757 CPU. | 448 | Select SH7757 if you have a SH4A SH7757 CPU. |
@@ -456,7 +450,6 @@ config CPU_SUBTYPE_SH7757 | |||
456 | config CPU_SUBTYPE_SH7763 | 450 | config CPU_SUBTYPE_SH7763 |
457 | bool "Support SH7763 processor" | 451 | bool "Support SH7763 processor" |
458 | select CPU_SH4A | 452 | select CPU_SH4A |
459 | select USB_ARCH_HAS_OHCI | ||
460 | select USB_OHCI_SH if USB_OHCI_HCD | 453 | select USB_OHCI_SH if USB_OHCI_HCD |
461 | help | 454 | help |
462 | Select SH7763 if you have a SH4A SH7763(R5S77631) CPU. | 455 | Select SH7763 if you have a SH4A SH7763(R5S77631) CPU. |
@@ -485,9 +478,7 @@ config CPU_SUBTYPE_SH7786 | |||
485 | select CPU_HAS_PTEAEX | 478 | select CPU_HAS_PTEAEX |
486 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP | 479 | select GENERIC_CLOCKEVENTS_BROADCAST if SMP |
487 | select ARCH_WANT_OPTIONAL_GPIOLIB | 480 | select ARCH_WANT_OPTIONAL_GPIOLIB |
488 | select USB_ARCH_HAS_OHCI | ||
489 | select USB_OHCI_SH if USB_OHCI_HCD | 481 | select USB_OHCI_SH if USB_OHCI_HCD |
490 | select USB_ARCH_HAS_EHCI | ||
491 | select USB_EHCI_SH if USB_EHCI_HCD | 482 | select USB_EHCI_SH if USB_EHCI_HCD |
492 | select PINCTRL | 483 | select PINCTRL |
493 | 484 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index cc32a6f96c64..2448d757b449 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -2278,6 +2278,7 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
2278 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, | 2278 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, |
2279 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, | 2279 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, |
2280 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, | 2280 | { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, |
2281 | { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, | ||
2281 | { } | 2282 | { } |
2282 | }; | 2283 | }; |
2283 | 2284 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 22f28d6b33a8..830de69d2df0 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -961,4 +961,7 @@ | |||
961 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 | 961 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 |
962 | 962 | ||
963 | 963 | ||
964 | #define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */ | ||
965 | #define USB_DEVICE_ID_RI_KA_WEBMAIL 0x1320 /* Webmail Notifier */ | ||
966 | |||
964 | #endif | 967 | #endif |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c7a551c2d5f1..8d3c49cc500f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -16,30 +16,56 @@ config GENERIC_PHY | |||
16 | framework should select this config. | 16 | framework should select this config. |
17 | 17 | ||
18 | config PHY_EXYNOS_MIPI_VIDEO | 18 | config PHY_EXYNOS_MIPI_VIDEO |
19 | depends on HAS_IOMEM | ||
20 | tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" | 19 | tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver" |
20 | depends on HAS_IOMEM | ||
21 | depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST | ||
22 | select GENERIC_PHY | ||
23 | default y if ARCH_S5PV210 || ARCH_EXYNOS | ||
21 | help | 24 | help |
22 | Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P | 25 | Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P |
23 | and EXYNOS SoCs. | 26 | and EXYNOS SoCs. |
24 | 27 | ||
25 | config PHY_MVEBU_SATA | 28 | config PHY_MVEBU_SATA |
26 | def_bool y | 29 | def_bool y |
27 | depends on ARCH_KIRKWOOD || ARCH_DOVE | 30 | depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE |
28 | depends on OF | 31 | depends on OF |
29 | select GENERIC_PHY | 32 | select GENERIC_PHY |
30 | 33 | ||
34 | config OMAP_CONTROL_PHY | ||
35 | tristate "OMAP CONTROL PHY Driver" | ||
36 | help | ||
37 | Enable this to add support for the PHY part present in the control | ||
38 | module. This driver has API to power on the USB2 PHY and to write to | ||
39 | the mailbox. The mailbox is present only in omap4 and the register to | ||
40 | power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an | ||
41 | additional register to power on USB3 PHY/SATA PHY/PCIE PHY | ||
42 | (PIPE3 PHY). | ||
43 | |||
31 | config OMAP_USB2 | 44 | config OMAP_USB2 |
32 | tristate "OMAP USB2 PHY Driver" | 45 | tristate "OMAP USB2 PHY Driver" |
33 | depends on ARCH_OMAP2PLUS | 46 | depends on ARCH_OMAP2PLUS |
34 | depends on USB_PHY | 47 | depends on USB_PHY |
35 | select GENERIC_PHY | 48 | select GENERIC_PHY |
36 | select OMAP_CONTROL_USB | 49 | select OMAP_CONTROL_PHY |
50 | depends on OMAP_OCP2SCP | ||
37 | help | 51 | help |
38 | Enable this to support the transceiver that is part of SOC. This | 52 | Enable this to support the transceiver that is part of SOC. This |
39 | driver takes care of all the PHY functionality apart from comparator. | 53 | driver takes care of all the PHY functionality apart from comparator. |
40 | The USB OTG controller communicates with the comparator using this | 54 | The USB OTG controller communicates with the comparator using this |
41 | driver. | 55 | driver. |
42 | 56 | ||
57 | config TI_PIPE3 | ||
58 | tristate "TI PIPE3 PHY Driver" | ||
59 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
60 | select GENERIC_PHY | ||
61 | select OMAP_CONTROL_PHY | ||
62 | depends on OMAP_OCP2SCP | ||
63 | help | ||
64 | Enable this to support the PIPE3 PHY that is part of TI SOCs. This | ||
65 | driver takes care of all the PHY functionality apart from comparator. | ||
66 | This driver interacts with the "OMAP Control PHY Driver" to power | ||
67 | on/off the PHY. | ||
68 | |||
43 | config TWL4030_USB | 69 | config TWL4030_USB |
44 | tristate "TWL4030 USB Transceiver Driver" | 70 | tristate "TWL4030 USB Transceiver Driver" |
45 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS | 71 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS |
@@ -54,6 +80,8 @@ config TWL4030_USB | |||
54 | config PHY_EXYNOS_DP_VIDEO | 80 | config PHY_EXYNOS_DP_VIDEO |
55 | tristate "EXYNOS SoC series Display Port PHY driver" | 81 | tristate "EXYNOS SoC series Display Port PHY driver" |
56 | depends on OF | 82 | depends on OF |
83 | depends on ARCH_EXYNOS || COMPILE_TEST | ||
84 | default ARCH_EXYNOS | ||
57 | select GENERIC_PHY | 85 | select GENERIC_PHY |
58 | help | 86 | help |
59 | Support for Display Port PHY found on Samsung EXYNOS SoCs. | 87 | Support for Display Port PHY found on Samsung EXYNOS SoCs. |
@@ -65,4 +93,77 @@ config BCM_KONA_USB2_PHY | |||
65 | help | 93 | help |
66 | Enable this to support the Broadcom Kona USB 2.0 PHY. | 94 | Enable this to support the Broadcom Kona USB 2.0 PHY. |
67 | 95 | ||
96 | config PHY_EXYNOS5250_SATA | ||
97 | tristate "Exynos5250 Sata SerDes/PHY driver" | ||
98 | depends on SOC_EXYNOS5250 | ||
99 | depends on HAS_IOMEM | ||
100 | depends on OF | ||
101 | select GENERIC_PHY | ||
102 | select I2C | ||
103 | select I2C_S3C2410 | ||
104 | select MFD_SYSCON | ||
105 | help | ||
106 | Enable this to support SATA SerDes/Phy found on Samsung's | ||
107 | Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s, | ||
108 | SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host | ||
109 | port to accept one SATA device. | ||
110 | |||
111 | config PHY_SUN4I_USB | ||
112 | tristate "Allwinner sunxi SoC USB PHY driver" | ||
113 | depends on ARCH_SUNXI && HAS_IOMEM && OF | ||
114 | select GENERIC_PHY | ||
115 | help | ||
116 | Enable this to support the transceiver that is part of Allwinner | ||
117 | sunxi SoCs. | ||
118 | |||
119 | This driver controls the entire USB PHY block, both the USB OTG | ||
120 | parts, as well as the 2 regular USB 2 host PHYs. | ||
121 | |||
122 | config PHY_SAMSUNG_USB2 | ||
123 | tristate "Samsung USB 2.0 PHY driver" | ||
124 | select GENERIC_PHY | ||
125 | select MFD_SYSCON | ||
126 | help | ||
127 | Enable this to support the Samsung USB 2.0 PHY driver for Samsung | ||
128 | SoCs. This driver provides the interface for USB 2.0 PHY. Support for | ||
129 | particular SoCs has to be enabled in addition to this driver. Number | ||
130 | and type of supported phys depends on the SoC. | ||
131 | |||
132 | config PHY_EXYNOS4210_USB2 | ||
133 | bool "Support for Exynos 4210" | ||
134 | depends on PHY_SAMSUNG_USB2 | ||
135 | depends on CPU_EXYNOS4210 | ||
136 | help | ||
137 | Enable USB PHY support for Exynos 4210. This option requires that | ||
138 | Samsung USB 2.0 PHY driver is enabled and means that support for this | ||
139 | particular SoC is compiled in the driver. In case of Exynos 4210 four | ||
140 | phys are available - device, host, HSIC0 and HSIC1. | ||
141 | |||
142 | config PHY_EXYNOS4X12_USB2 | ||
143 | bool "Support for Exynos 4x12" | ||
144 | depends on PHY_SAMSUNG_USB2 | ||
145 | depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) | ||
146 | help | ||
147 | Enable USB PHY support for Exynos 4x12. This option requires that | ||
148 | Samsung USB 2.0 PHY driver is enabled and means that support for this | ||
149 | particular SoC is compiled in the driver. In case of Exynos 4x12 four | ||
150 | phys are available - device, host, HSIC0 and HSIC1. | ||
151 | |||
152 | config PHY_EXYNOS5250_USB2 | ||
153 | bool "Support for Exynos 5250" | ||
154 | depends on PHY_SAMSUNG_USB2 | ||
155 | depends on SOC_EXYNOS5250 | ||
156 | help | ||
157 | Enable USB PHY support for Exynos 5250. This option requires that | ||
158 | Samsung USB 2.0 PHY driver is enabled and means that support for this | ||
159 | particular SoC is compiled in the driver. In case of Exynos 5250 four | ||
160 | phys are available - device, host, HSIC0 and HSIC. | ||
161 | |||
162 | config PHY_XGENE | ||
163 | tristate "APM X-Gene 15Gbps PHY support" | ||
164 | depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) | ||
165 | select GENERIC_PHY | ||
166 | help | ||
167 | This option enables support for APM X-Gene SoC multi-purpose PHY. | ||
168 | |||
68 | endmenu | 169 | endmenu |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index b57c25371cca..2faf78edc864 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -7,5 +7,14 @@ obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o | |||
7 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o | 7 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o |
8 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o | 8 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o |
9 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o | 9 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o |
10 | obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o | ||
10 | obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o | 11 | obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o |
12 | obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o | ||
11 | obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o | 13 | obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o |
14 | obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o | ||
15 | obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o | ||
16 | obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-samsung-usb2.o | ||
17 | obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o | ||
18 | obj-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o | ||
19 | obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o | ||
20 | obj-$(CONFIG_PHY_XGENE) += phy-xgene.o | ||
diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c index efc5c1a13a5d..e94f5a6a5645 100644 --- a/drivers/phy/phy-bcm-kona-usb2.c +++ b/drivers/phy/phy-bcm-kona-usb2.c | |||
@@ -128,10 +128,8 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev) | |||
128 | 128 | ||
129 | phy_provider = devm_of_phy_provider_register(dev, | 129 | phy_provider = devm_of_phy_provider_register(dev, |
130 | of_phy_simple_xlate); | 130 | of_phy_simple_xlate); |
131 | if (IS_ERR(phy_provider)) | ||
132 | return PTR_ERR(phy_provider); | ||
133 | 131 | ||
134 | return 0; | 132 | return PTR_ERR_OR_ZERO(phy_provider); |
135 | } | 133 | } |
136 | 134 | ||
137 | static const struct of_device_id bcm_kona_usb2_dt_ids[] = { | 135 | static const struct of_device_id bcm_kona_usb2_dt_ids[] = { |
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 6c738376daff..623b71c54b3e 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -274,8 +274,8 @@ int phy_power_off(struct phy *phy) | |||
274 | EXPORT_SYMBOL_GPL(phy_power_off); | 274 | EXPORT_SYMBOL_GPL(phy_power_off); |
275 | 275 | ||
276 | /** | 276 | /** |
277 | * of_phy_get() - lookup and obtain a reference to a phy by phandle | 277 | * _of_phy_get() - lookup and obtain a reference to a phy by phandle |
278 | * @dev: device that requests this phy | 278 | * @np: device_node for which to get the phy |
279 | * @index: the index of the phy | 279 | * @index: the index of the phy |
280 | * | 280 | * |
281 | * Returns the phy associated with the given phandle value, | 281 | * Returns the phy associated with the given phandle value, |
@@ -284,20 +284,17 @@ EXPORT_SYMBOL_GPL(phy_power_off); | |||
284 | * not yet loaded. This function uses of_xlate call back function provided | 284 | * not yet loaded. This function uses of_xlate call back function provided |
285 | * while registering the phy_provider to find the phy instance. | 285 | * while registering the phy_provider to find the phy instance. |
286 | */ | 286 | */ |
287 | static struct phy *of_phy_get(struct device *dev, int index) | 287 | static struct phy *_of_phy_get(struct device_node *np, int index) |
288 | { | 288 | { |
289 | int ret; | 289 | int ret; |
290 | struct phy_provider *phy_provider; | 290 | struct phy_provider *phy_provider; |
291 | struct phy *phy = NULL; | 291 | struct phy *phy = NULL; |
292 | struct of_phandle_args args; | 292 | struct of_phandle_args args; |
293 | 293 | ||
294 | ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells", | 294 | ret = of_parse_phandle_with_args(np, "phys", "#phy-cells", |
295 | index, &args); | 295 | index, &args); |
296 | if (ret) { | 296 | if (ret) |
297 | dev_dbg(dev, "failed to get phy in %s node\n", | ||
298 | dev->of_node->full_name); | ||
299 | return ERR_PTR(-ENODEV); | 297 | return ERR_PTR(-ENODEV); |
300 | } | ||
301 | 298 | ||
302 | mutex_lock(&phy_provider_mutex); | 299 | mutex_lock(&phy_provider_mutex); |
303 | phy_provider = of_phy_provider_lookup(args.np); | 300 | phy_provider = of_phy_provider_lookup(args.np); |
@@ -317,6 +314,36 @@ err0: | |||
317 | } | 314 | } |
318 | 315 | ||
319 | /** | 316 | /** |
317 | * of_phy_get() - lookup and obtain a reference to a phy using a device_node. | ||
318 | * @np: device_node for which to get the phy | ||
319 | * @con_id: name of the phy from device's point of view | ||
320 | * | ||
321 | * Returns the phy driver, after getting a refcount to it; or | ||
322 | * -ENODEV if there is no such phy. The caller is responsible for | ||
323 | * calling phy_put() to release that count. | ||
324 | */ | ||
325 | struct phy *of_phy_get(struct device_node *np, const char *con_id) | ||
326 | { | ||
327 | struct phy *phy = NULL; | ||
328 | int index = 0; | ||
329 | |||
330 | if (con_id) | ||
331 | index = of_property_match_string(np, "phy-names", con_id); | ||
332 | |||
333 | phy = _of_phy_get(np, index); | ||
334 | if (IS_ERR(phy)) | ||
335 | return phy; | ||
336 | |||
337 | if (!try_module_get(phy->ops->owner)) | ||
338 | return ERR_PTR(-EPROBE_DEFER); | ||
339 | |||
340 | get_device(&phy->dev); | ||
341 | |||
342 | return phy; | ||
343 | } | ||
344 | EXPORT_SYMBOL_GPL(of_phy_get); | ||
345 | |||
346 | /** | ||
320 | * phy_put() - release the PHY | 347 | * phy_put() - release the PHY |
321 | * @phy: the phy returned by phy_get() | 348 | * @phy: the phy returned by phy_get() |
322 | * | 349 | * |
@@ -407,7 +434,7 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
407 | if (dev->of_node) { | 434 | if (dev->of_node) { |
408 | index = of_property_match_string(dev->of_node, "phy-names", | 435 | index = of_property_match_string(dev->of_node, "phy-names", |
409 | string); | 436 | string); |
410 | phy = of_phy_get(dev, index); | 437 | phy = _of_phy_get(dev->of_node, index); |
411 | } else { | 438 | } else { |
412 | phy = phy_lookup(dev, string); | 439 | phy = phy_lookup(dev, string); |
413 | } | 440 | } |
@@ -499,6 +526,37 @@ struct phy *devm_phy_optional_get(struct device *dev, const char *string) | |||
499 | EXPORT_SYMBOL_GPL(devm_phy_optional_get); | 526 | EXPORT_SYMBOL_GPL(devm_phy_optional_get); |
500 | 527 | ||
501 | /** | 528 | /** |
529 | * devm_of_phy_get() - lookup and obtain a reference to a phy. | ||
530 | * @dev: device that requests this phy | ||
531 | * @np: node containing the phy | ||
532 | * @con_id: name of the phy from device's point of view | ||
533 | * | ||
534 | * Gets the phy using of_phy_get(), and associates a device with it using | ||
535 | * devres. On driver detach, release function is invoked on the devres data, | ||
536 | * then, devres data is freed. | ||
537 | */ | ||
538 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, | ||
539 | const char *con_id) | ||
540 | { | ||
541 | struct phy **ptr, *phy; | ||
542 | |||
543 | ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
544 | if (!ptr) | ||
545 | return ERR_PTR(-ENOMEM); | ||
546 | |||
547 | phy = of_phy_get(np, con_id); | ||
548 | if (!IS_ERR(phy)) { | ||
549 | *ptr = phy; | ||
550 | devres_add(dev, ptr); | ||
551 | } else { | ||
552 | devres_free(ptr); | ||
553 | } | ||
554 | |||
555 | return phy; | ||
556 | } | ||
557 | EXPORT_SYMBOL_GPL(devm_of_phy_get); | ||
558 | |||
559 | /** | ||
502 | * phy_create() - create a new phy | 560 | * phy_create() - create a new phy |
503 | * @dev: device that is creating the new phy | 561 | * @dev: device that is creating the new phy |
504 | * @ops: function pointers for performing phy operations | 562 | * @ops: function pointers for performing phy operations |
diff --git a/drivers/phy/phy-exynos4210-usb2.c b/drivers/phy/phy-exynos4210-usb2.c new file mode 100644 index 000000000000..236a52ad94eb --- /dev/null +++ b/drivers/phy/phy-exynos4210-usb2.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4210 support | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Kamil Debski <k.debski@samsung.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/delay.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/phy/phy.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include "phy-samsung-usb2.h" | ||
17 | |||
18 | /* Exynos USB PHY registers */ | ||
19 | |||
20 | /* PHY power control */ | ||
21 | #define EXYNOS_4210_UPHYPWR 0x0 | ||
22 | |||
23 | #define EXYNOS_4210_UPHYPWR_PHY0_SUSPEND BIT(0) | ||
24 | #define EXYNOS_4210_UPHYPWR_PHY0_PWR BIT(3) | ||
25 | #define EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR BIT(4) | ||
26 | #define EXYNOS_4210_UPHYPWR_PHY0_SLEEP BIT(5) | ||
27 | #define EXYNOS_4210_UPHYPWR_PHY0 ( \ | ||
28 | EXYNOS_4210_UPHYPWR_PHY0_SUSPEND | \ | ||
29 | EXYNOS_4210_UPHYPWR_PHY0_PWR | \ | ||
30 | EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR | \ | ||
31 | EXYNOS_4210_UPHYPWR_PHY0_SLEEP) | ||
32 | |||
33 | #define EXYNOS_4210_UPHYPWR_PHY1_SUSPEND BIT(6) | ||
34 | #define EXYNOS_4210_UPHYPWR_PHY1_PWR BIT(7) | ||
35 | #define EXYNOS_4210_UPHYPWR_PHY1_SLEEP BIT(8) | ||
36 | #define EXYNOS_4210_UPHYPWR_PHY1 ( \ | ||
37 | EXYNOS_4210_UPHYPWR_PHY1_SUSPEND | \ | ||
38 | EXYNOS_4210_UPHYPWR_PHY1_PWR | \ | ||
39 | EXYNOS_4210_UPHYPWR_PHY1_SLEEP) | ||
40 | |||
41 | #define EXYNOS_4210_UPHYPWR_HSIC0_SUSPEND BIT(9) | ||
42 | #define EXYNOS_4210_UPHYPWR_HSIC0_SLEEP BIT(10) | ||
43 | #define EXYNOS_4210_UPHYPWR_HSIC0 ( \ | ||
44 | EXYNOS_4210_UPHYPWR_HSIC0_SUSPEND | \ | ||
45 | EXYNOS_4210_UPHYPWR_HSIC0_SLEEP) | ||
46 | |||
47 | #define EXYNOS_4210_UPHYPWR_HSIC1_SUSPEND BIT(11) | ||
48 | #define EXYNOS_4210_UPHYPWR_HSIC1_SLEEP BIT(12) | ||
49 | #define EXYNOS_4210_UPHYPWR_HSIC1 ( \ | ||
50 | EXYNOS_4210_UPHYPWR_HSIC1_SUSPEND | \ | ||
51 | EXYNOS_4210_UPHYPWR_HSIC1_SLEEP) | ||
52 | |||
53 | /* PHY clock control */ | ||
54 | #define EXYNOS_4210_UPHYCLK 0x4 | ||
55 | |||
56 | #define EXYNOS_4210_UPHYCLK_PHYFSEL_MASK (0x3 << 0) | ||
57 | #define EXYNOS_4210_UPHYCLK_PHYFSEL_OFFSET 0 | ||
58 | #define EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0) | ||
59 | #define EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0) | ||
60 | #define EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) | ||
61 | |||
62 | #define EXYNOS_4210_UPHYCLK_PHY0_ID_PULLUP BIT(2) | ||
63 | #define EXYNOS_4210_UPHYCLK_PHY0_COMMON_ON BIT(4) | ||
64 | #define EXYNOS_4210_UPHYCLK_PHY1_COMMON_ON BIT(7) | ||
65 | |||
66 | /* PHY reset control */ | ||
67 | #define EXYNOS_4210_UPHYRST 0x8 | ||
68 | |||
69 | #define EXYNOS_4210_URSTCON_PHY0 BIT(0) | ||
70 | #define EXYNOS_4210_URSTCON_OTG_HLINK BIT(1) | ||
71 | #define EXYNOS_4210_URSTCON_OTG_PHYLINK BIT(2) | ||
72 | #define EXYNOS_4210_URSTCON_PHY1_ALL BIT(3) | ||
73 | #define EXYNOS_4210_URSTCON_PHY1_P0 BIT(4) | ||
74 | #define EXYNOS_4210_URSTCON_PHY1_P1P2 BIT(5) | ||
75 | #define EXYNOS_4210_URSTCON_HOST_LINK_ALL BIT(6) | ||
76 | #define EXYNOS_4210_URSTCON_HOST_LINK_P0 BIT(7) | ||
77 | #define EXYNOS_4210_URSTCON_HOST_LINK_P1 BIT(8) | ||
78 | #define EXYNOS_4210_URSTCON_HOST_LINK_P2 BIT(9) | ||
79 | |||
80 | /* Isolation, configured in the power management unit */ | ||
81 | #define EXYNOS_4210_USB_ISOL_DEVICE_OFFSET 0x704 | ||
82 | #define EXYNOS_4210_USB_ISOL_DEVICE BIT(0) | ||
83 | #define EXYNOS_4210_USB_ISOL_HOST_OFFSET 0x708 | ||
84 | #define EXYNOS_4210_USB_ISOL_HOST BIT(0) | ||
85 | |||
86 | /* USBYPHY1 Floating prevention */ | ||
87 | #define EXYNOS_4210_UPHY1CON 0x34 | ||
88 | #define EXYNOS_4210_UPHY1CON_FLOAT_PREVENTION 0x1 | ||
89 | |||
90 | /* Mode switching SUB Device <-> Host */ | ||
91 | #define EXYNOS_4210_MODE_SWITCH_OFFSET 0x21c | ||
92 | #define EXYNOS_4210_MODE_SWITCH_MASK 1 | ||
93 | #define EXYNOS_4210_MODE_SWITCH_DEVICE 0 | ||
94 | #define EXYNOS_4210_MODE_SWITCH_HOST 1 | ||
95 | |||
96 | enum exynos4210_phy_id { | ||
97 | EXYNOS4210_DEVICE, | ||
98 | EXYNOS4210_HOST, | ||
99 | EXYNOS4210_HSIC0, | ||
100 | EXYNOS4210_HSIC1, | ||
101 | EXYNOS4210_NUM_PHYS, | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * exynos4210_rate_to_clk() converts the supplied clock rate to the value that | ||
106 | * can be written to the phy register. | ||
107 | */ | ||
108 | static int exynos4210_rate_to_clk(unsigned long rate, u32 *reg) | ||
109 | { | ||
110 | switch (rate) { | ||
111 | case 12 * MHZ: | ||
112 | *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ; | ||
113 | break; | ||
114 | case 24 * MHZ: | ||
115 | *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ; | ||
116 | break; | ||
117 | case 48 * MHZ: | ||
118 | *reg = EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ; | ||
119 | break; | ||
120 | default: | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void exynos4210_isol(struct samsung_usb2_phy_instance *inst, bool on) | ||
128 | { | ||
129 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
130 | u32 offset; | ||
131 | u32 mask; | ||
132 | |||
133 | switch (inst->cfg->id) { | ||
134 | case EXYNOS4210_DEVICE: | ||
135 | offset = EXYNOS_4210_USB_ISOL_DEVICE_OFFSET; | ||
136 | mask = EXYNOS_4210_USB_ISOL_DEVICE; | ||
137 | break; | ||
138 | case EXYNOS4210_HOST: | ||
139 | offset = EXYNOS_4210_USB_ISOL_HOST_OFFSET; | ||
140 | mask = EXYNOS_4210_USB_ISOL_HOST; | ||
141 | break; | ||
142 | default: | ||
143 | return; | ||
144 | }; | ||
145 | |||
146 | regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); | ||
147 | } | ||
148 | |||
149 | static void exynos4210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) | ||
150 | { | ||
151 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
152 | u32 rstbits = 0; | ||
153 | u32 phypwr = 0; | ||
154 | u32 rst; | ||
155 | u32 pwr; | ||
156 | u32 clk; | ||
157 | |||
158 | switch (inst->cfg->id) { | ||
159 | case EXYNOS4210_DEVICE: | ||
160 | phypwr = EXYNOS_4210_UPHYPWR_PHY0; | ||
161 | rstbits = EXYNOS_4210_URSTCON_PHY0; | ||
162 | break; | ||
163 | case EXYNOS4210_HOST: | ||
164 | phypwr = EXYNOS_4210_UPHYPWR_PHY1; | ||
165 | rstbits = EXYNOS_4210_URSTCON_PHY1_ALL | | ||
166 | EXYNOS_4210_URSTCON_PHY1_P0 | | ||
167 | EXYNOS_4210_URSTCON_PHY1_P1P2 | | ||
168 | EXYNOS_4210_URSTCON_HOST_LINK_ALL | | ||
169 | EXYNOS_4210_URSTCON_HOST_LINK_P0; | ||
170 | writel(on, drv->reg_phy + EXYNOS_4210_UPHY1CON); | ||
171 | break; | ||
172 | case EXYNOS4210_HSIC0: | ||
173 | phypwr = EXYNOS_4210_UPHYPWR_HSIC0; | ||
174 | rstbits = EXYNOS_4210_URSTCON_PHY1_P1P2 | | ||
175 | EXYNOS_4210_URSTCON_HOST_LINK_P1; | ||
176 | break; | ||
177 | case EXYNOS4210_HSIC1: | ||
178 | phypwr = EXYNOS_4210_UPHYPWR_HSIC1; | ||
179 | rstbits = EXYNOS_4210_URSTCON_PHY1_P1P2 | | ||
180 | EXYNOS_4210_URSTCON_HOST_LINK_P2; | ||
181 | break; | ||
182 | }; | ||
183 | |||
184 | if (on) { | ||
185 | clk = readl(drv->reg_phy + EXYNOS_4210_UPHYCLK); | ||
186 | clk &= ~EXYNOS_4210_UPHYCLK_PHYFSEL_MASK; | ||
187 | clk |= drv->ref_reg_val << EXYNOS_4210_UPHYCLK_PHYFSEL_OFFSET; | ||
188 | writel(clk, drv->reg_phy + EXYNOS_4210_UPHYCLK); | ||
189 | |||
190 | pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR); | ||
191 | pwr &= ~phypwr; | ||
192 | writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR); | ||
193 | |||
194 | rst = readl(drv->reg_phy + EXYNOS_4210_UPHYRST); | ||
195 | rst |= rstbits; | ||
196 | writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST); | ||
197 | udelay(10); | ||
198 | rst &= ~rstbits; | ||
199 | writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST); | ||
200 | /* The following delay is necessary for the reset sequence to be | ||
201 | * completed */ | ||
202 | udelay(80); | ||
203 | } else { | ||
204 | pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR); | ||
205 | pwr |= phypwr; | ||
206 | writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static int exynos4210_power_on(struct samsung_usb2_phy_instance *inst) | ||
211 | { | ||
212 | /* Order of initialisation is important - first power then isolation */ | ||
213 | exynos4210_phy_pwr(inst, 1); | ||
214 | exynos4210_isol(inst, 0); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int exynos4210_power_off(struct samsung_usb2_phy_instance *inst) | ||
220 | { | ||
221 | exynos4210_isol(inst, 1); | ||
222 | exynos4210_phy_pwr(inst, 0); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | |||
228 | static const struct samsung_usb2_common_phy exynos4210_phys[] = { | ||
229 | { | ||
230 | .label = "device", | ||
231 | .id = EXYNOS4210_DEVICE, | ||
232 | .power_on = exynos4210_power_on, | ||
233 | .power_off = exynos4210_power_off, | ||
234 | }, | ||
235 | { | ||
236 | .label = "host", | ||
237 | .id = EXYNOS4210_HOST, | ||
238 | .power_on = exynos4210_power_on, | ||
239 | .power_off = exynos4210_power_off, | ||
240 | }, | ||
241 | { | ||
242 | .label = "hsic0", | ||
243 | .id = EXYNOS4210_HSIC0, | ||
244 | .power_on = exynos4210_power_on, | ||
245 | .power_off = exynos4210_power_off, | ||
246 | }, | ||
247 | { | ||
248 | .label = "hsic1", | ||
249 | .id = EXYNOS4210_HSIC1, | ||
250 | .power_on = exynos4210_power_on, | ||
251 | .power_off = exynos4210_power_off, | ||
252 | }, | ||
253 | {}, | ||
254 | }; | ||
255 | |||
256 | const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = { | ||
257 | .has_mode_switch = 0, | ||
258 | .num_phys = EXYNOS4210_NUM_PHYS, | ||
259 | .phys = exynos4210_phys, | ||
260 | .rate_to_clk = exynos4210_rate_to_clk, | ||
261 | }; | ||
diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c new file mode 100644 index 000000000000..d92a7cc5698a --- /dev/null +++ b/drivers/phy/phy-exynos4x12-usb2.c | |||
@@ -0,0 +1,328 @@ | |||
1 | /* | ||
2 | * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4x12 support | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Kamil Debski <k.debski@samsung.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/delay.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/phy/phy.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include "phy-samsung-usb2.h" | ||
17 | |||
18 | /* Exynos USB PHY registers */ | ||
19 | |||
20 | /* PHY power control */ | ||
21 | #define EXYNOS_4x12_UPHYPWR 0x0 | ||
22 | |||
23 | #define EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND BIT(0) | ||
24 | #define EXYNOS_4x12_UPHYPWR_PHY0_PWR BIT(3) | ||
25 | #define EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR BIT(4) | ||
26 | #define EXYNOS_4x12_UPHYPWR_PHY0_SLEEP BIT(5) | ||
27 | #define EXYNOS_4x12_UPHYPWR_PHY0 ( \ | ||
28 | EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND | \ | ||
29 | EXYNOS_4x12_UPHYPWR_PHY0_PWR | \ | ||
30 | EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR | \ | ||
31 | EXYNOS_4x12_UPHYPWR_PHY0_SLEEP) | ||
32 | |||
33 | #define EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND BIT(6) | ||
34 | #define EXYNOS_4x12_UPHYPWR_PHY1_PWR BIT(7) | ||
35 | #define EXYNOS_4x12_UPHYPWR_PHY1_SLEEP BIT(8) | ||
36 | #define EXYNOS_4x12_UPHYPWR_PHY1 ( \ | ||
37 | EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND | \ | ||
38 | EXYNOS_4x12_UPHYPWR_PHY1_PWR | \ | ||
39 | EXYNOS_4x12_UPHYPWR_PHY1_SLEEP) | ||
40 | |||
41 | #define EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND BIT(9) | ||
42 | #define EXYNOS_4x12_UPHYPWR_HSIC0_PWR BIT(10) | ||
43 | #define EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP BIT(11) | ||
44 | #define EXYNOS_4x12_UPHYPWR_HSIC0 ( \ | ||
45 | EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND | \ | ||
46 | EXYNOS_4x12_UPHYPWR_HSIC0_PWR | \ | ||
47 | EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP) | ||
48 | |||
49 | #define EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND BIT(12) | ||
50 | #define EXYNOS_4x12_UPHYPWR_HSIC1_PWR BIT(13) | ||
51 | #define EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP BIT(14) | ||
52 | #define EXYNOS_4x12_UPHYPWR_HSIC1 ( \ | ||
53 | EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND | \ | ||
54 | EXYNOS_4x12_UPHYPWR_HSIC1_PWR | \ | ||
55 | EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP) | ||
56 | |||
57 | /* PHY clock control */ | ||
58 | #define EXYNOS_4x12_UPHYCLK 0x4 | ||
59 | |||
60 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK (0x7 << 0) | ||
61 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET 0 | ||
62 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6 (0x0 << 0) | ||
63 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ (0x1 << 0) | ||
64 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0) | ||
65 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2 (0x3 << 0) | ||
66 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ (0x4 << 0) | ||
67 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0) | ||
68 | #define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0) | ||
69 | |||
70 | #define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3) | ||
71 | #define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4) | ||
72 | #define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7) | ||
73 | |||
74 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_MASK (0x7f << 10) | ||
75 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_OFFSET 10 | ||
76 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_12MHZ (0x24 << 10) | ||
77 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_15MHZ (0x1c << 10) | ||
78 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_16MHZ (0x1a << 10) | ||
79 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_19MHZ2 (0x15 << 10) | ||
80 | #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_20MHZ (0x14 << 10) | ||
81 | |||
82 | /* PHY reset control */ | ||
83 | #define EXYNOS_4x12_UPHYRST 0x8 | ||
84 | |||
85 | #define EXYNOS_4x12_URSTCON_PHY0 BIT(0) | ||
86 | #define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1) | ||
87 | #define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2) | ||
88 | #define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3) | ||
89 | #define EXYNOS_4x12_URSTCON_PHY1 BIT(4) | ||
90 | #define EXYNOS_4x12_URSTCON_HSIC0 BIT(5) | ||
91 | #define EXYNOS_4x12_URSTCON_HSIC1 BIT(6) | ||
92 | #define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7) | ||
93 | #define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8) | ||
94 | #define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9) | ||
95 | #define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(10) | ||
96 | |||
97 | /* Isolation, configured in the power management unit */ | ||
98 | #define EXYNOS_4x12_USB_ISOL_OFFSET 0x704 | ||
99 | #define EXYNOS_4x12_USB_ISOL_OTG BIT(0) | ||
100 | #define EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET 0x708 | ||
101 | #define EXYNOS_4x12_USB_ISOL_HSIC0 BIT(0) | ||
102 | #define EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET 0x70c | ||
103 | #define EXYNOS_4x12_USB_ISOL_HSIC1 BIT(0) | ||
104 | |||
105 | /* Mode switching SUB Device <-> Host */ | ||
106 | #define EXYNOS_4x12_MODE_SWITCH_OFFSET 0x21c | ||
107 | #define EXYNOS_4x12_MODE_SWITCH_MASK 1 | ||
108 | #define EXYNOS_4x12_MODE_SWITCH_DEVICE 0 | ||
109 | #define EXYNOS_4x12_MODE_SWITCH_HOST 1 | ||
110 | |||
111 | enum exynos4x12_phy_id { | ||
112 | EXYNOS4x12_DEVICE, | ||
113 | EXYNOS4x12_HOST, | ||
114 | EXYNOS4x12_HSIC0, | ||
115 | EXYNOS4x12_HSIC1, | ||
116 | EXYNOS4x12_NUM_PHYS, | ||
117 | }; | ||
118 | |||
119 | /* | ||
120 | * exynos4x12_rate_to_clk() converts the supplied clock rate to the value that | ||
121 | * can be written to the phy register. | ||
122 | */ | ||
123 | static int exynos4x12_rate_to_clk(unsigned long rate, u32 *reg) | ||
124 | { | ||
125 | /* EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK */ | ||
126 | |||
127 | switch (rate) { | ||
128 | case 9600 * KHZ: | ||
129 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6; | ||
130 | break; | ||
131 | case 10 * MHZ: | ||
132 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ; | ||
133 | break; | ||
134 | case 12 * MHZ: | ||
135 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ; | ||
136 | break; | ||
137 | case 19200 * KHZ: | ||
138 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2; | ||
139 | break; | ||
140 | case 20 * MHZ: | ||
141 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ; | ||
142 | break; | ||
143 | case 24 * MHZ: | ||
144 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ; | ||
145 | break; | ||
146 | case 50 * MHZ: | ||
147 | *reg = EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ; | ||
148 | break; | ||
149 | default: | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static void exynos4x12_isol(struct samsung_usb2_phy_instance *inst, bool on) | ||
157 | { | ||
158 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
159 | u32 offset; | ||
160 | u32 mask; | ||
161 | |||
162 | switch (inst->cfg->id) { | ||
163 | case EXYNOS4x12_DEVICE: | ||
164 | case EXYNOS4x12_HOST: | ||
165 | offset = EXYNOS_4x12_USB_ISOL_OFFSET; | ||
166 | mask = EXYNOS_4x12_USB_ISOL_OTG; | ||
167 | break; | ||
168 | case EXYNOS4x12_HSIC0: | ||
169 | offset = EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET; | ||
170 | mask = EXYNOS_4x12_USB_ISOL_HSIC0; | ||
171 | break; | ||
172 | case EXYNOS4x12_HSIC1: | ||
173 | offset = EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET; | ||
174 | mask = EXYNOS_4x12_USB_ISOL_HSIC1; | ||
175 | break; | ||
176 | default: | ||
177 | return; | ||
178 | }; | ||
179 | |||
180 | regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); | ||
181 | } | ||
182 | |||
183 | static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst) | ||
184 | { | ||
185 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
186 | u32 clk; | ||
187 | |||
188 | clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK); | ||
189 | clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK; | ||
190 | clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET; | ||
191 | writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK); | ||
192 | } | ||
193 | |||
194 | static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) | ||
195 | { | ||
196 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
197 | u32 rstbits = 0; | ||
198 | u32 phypwr = 0; | ||
199 | u32 rst; | ||
200 | u32 pwr; | ||
201 | u32 mode = 0; | ||
202 | u32 switch_mode = 0; | ||
203 | |||
204 | switch (inst->cfg->id) { | ||
205 | case EXYNOS4x12_DEVICE: | ||
206 | phypwr = EXYNOS_4x12_UPHYPWR_PHY0; | ||
207 | rstbits = EXYNOS_4x12_URSTCON_PHY0; | ||
208 | mode = EXYNOS_4x12_MODE_SWITCH_DEVICE; | ||
209 | switch_mode = 1; | ||
210 | break; | ||
211 | case EXYNOS4x12_HOST: | ||
212 | phypwr = EXYNOS_4x12_UPHYPWR_PHY1; | ||
213 | rstbits = EXYNOS_4x12_URSTCON_HOST_PHY; | ||
214 | mode = EXYNOS_4x12_MODE_SWITCH_HOST; | ||
215 | switch_mode = 1; | ||
216 | break; | ||
217 | case EXYNOS4x12_HSIC0: | ||
218 | phypwr = EXYNOS_4x12_UPHYPWR_HSIC0; | ||
219 | rstbits = EXYNOS_4x12_URSTCON_HSIC1 | | ||
220 | EXYNOS_4x12_URSTCON_HOST_LINK_P0 | | ||
221 | EXYNOS_4x12_URSTCON_HOST_PHY; | ||
222 | break; | ||
223 | case EXYNOS4x12_HSIC1: | ||
224 | phypwr = EXYNOS_4x12_UPHYPWR_HSIC1; | ||
225 | rstbits = EXYNOS_4x12_URSTCON_HSIC1 | | ||
226 | EXYNOS_4x12_URSTCON_HOST_LINK_P1; | ||
227 | break; | ||
228 | }; | ||
229 | |||
230 | if (on) { | ||
231 | if (switch_mode) | ||
232 | regmap_update_bits(drv->reg_sys, | ||
233 | EXYNOS_4x12_MODE_SWITCH_OFFSET, | ||
234 | EXYNOS_4x12_MODE_SWITCH_MASK, mode); | ||
235 | |||
236 | pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); | ||
237 | pwr &= ~phypwr; | ||
238 | writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); | ||
239 | |||
240 | rst = readl(drv->reg_phy + EXYNOS_4x12_UPHYRST); | ||
241 | rst |= rstbits; | ||
242 | writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); | ||
243 | udelay(10); | ||
244 | rst &= ~rstbits; | ||
245 | writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); | ||
246 | /* The following delay is necessary for the reset sequence to be | ||
247 | * completed */ | ||
248 | udelay(80); | ||
249 | } else { | ||
250 | pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); | ||
251 | pwr |= phypwr; | ||
252 | writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst) | ||
257 | { | ||
258 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
259 | |||
260 | inst->enabled = 1; | ||
261 | exynos4x12_setup_clk(inst); | ||
262 | exynos4x12_phy_pwr(inst, 1); | ||
263 | exynos4x12_isol(inst, 0); | ||
264 | |||
265 | /* Power on the device, as it is necessary for HSIC to work */ | ||
266 | if (inst->cfg->id == EXYNOS4x12_HSIC0) { | ||
267 | struct samsung_usb2_phy_instance *device = | ||
268 | &drv->instances[EXYNOS4x12_DEVICE]; | ||
269 | exynos4x12_phy_pwr(device, 1); | ||
270 | exynos4x12_isol(device, 0); | ||
271 | } | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst) | ||
277 | { | ||
278 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
279 | struct samsung_usb2_phy_instance *device = | ||
280 | &drv->instances[EXYNOS4x12_DEVICE]; | ||
281 | |||
282 | inst->enabled = 0; | ||
283 | exynos4x12_isol(inst, 1); | ||
284 | exynos4x12_phy_pwr(inst, 0); | ||
285 | |||
286 | if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) { | ||
287 | exynos4x12_isol(device, 1); | ||
288 | exynos4x12_phy_pwr(device, 0); | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | |||
295 | static const struct samsung_usb2_common_phy exynos4x12_phys[] = { | ||
296 | { | ||
297 | .label = "device", | ||
298 | .id = EXYNOS4x12_DEVICE, | ||
299 | .power_on = exynos4x12_power_on, | ||
300 | .power_off = exynos4x12_power_off, | ||
301 | }, | ||
302 | { | ||
303 | .label = "host", | ||
304 | .id = EXYNOS4x12_HOST, | ||
305 | .power_on = exynos4x12_power_on, | ||
306 | .power_off = exynos4x12_power_off, | ||
307 | }, | ||
308 | { | ||
309 | .label = "hsic0", | ||
310 | .id = EXYNOS4x12_HSIC0, | ||
311 | .power_on = exynos4x12_power_on, | ||
312 | .power_off = exynos4x12_power_off, | ||
313 | }, | ||
314 | { | ||
315 | .label = "hsic1", | ||
316 | .id = EXYNOS4x12_HSIC1, | ||
317 | .power_on = exynos4x12_power_on, | ||
318 | .power_off = exynos4x12_power_off, | ||
319 | }, | ||
320 | {}, | ||
321 | }; | ||
322 | |||
323 | const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config = { | ||
324 | .has_mode_switch = 1, | ||
325 | .num_phys = EXYNOS4x12_NUM_PHYS, | ||
326 | .phys = exynos4x12_phys, | ||
327 | .rate_to_clk = exynos4x12_rate_to_clk, | ||
328 | }; | ||
diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c new file mode 100644 index 000000000000..c9361b731fa6 --- /dev/null +++ b/drivers/phy/phy-exynos5250-sata.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* | ||
2 | * Samsung SATA SerDes(PHY) driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Authors: Girish K S <ks.giri@samsung.com> | ||
6 | * Yuvaraj Kumar C D <yuvaraj.cd@samsung.com> | ||
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 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/phy/phy.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/mfd/syscon.h> | ||
26 | |||
27 | #define SATAPHY_CONTROL_OFFSET 0x0724 | ||
28 | #define EXYNOS5_SATAPHY_PMU_ENABLE BIT(0) | ||
29 | #define EXYNOS5_SATA_RESET 0x4 | ||
30 | #define RESET_GLOBAL_RST_N BIT(0) | ||
31 | #define RESET_CMN_RST_N BIT(1) | ||
32 | #define RESET_CMN_BLOCK_RST_N BIT(2) | ||
33 | #define RESET_CMN_I2C_RST_N BIT(3) | ||
34 | #define RESET_TX_RX_PIPE_RST_N BIT(4) | ||
35 | #define RESET_TX_RX_BLOCK_RST_N BIT(5) | ||
36 | #define RESET_TX_RX_I2C_RST_N (BIT(6) | BIT(7)) | ||
37 | #define LINK_RESET 0xf0000 | ||
38 | #define EXYNOS5_SATA_MODE0 0x10 | ||
39 | #define SATA_SPD_GEN3 BIT(1) | ||
40 | #define EXYNOS5_SATA_CTRL0 0x14 | ||
41 | #define CTRL0_P0_PHY_CALIBRATED_SEL BIT(9) | ||
42 | #define CTRL0_P0_PHY_CALIBRATED BIT(8) | ||
43 | #define EXYNOS5_SATA_PHSATA_CTRLM 0xe0 | ||
44 | #define PHCTRLM_REF_RATE BIT(1) | ||
45 | #define PHCTRLM_HIGH_SPEED BIT(0) | ||
46 | #define EXYNOS5_SATA_PHSATA_STATM 0xf0 | ||
47 | #define PHSTATM_PLL_LOCKED BIT(0) | ||
48 | |||
49 | #define PHY_PLL_TIMEOUT (usecs_to_jiffies(1000)) | ||
50 | |||
51 | struct exynos_sata_phy { | ||
52 | struct phy *phy; | ||
53 | struct clk *phyclk; | ||
54 | void __iomem *regs; | ||
55 | struct regmap *pmureg; | ||
56 | struct i2c_client *client; | ||
57 | }; | ||
58 | |||
59 | static int wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit, | ||
60 | u32 status) | ||
61 | { | ||
62 | unsigned long timeout = jiffies + PHY_PLL_TIMEOUT; | ||
63 | |||
64 | while (time_before(jiffies, timeout)) { | ||
65 | if ((readl(base + reg) & checkbit) == status) | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | return -EFAULT; | ||
70 | } | ||
71 | |||
72 | static int exynos_sata_phy_power_on(struct phy *phy) | ||
73 | { | ||
74 | struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); | ||
75 | |||
76 | return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, | ||
77 | EXYNOS5_SATAPHY_PMU_ENABLE, true); | ||
78 | |||
79 | } | ||
80 | |||
81 | static int exynos_sata_phy_power_off(struct phy *phy) | ||
82 | { | ||
83 | struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); | ||
84 | |||
85 | return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, | ||
86 | EXYNOS5_SATAPHY_PMU_ENABLE, false); | ||
87 | |||
88 | } | ||
89 | |||
90 | static int exynos_sata_phy_init(struct phy *phy) | ||
91 | { | ||
92 | u32 val = 0; | ||
93 | int ret = 0; | ||
94 | u8 buf[] = { 0x3a, 0x0b }; | ||
95 | struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy); | ||
96 | |||
97 | ret = regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET, | ||
98 | EXYNOS5_SATAPHY_PMU_ENABLE, true); | ||
99 | if (ret != 0) | ||
100 | dev_err(&sata_phy->phy->dev, "phy init failed\n"); | ||
101 | |||
102 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
103 | |||
104 | val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); | ||
105 | val |= RESET_GLOBAL_RST_N | RESET_CMN_RST_N | RESET_CMN_BLOCK_RST_N | ||
106 | | RESET_CMN_I2C_RST_N | RESET_TX_RX_PIPE_RST_N | ||
107 | | RESET_TX_RX_BLOCK_RST_N | RESET_TX_RX_I2C_RST_N; | ||
108 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
109 | |||
110 | val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); | ||
111 | val |= LINK_RESET; | ||
112 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
113 | |||
114 | val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); | ||
115 | val |= RESET_CMN_RST_N; | ||
116 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
117 | |||
118 | val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); | ||
119 | val &= ~PHCTRLM_REF_RATE; | ||
120 | writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); | ||
121 | |||
122 | /* High speed enable for Gen3 */ | ||
123 | val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); | ||
124 | val |= PHCTRLM_HIGH_SPEED; | ||
125 | writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM); | ||
126 | |||
127 | val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0); | ||
128 | val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED; | ||
129 | writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0); | ||
130 | |||
131 | val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0); | ||
132 | val |= SATA_SPD_GEN3; | ||
133 | writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0); | ||
134 | |||
135 | ret = i2c_master_send(sata_phy->client, buf, sizeof(buf)); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | /* release cmu reset */ | ||
140 | val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); | ||
141 | val &= ~RESET_CMN_RST_N; | ||
142 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
143 | |||
144 | val = readl(sata_phy->regs + EXYNOS5_SATA_RESET); | ||
145 | val |= RESET_CMN_RST_N; | ||
146 | writel(val, sata_phy->regs + EXYNOS5_SATA_RESET); | ||
147 | |||
148 | ret = wait_for_reg_status(sata_phy->regs, | ||
149 | EXYNOS5_SATA_PHSATA_STATM, | ||
150 | PHSTATM_PLL_LOCKED, 1); | ||
151 | if (ret < 0) | ||
152 | dev_err(&sata_phy->phy->dev, | ||
153 | "PHY PLL locking failed\n"); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | static struct phy_ops exynos_sata_phy_ops = { | ||
158 | .init = exynos_sata_phy_init, | ||
159 | .power_on = exynos_sata_phy_power_on, | ||
160 | .power_off = exynos_sata_phy_power_off, | ||
161 | .owner = THIS_MODULE, | ||
162 | }; | ||
163 | |||
164 | static int exynos_sata_phy_probe(struct platform_device *pdev) | ||
165 | { | ||
166 | struct exynos_sata_phy *sata_phy; | ||
167 | struct device *dev = &pdev->dev; | ||
168 | struct resource *res; | ||
169 | struct phy_provider *phy_provider; | ||
170 | struct device_node *node; | ||
171 | int ret = 0; | ||
172 | |||
173 | sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL); | ||
174 | if (!sata_phy) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
178 | |||
179 | sata_phy->regs = devm_ioremap_resource(dev, res); | ||
180 | if (IS_ERR(sata_phy->regs)) | ||
181 | return PTR_ERR(sata_phy->regs); | ||
182 | |||
183 | sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, | ||
184 | "samsung,syscon-phandle"); | ||
185 | if (IS_ERR(sata_phy->pmureg)) { | ||
186 | dev_err(dev, "syscon regmap lookup failed.\n"); | ||
187 | return PTR_ERR(sata_phy->pmureg); | ||
188 | } | ||
189 | |||
190 | node = of_parse_phandle(dev->of_node, | ||
191 | "samsung,exynos-sataphy-i2c-phandle", 0); | ||
192 | if (!node) | ||
193 | return -EINVAL; | ||
194 | |||
195 | sata_phy->client = of_find_i2c_device_by_node(node); | ||
196 | if (!sata_phy->client) | ||
197 | return -EPROBE_DEFER; | ||
198 | |||
199 | dev_set_drvdata(dev, sata_phy); | ||
200 | |||
201 | sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl"); | ||
202 | if (IS_ERR(sata_phy->phyclk)) { | ||
203 | dev_err(dev, "failed to get clk for PHY\n"); | ||
204 | return PTR_ERR(sata_phy->phyclk); | ||
205 | } | ||
206 | |||
207 | ret = clk_prepare_enable(sata_phy->phyclk); | ||
208 | if (ret < 0) { | ||
209 | dev_err(dev, "failed to enable source clk\n"); | ||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | sata_phy->phy = devm_phy_create(dev, &exynos_sata_phy_ops, NULL); | ||
214 | if (IS_ERR(sata_phy->phy)) { | ||
215 | clk_disable_unprepare(sata_phy->phyclk); | ||
216 | dev_err(dev, "failed to create PHY\n"); | ||
217 | return PTR_ERR(sata_phy->phy); | ||
218 | } | ||
219 | |||
220 | phy_set_drvdata(sata_phy->phy, sata_phy); | ||
221 | |||
222 | phy_provider = devm_of_phy_provider_register(dev, | ||
223 | of_phy_simple_xlate); | ||
224 | if (IS_ERR(phy_provider)) { | ||
225 | clk_disable_unprepare(sata_phy->phyclk); | ||
226 | return PTR_ERR(phy_provider); | ||
227 | } | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static const struct of_device_id exynos_sata_phy_of_match[] = { | ||
233 | { .compatible = "samsung,exynos5250-sata-phy" }, | ||
234 | { }, | ||
235 | }; | ||
236 | MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match); | ||
237 | |||
238 | static struct platform_driver exynos_sata_phy_driver = { | ||
239 | .probe = exynos_sata_phy_probe, | ||
240 | .driver = { | ||
241 | .of_match_table = exynos_sata_phy_of_match, | ||
242 | .name = "samsung,sata-phy", | ||
243 | .owner = THIS_MODULE, | ||
244 | } | ||
245 | }; | ||
246 | module_platform_driver(exynos_sata_phy_driver); | ||
247 | |||
248 | MODULE_DESCRIPTION("Samsung SerDes PHY driver"); | ||
249 | MODULE_LICENSE("GPL V2"); | ||
250 | MODULE_AUTHOR("Girish K S <ks.giri@samsung.com>"); | ||
251 | MODULE_AUTHOR("Yuvaraj C D <yuvaraj.cd@samsung.com>"); | ||
diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c new file mode 100644 index 000000000000..94179afda951 --- /dev/null +++ b/drivers/phy/phy-exynos5250-usb2.c | |||
@@ -0,0 +1,404 @@ | |||
1 | /* | ||
2 | * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Kamil Debski <k.debski@samsung.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/delay.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/phy/phy.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include "phy-samsung-usb2.h" | ||
17 | |||
18 | /* Exynos USB PHY registers */ | ||
19 | #define EXYNOS_5250_REFCLKSEL_CRYSTAL 0x0 | ||
20 | #define EXYNOS_5250_REFCLKSEL_XO 0x1 | ||
21 | #define EXYNOS_5250_REFCLKSEL_CLKCORE 0x2 | ||
22 | |||
23 | #define EXYNOS_5250_FSEL_9MHZ6 0x0 | ||
24 | #define EXYNOS_5250_FSEL_10MHZ 0x1 | ||
25 | #define EXYNOS_5250_FSEL_12MHZ 0x2 | ||
26 | #define EXYNOS_5250_FSEL_19MHZ2 0x3 | ||
27 | #define EXYNOS_5250_FSEL_20MHZ 0x4 | ||
28 | #define EXYNOS_5250_FSEL_24MHZ 0x5 | ||
29 | #define EXYNOS_5250_FSEL_50MHZ 0x7 | ||
30 | |||
31 | /* Normal host */ | ||
32 | #define EXYNOS_5250_HOSTPHYCTRL0 0x0 | ||
33 | |||
34 | #define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL BIT(31) | ||
35 | #define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT 19 | ||
36 | #define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_MASK \ | ||
37 | (0x3 << EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT) | ||
38 | #define EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT 16 | ||
39 | #define EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK \ | ||
40 | (0x7 << EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT) | ||
41 | #define EXYNOS_5250_HOSTPHYCTRL0_TESTBURNIN BIT(11) | ||
42 | #define EXYNOS_5250_HOSTPHYCTRL0_RETENABLE BIT(10) | ||
43 | #define EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N BIT(9) | ||
44 | #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_MASK (0x3 << 7) | ||
45 | #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_DUAL (0x0 << 7) | ||
46 | #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ID0 (0x1 << 7) | ||
47 | #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ANALOGTEST (0x2 << 7) | ||
48 | #define EXYNOS_5250_HOSTPHYCTRL0_SIDDQ BIT(6) | ||
49 | #define EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP BIT(5) | ||
50 | #define EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND BIT(4) | ||
51 | #define EXYNOS_5250_HOSTPHYCTRL0_WORDINTERFACE BIT(3) | ||
52 | #define EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST BIT(2) | ||
53 | #define EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST BIT(1) | ||
54 | #define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST BIT(0) | ||
55 | |||
56 | /* HSIC0 & HSIC1 */ | ||
57 | #define EXYNOS_5250_HSICPHYCTRL1 0x10 | ||
58 | #define EXYNOS_5250_HSICPHYCTRL2 0x20 | ||
59 | |||
60 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_MASK (0x3 << 23) | ||
61 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT (0x2 << 23) | ||
62 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_MASK (0x7f << 16) | ||
63 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 (0x24 << 16) | ||
64 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_15 (0x1c << 16) | ||
65 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_16 (0x1a << 16) | ||
66 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_19_2 (0x15 << 16) | ||
67 | #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_20 (0x14 << 16) | ||
68 | #define EXYNOS_5250_HSICPHYCTRLX_SIDDQ BIT(6) | ||
69 | #define EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP BIT(5) | ||
70 | #define EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND BIT(4) | ||
71 | #define EXYNOS_5250_HSICPHYCTRLX_WORDINTERFACE BIT(3) | ||
72 | #define EXYNOS_5250_HSICPHYCTRLX_UTMISWRST BIT(2) | ||
73 | #define EXYNOS_5250_HSICPHYCTRLX_PHYSWRST BIT(0) | ||
74 | |||
75 | /* EHCI control */ | ||
76 | #define EXYNOS_5250_HOSTEHCICTRL 0x30 | ||
77 | #define EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN BIT(29) | ||
78 | #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 BIT(28) | ||
79 | #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 BIT(27) | ||
80 | #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR16 BIT(26) | ||
81 | #define EXYNOS_5250_HOSTEHCICTRL_AUTOPPDONOVRCUREN BIT(25) | ||
82 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT 19 | ||
83 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ | ||
84 | (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) | ||
85 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT 13 | ||
86 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_MASK \ | ||
87 | (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT) | ||
88 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL2_SHIFT 7 | ||
89 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \ | ||
90 | (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT) | ||
91 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT 1 | ||
92 | #define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_MASK \ | ||
93 | (0x1 << EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT) | ||
94 | #define EXYNOS_5250_HOSTEHCICTRL_SIMULATIONMODE BIT(0) | ||
95 | |||
96 | /* OHCI control */ | ||
97 | #define EXYNOS_5250_HOSTOHCICTRL 0x34 | ||
98 | #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT 1 | ||
99 | #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_MASK \ | ||
100 | (0x3ff << EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT) | ||
101 | #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVALEN BIT(0) | ||
102 | |||
103 | /* USBOTG */ | ||
104 | #define EXYNOS_5250_USBOTGSYS 0x38 | ||
105 | #define EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET BIT(14) | ||
106 | #define EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG BIT(13) | ||
107 | #define EXYNOS_5250_USBOTGSYS_PHY_SW_RST BIT(12) | ||
108 | #define EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT 9 | ||
109 | #define EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK \ | ||
110 | (0x3 << EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT) | ||
111 | #define EXYNOS_5250_USBOTGSYS_ID_PULLUP BIT(8) | ||
112 | #define EXYNOS_5250_USBOTGSYS_COMMON_ON BIT(7) | ||
113 | #define EXYNOS_5250_USBOTGSYS_FSEL_SHIFT 4 | ||
114 | #define EXYNOS_5250_USBOTGSYS_FSEL_MASK \ | ||
115 | (0x3 << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT) | ||
116 | #define EXYNOS_5250_USBOTGSYS_FORCE_SLEEP BIT(3) | ||
117 | #define EXYNOS_5250_USBOTGSYS_OTGDISABLE BIT(2) | ||
118 | #define EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG BIT(1) | ||
119 | #define EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND BIT(0) | ||
120 | |||
121 | /* Isolation, configured in the power management unit */ | ||
122 | #define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704 | ||
123 | #define EXYNOS_5250_USB_ISOL_OTG BIT(0) | ||
124 | #define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708 | ||
125 | #define EXYNOS_5250_USB_ISOL_HOST BIT(0) | ||
126 | |||
127 | /* Mode swtich register */ | ||
128 | #define EXYNOS_5250_MODE_SWITCH_OFFSET 0x230 | ||
129 | #define EXYNOS_5250_MODE_SWITCH_MASK 1 | ||
130 | #define EXYNOS_5250_MODE_SWITCH_DEVICE 0 | ||
131 | #define EXYNOS_5250_MODE_SWITCH_HOST 1 | ||
132 | |||
133 | enum exynos4x12_phy_id { | ||
134 | EXYNOS5250_DEVICE, | ||
135 | EXYNOS5250_HOST, | ||
136 | EXYNOS5250_HSIC0, | ||
137 | EXYNOS5250_HSIC1, | ||
138 | EXYNOS5250_NUM_PHYS, | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * exynos5250_rate_to_clk() converts the supplied clock rate to the value that | ||
143 | * can be written to the phy register. | ||
144 | */ | ||
145 | static int exynos5250_rate_to_clk(unsigned long rate, u32 *reg) | ||
146 | { | ||
147 | /* EXYNOS_5250_FSEL_MASK */ | ||
148 | |||
149 | switch (rate) { | ||
150 | case 9600 * KHZ: | ||
151 | *reg = EXYNOS_5250_FSEL_9MHZ6; | ||
152 | break; | ||
153 | case 10 * MHZ: | ||
154 | *reg = EXYNOS_5250_FSEL_10MHZ; | ||
155 | break; | ||
156 | case 12 * MHZ: | ||
157 | *reg = EXYNOS_5250_FSEL_12MHZ; | ||
158 | break; | ||
159 | case 19200 * KHZ: | ||
160 | *reg = EXYNOS_5250_FSEL_19MHZ2; | ||
161 | break; | ||
162 | case 20 * MHZ: | ||
163 | *reg = EXYNOS_5250_FSEL_20MHZ; | ||
164 | break; | ||
165 | case 24 * MHZ: | ||
166 | *reg = EXYNOS_5250_FSEL_24MHZ; | ||
167 | break; | ||
168 | case 50 * MHZ: | ||
169 | *reg = EXYNOS_5250_FSEL_50MHZ; | ||
170 | break; | ||
171 | default: | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on) | ||
179 | { | ||
180 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
181 | u32 offset; | ||
182 | u32 mask; | ||
183 | |||
184 | switch (inst->cfg->id) { | ||
185 | case EXYNOS5250_DEVICE: | ||
186 | offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET; | ||
187 | mask = EXYNOS_5250_USB_ISOL_OTG; | ||
188 | break; | ||
189 | case EXYNOS5250_HOST: | ||
190 | offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET; | ||
191 | mask = EXYNOS_5250_USB_ISOL_HOST; | ||
192 | break; | ||
193 | default: | ||
194 | return; | ||
195 | }; | ||
196 | |||
197 | regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask); | ||
198 | } | ||
199 | |||
200 | static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst) | ||
201 | { | ||
202 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
203 | u32 ctrl0; | ||
204 | u32 otg; | ||
205 | u32 ehci; | ||
206 | u32 ohci; | ||
207 | u32 hsic; | ||
208 | |||
209 | switch (inst->cfg->id) { | ||
210 | case EXYNOS5250_DEVICE: | ||
211 | regmap_update_bits(drv->reg_sys, | ||
212 | EXYNOS_5250_MODE_SWITCH_OFFSET, | ||
213 | EXYNOS_5250_MODE_SWITCH_MASK, | ||
214 | EXYNOS_5250_MODE_SWITCH_DEVICE); | ||
215 | |||
216 | /* OTG configuration */ | ||
217 | otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
218 | /* The clock */ | ||
219 | otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; | ||
220 | otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; | ||
221 | /* Reset */ | ||
222 | otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | | ||
223 | EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | | ||
224 | EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); | ||
225 | otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | | ||
226 | EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | | ||
227 | EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | | ||
228 | EXYNOS_5250_USBOTGSYS_OTGDISABLE; | ||
229 | /* Ref clock */ | ||
230 | otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; | ||
231 | otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << | ||
232 | EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; | ||
233 | writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
234 | udelay(100); | ||
235 | otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | | ||
236 | EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | | ||
237 | EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | | ||
238 | EXYNOS_5250_USBOTGSYS_OTGDISABLE); | ||
239 | writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
240 | |||
241 | |||
242 | break; | ||
243 | case EXYNOS5250_HOST: | ||
244 | case EXYNOS5250_HSIC0: | ||
245 | case EXYNOS5250_HSIC1: | ||
246 | /* Host registers configuration */ | ||
247 | ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); | ||
248 | /* The clock */ | ||
249 | ctrl0 &= ~EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK; | ||
250 | ctrl0 |= drv->ref_reg_val << | ||
251 | EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT; | ||
252 | |||
253 | /* Reset */ | ||
254 | ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | | ||
255 | EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL | | ||
256 | EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | | ||
257 | EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | | ||
258 | EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP); | ||
259 | ctrl0 |= EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | | ||
260 | EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST | | ||
261 | EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N; | ||
262 | writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); | ||
263 | udelay(10); | ||
264 | ctrl0 &= ~(EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST | | ||
265 | EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST); | ||
266 | writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); | ||
267 | |||
268 | /* OTG configuration */ | ||
269 | otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
270 | /* The clock */ | ||
271 | otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK; | ||
272 | otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT; | ||
273 | /* Reset */ | ||
274 | otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | | ||
275 | EXYNOS_5250_USBOTGSYS_FORCE_SLEEP | | ||
276 | EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG); | ||
277 | otg |= EXYNOS_5250_USBOTGSYS_PHY_SW_RST | | ||
278 | EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET | | ||
279 | EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | | ||
280 | EXYNOS_5250_USBOTGSYS_OTGDISABLE; | ||
281 | /* Ref clock */ | ||
282 | otg &= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK; | ||
283 | otg |= EXYNOS_5250_REFCLKSEL_CLKCORE << | ||
284 | EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT; | ||
285 | writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
286 | udelay(10); | ||
287 | otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST | | ||
288 | EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG | | ||
289 | EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET); | ||
290 | |||
291 | /* HSIC phy configuration */ | ||
292 | hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | | ||
293 | EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | | ||
294 | EXYNOS_5250_HSICPHYCTRLX_PHYSWRST); | ||
295 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); | ||
296 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); | ||
297 | udelay(10); | ||
298 | hsic &= ~EXYNOS_5250_HSICPHYCTRLX_PHYSWRST; | ||
299 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); | ||
300 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); | ||
301 | /* The following delay is necessary for the reset sequence to be | ||
302 | * completed */ | ||
303 | udelay(80); | ||
304 | |||
305 | /* Enable EHCI DMA burst */ | ||
306 | ehci = readl(drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); | ||
307 | ehci |= EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN | | ||
308 | EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 | | ||
309 | EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 | | ||
310 | EXYNOS_5250_HOSTEHCICTRL_ENAINCR16; | ||
311 | writel(ehci, drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL); | ||
312 | |||
313 | /* OHCI settings */ | ||
314 | ohci = readl(drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); | ||
315 | /* Following code is based on the old driver */ | ||
316 | ohci |= 0x1 << 3; | ||
317 | writel(ohci, drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL); | ||
318 | |||
319 | break; | ||
320 | } | ||
321 | inst->enabled = 1; | ||
322 | exynos5250_isol(inst, 0); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst) | ||
328 | { | ||
329 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
330 | u32 ctrl0; | ||
331 | u32 otg; | ||
332 | u32 hsic; | ||
333 | |||
334 | inst->enabled = 0; | ||
335 | exynos5250_isol(inst, 1); | ||
336 | |||
337 | switch (inst->cfg->id) { | ||
338 | case EXYNOS5250_DEVICE: | ||
339 | otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
340 | otg |= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND | | ||
341 | EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG | | ||
342 | EXYNOS_5250_USBOTGSYS_FORCE_SLEEP); | ||
343 | writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS); | ||
344 | break; | ||
345 | case EXYNOS5250_HOST: | ||
346 | ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); | ||
347 | ctrl0 |= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ | | ||
348 | EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND | | ||
349 | EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP | | ||
350 | EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST | | ||
351 | EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL); | ||
352 | writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0); | ||
353 | break; | ||
354 | case EXYNOS5250_HSIC0: | ||
355 | case EXYNOS5250_HSIC1: | ||
356 | hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 | | ||
357 | EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT | | ||
358 | EXYNOS_5250_HSICPHYCTRLX_SIDDQ | | ||
359 | EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP | | ||
360 | EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND | ||
361 | ); | ||
362 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1); | ||
363 | writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2); | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | |||
371 | static const struct samsung_usb2_common_phy exynos5250_phys[] = { | ||
372 | { | ||
373 | .label = "device", | ||
374 | .id = EXYNOS5250_DEVICE, | ||
375 | .power_on = exynos5250_power_on, | ||
376 | .power_off = exynos5250_power_off, | ||
377 | }, | ||
378 | { | ||
379 | .label = "host", | ||
380 | .id = EXYNOS5250_HOST, | ||
381 | .power_on = exynos5250_power_on, | ||
382 | .power_off = exynos5250_power_off, | ||
383 | }, | ||
384 | { | ||
385 | .label = "hsic0", | ||
386 | .id = EXYNOS5250_HSIC0, | ||
387 | .power_on = exynos5250_power_on, | ||
388 | .power_off = exynos5250_power_off, | ||
389 | }, | ||
390 | { | ||
391 | .label = "hsic1", | ||
392 | .id = EXYNOS5250_HSIC1, | ||
393 | .power_on = exynos5250_power_on, | ||
394 | .power_off = exynos5250_power_off, | ||
395 | }, | ||
396 | {}, | ||
397 | }; | ||
398 | |||
399 | const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = { | ||
400 | .has_mode_switch = 1, | ||
401 | .num_phys = EXYNOS5250_NUM_PHYS, | ||
402 | .phys = exynos5250_phys, | ||
403 | .rate_to_clk = exynos5250_rate_to_clk, | ||
404 | }; | ||
diff --git a/drivers/usb/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index e7253182e47d..311b4f9a5132 100644 --- a/drivers/usb/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * omap-control-usb.c - The USB part of control module. | 2 | * omap-control-phy.c - The PHY part of control module. |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | 4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
@@ -24,36 +24,36 @@ | |||
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/usb/omap_control_usb.h> | 27 | #include <linux/phy/omap_control_phy.h> |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * omap_control_usb_phy_power - power on/off the phy using control module reg | 30 | * omap_control_phy_power - power on/off the phy using control module reg |
31 | * @dev: the control module device | 31 | * @dev: the control module device |
32 | * @on: 0 or 1, based on powering on or off the PHY | 32 | * @on: 0 or 1, based on powering on or off the PHY |
33 | */ | 33 | */ |
34 | void omap_control_usb_phy_power(struct device *dev, int on) | 34 | void omap_control_phy_power(struct device *dev, int on) |
35 | { | 35 | { |
36 | u32 val; | 36 | u32 val; |
37 | unsigned long rate; | 37 | unsigned long rate; |
38 | struct omap_control_usb *control_usb; | 38 | struct omap_control_phy *control_phy; |
39 | 39 | ||
40 | if (IS_ERR(dev) || !dev) { | 40 | if (IS_ERR(dev) || !dev) { |
41 | pr_err("%s: invalid device\n", __func__); | 41 | pr_err("%s: invalid device\n", __func__); |
42 | return; | 42 | return; |
43 | } | 43 | } |
44 | 44 | ||
45 | control_usb = dev_get_drvdata(dev); | 45 | control_phy = dev_get_drvdata(dev); |
46 | if (!control_usb) { | 46 | if (!control_phy) { |
47 | dev_err(dev, "%s: invalid control usb device\n", __func__); | 47 | dev_err(dev, "%s: invalid control phy device\n", __func__); |
48 | return; | 48 | return; |
49 | } | 49 | } |
50 | 50 | ||
51 | if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) | 51 | if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) |
52 | return; | 52 | return; |
53 | 53 | ||
54 | val = readl(control_usb->power); | 54 | val = readl(control_phy->power); |
55 | 55 | ||
56 | switch (control_usb->type) { | 56 | switch (control_phy->type) { |
57 | case OMAP_CTRL_TYPE_USB2: | 57 | case OMAP_CTRL_TYPE_USB2: |
58 | if (on) | 58 | if (on) |
59 | val &= ~OMAP_CTRL_DEV_PHY_PD; | 59 | val &= ~OMAP_CTRL_DEV_PHY_PD; |
@@ -62,19 +62,20 @@ void omap_control_usb_phy_power(struct device *dev, int on) | |||
62 | break; | 62 | break; |
63 | 63 | ||
64 | case OMAP_CTRL_TYPE_PIPE3: | 64 | case OMAP_CTRL_TYPE_PIPE3: |
65 | rate = clk_get_rate(control_usb->sys_clk); | 65 | rate = clk_get_rate(control_phy->sys_clk); |
66 | rate = rate/1000000; | 66 | rate = rate/1000000; |
67 | 67 | ||
68 | if (on) { | 68 | if (on) { |
69 | val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK | | 69 | val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | |
70 | OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK); | 70 | OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); |
71 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON << | 71 | val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << |
72 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | 72 | OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; |
73 | val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT; | 73 | val |= rate << |
74 | OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; | ||
74 | } else { | 75 | } else { |
75 | val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK; | 76 | val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; |
76 | val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << | 77 | val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << |
77 | OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT; | 78 | OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; |
78 | } | 79 | } |
79 | break; | 80 | break; |
80 | 81 | ||
@@ -100,66 +101,66 @@ void omap_control_usb_phy_power(struct device *dev, int on) | |||
100 | break; | 101 | break; |
101 | default: | 102 | default: |
102 | dev_err(dev, "%s: type %d not recognized\n", | 103 | dev_err(dev, "%s: type %d not recognized\n", |
103 | __func__, control_usb->type); | 104 | __func__, control_phy->type); |
104 | break; | 105 | break; |
105 | } | 106 | } |
106 | 107 | ||
107 | writel(val, control_usb->power); | 108 | writel(val, control_phy->power); |
108 | } | 109 | } |
109 | EXPORT_SYMBOL_GPL(omap_control_usb_phy_power); | 110 | EXPORT_SYMBOL_GPL(omap_control_phy_power); |
110 | 111 | ||
111 | /** | 112 | /** |
112 | * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded | 113 | * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded |
113 | * @ctrl_usb: struct omap_control_usb * | 114 | * @ctrl_phy: struct omap_control_phy * |
114 | * | 115 | * |
115 | * Writes to the mailbox register to notify the usb core that a usb | 116 | * Writes to the mailbox register to notify the usb core that a usb |
116 | * device has been connected. | 117 | * device has been connected. |
117 | */ | 118 | */ |
118 | static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb) | 119 | static void omap_control_usb_host_mode(struct omap_control_phy *ctrl_phy) |
119 | { | 120 | { |
120 | u32 val; | 121 | u32 val; |
121 | 122 | ||
122 | val = readl(ctrl_usb->otghs_control); | 123 | val = readl(ctrl_phy->otghs_control); |
123 | val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); | 124 | val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND); |
124 | val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; | 125 | val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID; |
125 | writel(val, ctrl_usb->otghs_control); | 126 | writel(val, ctrl_phy->otghs_control); |
126 | } | 127 | } |
127 | 128 | ||
128 | /** | 129 | /** |
129 | * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high | 130 | * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high |
130 | * impedance | 131 | * impedance |
131 | * @ctrl_usb: struct omap_control_usb * | 132 | * @ctrl_phy: struct omap_control_phy * |
132 | * | 133 | * |
133 | * Writes to the mailbox register to notify the usb core that it has been | 134 | * Writes to the mailbox register to notify the usb core that it has been |
134 | * connected to a usb host. | 135 | * connected to a usb host. |
135 | */ | 136 | */ |
136 | static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb) | 137 | static void omap_control_usb_device_mode(struct omap_control_phy *ctrl_phy) |
137 | { | 138 | { |
138 | u32 val; | 139 | u32 val; |
139 | 140 | ||
140 | val = readl(ctrl_usb->otghs_control); | 141 | val = readl(ctrl_phy->otghs_control); |
141 | val &= ~OMAP_CTRL_DEV_SESSEND; | 142 | val &= ~OMAP_CTRL_DEV_SESSEND; |
142 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | | 143 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID | |
143 | OMAP_CTRL_DEV_VBUSVALID; | 144 | OMAP_CTRL_DEV_VBUSVALID; |
144 | writel(val, ctrl_usb->otghs_control); | 145 | writel(val, ctrl_phy->otghs_control); |
145 | } | 146 | } |
146 | 147 | ||
147 | /** | 148 | /** |
148 | * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high | 149 | * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high |
149 | * impedance | 150 | * impedance |
150 | * @ctrl_usb: struct omap_control_usb * | 151 | * @ctrl_phy: struct omap_control_phy * |
151 | * | 152 | * |
152 | * Writes to the mailbox register to notify the usb core it's now in | 153 | * Writes to the mailbox register to notify the usb core it's now in |
153 | * disconnected state. | 154 | * disconnected state. |
154 | */ | 155 | */ |
155 | static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) | 156 | static void omap_control_usb_set_sessionend(struct omap_control_phy *ctrl_phy) |
156 | { | 157 | { |
157 | u32 val; | 158 | u32 val; |
158 | 159 | ||
159 | val = readl(ctrl_usb->otghs_control); | 160 | val = readl(ctrl_phy->otghs_control); |
160 | val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); | 161 | val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID); |
161 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; | 162 | val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND; |
162 | writel(val, ctrl_usb->otghs_control); | 163 | writel(val, ctrl_phy->otghs_control); |
163 | } | 164 | } |
164 | 165 | ||
165 | /** | 166 | /** |
@@ -174,30 +175,30 @@ static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb) | |||
174 | void omap_control_usb_set_mode(struct device *dev, | 175 | void omap_control_usb_set_mode(struct device *dev, |
175 | enum omap_control_usb_mode mode) | 176 | enum omap_control_usb_mode mode) |
176 | { | 177 | { |
177 | struct omap_control_usb *ctrl_usb; | 178 | struct omap_control_phy *ctrl_phy; |
178 | 179 | ||
179 | if (IS_ERR(dev) || !dev) | 180 | if (IS_ERR(dev) || !dev) |
180 | return; | 181 | return; |
181 | 182 | ||
182 | ctrl_usb = dev_get_drvdata(dev); | 183 | ctrl_phy = dev_get_drvdata(dev); |
183 | 184 | ||
184 | if (!ctrl_usb) { | 185 | if (!ctrl_phy) { |
185 | dev_err(dev, "Invalid control usb device\n"); | 186 | dev_err(dev, "Invalid control phy device\n"); |
186 | return; | 187 | return; |
187 | } | 188 | } |
188 | 189 | ||
189 | if (ctrl_usb->type != OMAP_CTRL_TYPE_OTGHS) | 190 | if (ctrl_phy->type != OMAP_CTRL_TYPE_OTGHS) |
190 | return; | 191 | return; |
191 | 192 | ||
192 | switch (mode) { | 193 | switch (mode) { |
193 | case USB_MODE_HOST: | 194 | case USB_MODE_HOST: |
194 | omap_control_usb_host_mode(ctrl_usb); | 195 | omap_control_usb_host_mode(ctrl_phy); |
195 | break; | 196 | break; |
196 | case USB_MODE_DEVICE: | 197 | case USB_MODE_DEVICE: |
197 | omap_control_usb_device_mode(ctrl_usb); | 198 | omap_control_usb_device_mode(ctrl_phy); |
198 | break; | 199 | break; |
199 | case USB_MODE_DISCONNECT: | 200 | case USB_MODE_DISCONNECT: |
200 | omap_control_usb_set_sessionend(ctrl_usb); | 201 | omap_control_usb_set_sessionend(ctrl_phy); |
201 | break; | 202 | break; |
202 | default: | 203 | default: |
203 | dev_vdbg(dev, "invalid omap control usb mode\n"); | 204 | dev_vdbg(dev, "invalid omap control usb mode\n"); |
@@ -207,13 +208,13 @@ EXPORT_SYMBOL_GPL(omap_control_usb_set_mode); | |||
207 | 208 | ||
208 | #ifdef CONFIG_OF | 209 | #ifdef CONFIG_OF |
209 | 210 | ||
210 | static const enum omap_control_usb_type otghs_data = OMAP_CTRL_TYPE_OTGHS; | 211 | static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS; |
211 | static const enum omap_control_usb_type usb2_data = OMAP_CTRL_TYPE_USB2; | 212 | static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2; |
212 | static const enum omap_control_usb_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; | 213 | static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3; |
213 | static const enum omap_control_usb_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; | 214 | static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2; |
214 | static const enum omap_control_usb_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2; | 215 | static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2; |
215 | 216 | ||
216 | static const struct of_device_id omap_control_usb_id_table[] = { | 217 | static const struct of_device_id omap_control_phy_id_table[] = { |
217 | { | 218 | { |
218 | .compatible = "ti,control-phy-otghs", | 219 | .compatible = "ti,control-phy-otghs", |
219 | .data = &otghs_data, | 220 | .data = &otghs_data, |
@@ -227,93 +228,93 @@ static const struct of_device_id omap_control_usb_id_table[] = { | |||
227 | .data = &pipe3_data, | 228 | .data = &pipe3_data, |
228 | }, | 229 | }, |
229 | { | 230 | { |
230 | .compatible = "ti,control-phy-dra7usb2", | 231 | .compatible = "ti,control-phy-usb2-dra7", |
231 | .data = &dra7usb2_data, | 232 | .data = &dra7usb2_data, |
232 | }, | 233 | }, |
233 | { | 234 | { |
234 | .compatible = "ti,control-phy-am437usb2", | 235 | .compatible = "ti,control-phy-usb2-am437", |
235 | .data = &am437usb2_data, | 236 | .data = &am437usb2_data, |
236 | }, | 237 | }, |
237 | {}, | 238 | {}, |
238 | }; | 239 | }; |
239 | MODULE_DEVICE_TABLE(of, omap_control_usb_id_table); | 240 | MODULE_DEVICE_TABLE(of, omap_control_phy_id_table); |
240 | #endif | 241 | #endif |
241 | 242 | ||
242 | 243 | ||
243 | static int omap_control_usb_probe(struct platform_device *pdev) | 244 | static int omap_control_phy_probe(struct platform_device *pdev) |
244 | { | 245 | { |
245 | struct resource *res; | 246 | struct resource *res; |
246 | const struct of_device_id *of_id; | 247 | const struct of_device_id *of_id; |
247 | struct omap_control_usb *control_usb; | 248 | struct omap_control_phy *control_phy; |
248 | 249 | ||
249 | of_id = of_match_device(of_match_ptr(omap_control_usb_id_table), | 250 | of_id = of_match_device(of_match_ptr(omap_control_phy_id_table), |
250 | &pdev->dev); | 251 | &pdev->dev); |
251 | if (!of_id) | 252 | if (!of_id) |
252 | return -EINVAL; | 253 | return -EINVAL; |
253 | 254 | ||
254 | control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb), | 255 | control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy), |
255 | GFP_KERNEL); | 256 | GFP_KERNEL); |
256 | if (!control_usb) { | 257 | if (!control_phy) { |
257 | dev_err(&pdev->dev, "unable to alloc memory for control usb\n"); | 258 | dev_err(&pdev->dev, "unable to alloc memory for control phy\n"); |
258 | return -ENOMEM; | 259 | return -ENOMEM; |
259 | } | 260 | } |
260 | 261 | ||
261 | control_usb->dev = &pdev->dev; | 262 | control_phy->dev = &pdev->dev; |
262 | control_usb->type = *(enum omap_control_usb_type *)of_id->data; | 263 | control_phy->type = *(enum omap_control_phy_type *)of_id->data; |
263 | 264 | ||
264 | if (control_usb->type == OMAP_CTRL_TYPE_OTGHS) { | 265 | if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) { |
265 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 266 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
266 | "otghs_control"); | 267 | "otghs_control"); |
267 | control_usb->otghs_control = devm_ioremap_resource( | 268 | control_phy->otghs_control = devm_ioremap_resource( |
268 | &pdev->dev, res); | 269 | &pdev->dev, res); |
269 | if (IS_ERR(control_usb->otghs_control)) | 270 | if (IS_ERR(control_phy->otghs_control)) |
270 | return PTR_ERR(control_usb->otghs_control); | 271 | return PTR_ERR(control_phy->otghs_control); |
271 | } else { | 272 | } else { |
272 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 273 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
273 | "power"); | 274 | "power"); |
274 | control_usb->power = devm_ioremap_resource(&pdev->dev, res); | 275 | control_phy->power = devm_ioremap_resource(&pdev->dev, res); |
275 | if (IS_ERR(control_usb->power)) { | 276 | if (IS_ERR(control_phy->power)) { |
276 | dev_err(&pdev->dev, "Couldn't get power register\n"); | 277 | dev_err(&pdev->dev, "Couldn't get power register\n"); |
277 | return PTR_ERR(control_usb->power); | 278 | return PTR_ERR(control_phy->power); |
278 | } | 279 | } |
279 | } | 280 | } |
280 | 281 | ||
281 | if (control_usb->type == OMAP_CTRL_TYPE_PIPE3) { | 282 | if (control_phy->type == OMAP_CTRL_TYPE_PIPE3) { |
282 | control_usb->sys_clk = devm_clk_get(control_usb->dev, | 283 | control_phy->sys_clk = devm_clk_get(control_phy->dev, |
283 | "sys_clkin"); | 284 | "sys_clkin"); |
284 | if (IS_ERR(control_usb->sys_clk)) { | 285 | if (IS_ERR(control_phy->sys_clk)) { |
285 | pr_err("%s: unable to get sys_clkin\n", __func__); | 286 | pr_err("%s: unable to get sys_clkin\n", __func__); |
286 | return -EINVAL; | 287 | return -EINVAL; |
287 | } | 288 | } |
288 | } | 289 | } |
289 | 290 | ||
290 | dev_set_drvdata(control_usb->dev, control_usb); | 291 | dev_set_drvdata(control_phy->dev, control_phy); |
291 | 292 | ||
292 | return 0; | 293 | return 0; |
293 | } | 294 | } |
294 | 295 | ||
295 | static struct platform_driver omap_control_usb_driver = { | 296 | static struct platform_driver omap_control_phy_driver = { |
296 | .probe = omap_control_usb_probe, | 297 | .probe = omap_control_phy_probe, |
297 | .driver = { | 298 | .driver = { |
298 | .name = "omap-control-usb", | 299 | .name = "omap-control-phy", |
299 | .owner = THIS_MODULE, | 300 | .owner = THIS_MODULE, |
300 | .of_match_table = of_match_ptr(omap_control_usb_id_table), | 301 | .of_match_table = of_match_ptr(omap_control_phy_id_table), |
301 | }, | 302 | }, |
302 | }; | 303 | }; |
303 | 304 | ||
304 | static int __init omap_control_usb_init(void) | 305 | static int __init omap_control_phy_init(void) |
305 | { | 306 | { |
306 | return platform_driver_register(&omap_control_usb_driver); | 307 | return platform_driver_register(&omap_control_phy_driver); |
307 | } | 308 | } |
308 | subsys_initcall(omap_control_usb_init); | 309 | subsys_initcall(omap_control_phy_init); |
309 | 310 | ||
310 | static void __exit omap_control_usb_exit(void) | 311 | static void __exit omap_control_phy_exit(void) |
311 | { | 312 | { |
312 | platform_driver_unregister(&omap_control_usb_driver); | 313 | platform_driver_unregister(&omap_control_phy_driver); |
313 | } | 314 | } |
314 | module_exit(omap_control_usb_exit); | 315 | module_exit(omap_control_phy_exit); |
315 | 316 | ||
316 | MODULE_ALIAS("platform: omap_control_usb"); | 317 | MODULE_ALIAS("platform: omap_control_phy"); |
317 | MODULE_AUTHOR("Texas Instruments Inc."); | 318 | MODULE_AUTHOR("Texas Instruments Inc."); |
318 | MODULE_DESCRIPTION("OMAP Control Module USB Driver"); | 319 | MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); |
319 | MODULE_LICENSE("GPL v2"); | 320 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index 7699752fba11..a2205a841e5e 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
@@ -21,16 +21,19 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/usb/omap_usb.h> | 24 | #include <linux/phy/omap_usb.h> |
25 | #include <linux/usb/phy_companion.h> | 25 | #include <linux/usb/phy_companion.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/usb/omap_control_usb.h> | 30 | #include <linux/phy/omap_control_phy.h> |
31 | #include <linux/phy/phy.h> | 31 | #include <linux/phy/phy.h> |
32 | #include <linux/of_platform.h> | 32 | #include <linux/of_platform.h> |
33 | 33 | ||
34 | #define USB2PHY_DISCON_BYP_LATCH (1 << 31) | ||
35 | #define USB2PHY_ANA_CONFIG1 0x4c | ||
36 | |||
34 | /** | 37 | /** |
35 | * omap_usb2_set_comparator - links the comparator present in the sytem with | 38 | * omap_usb2_set_comparator - links the comparator present in the sytem with |
36 | * this phy | 39 | * this phy |
@@ -98,65 +101,116 @@ static int omap_usb_set_peripheral(struct usb_otg *otg, | |||
98 | return 0; | 101 | return 0; |
99 | } | 102 | } |
100 | 103 | ||
101 | static int omap_usb2_suspend(struct usb_phy *x, int suspend) | 104 | static int omap_usb_power_off(struct phy *x) |
102 | { | 105 | { |
103 | struct omap_usb *phy = phy_to_omapusb(x); | 106 | struct omap_usb *phy = phy_get_drvdata(x); |
104 | int ret; | ||
105 | 107 | ||
106 | if (suspend && !phy->is_suspended) { | 108 | omap_control_phy_power(phy->control_dev, 0); |
107 | omap_control_usb_phy_power(phy->control_dev, 0); | ||
108 | pm_runtime_put_sync(phy->dev); | ||
109 | phy->is_suspended = 1; | ||
110 | } else if (!suspend && phy->is_suspended) { | ||
111 | ret = pm_runtime_get_sync(phy->dev); | ||
112 | if (ret < 0) { | ||
113 | dev_err(phy->dev, "get_sync failed with err %d\n", ret); | ||
114 | return ret; | ||
115 | } | ||
116 | omap_control_usb_phy_power(phy->control_dev, 1); | ||
117 | phy->is_suspended = 0; | ||
118 | } | ||
119 | 109 | ||
120 | return 0; | 110 | return 0; |
121 | } | 111 | } |
122 | 112 | ||
123 | static int omap_usb_power_off(struct phy *x) | 113 | static int omap_usb_power_on(struct phy *x) |
124 | { | 114 | { |
125 | struct omap_usb *phy = phy_get_drvdata(x); | 115 | struct omap_usb *phy = phy_get_drvdata(x); |
126 | 116 | ||
127 | omap_control_usb_phy_power(phy->control_dev, 0); | 117 | omap_control_phy_power(phy->control_dev, 1); |
128 | 118 | ||
129 | return 0; | 119 | return 0; |
130 | } | 120 | } |
131 | 121 | ||
132 | static int omap_usb_power_on(struct phy *x) | 122 | static int omap_usb_init(struct phy *x) |
133 | { | 123 | { |
134 | struct omap_usb *phy = phy_get_drvdata(x); | 124 | struct omap_usb *phy = phy_get_drvdata(x); |
135 | 125 | u32 val; | |
136 | omap_control_usb_phy_power(phy->control_dev, 1); | 126 | |
127 | if (phy->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { | ||
128 | /* | ||
129 | * | ||
130 | * Reduce the sensitivity of internal PHY by enabling the | ||
131 | * DISCON_BYP_LATCH of the USB2PHY_ANA_CONFIG1 register. This | ||
132 | * resolves issues with certain devices which can otherwise | ||
133 | * be prone to false disconnects. | ||
134 | * | ||
135 | */ | ||
136 | val = omap_usb_readl(phy->phy_base, USB2PHY_ANA_CONFIG1); | ||
137 | val |= USB2PHY_DISCON_BYP_LATCH; | ||
138 | omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val); | ||
139 | } | ||
137 | 140 | ||
138 | return 0; | 141 | return 0; |
139 | } | 142 | } |
140 | 143 | ||
141 | static struct phy_ops ops = { | 144 | static struct phy_ops ops = { |
145 | .init = omap_usb_init, | ||
142 | .power_on = omap_usb_power_on, | 146 | .power_on = omap_usb_power_on, |
143 | .power_off = omap_usb_power_off, | 147 | .power_off = omap_usb_power_off, |
144 | .owner = THIS_MODULE, | 148 | .owner = THIS_MODULE, |
145 | }; | 149 | }; |
146 | 150 | ||
151 | #ifdef CONFIG_OF | ||
152 | static const struct usb_phy_data omap_usb2_data = { | ||
153 | .label = "omap_usb2", | ||
154 | .flags = OMAP_USB2_HAS_START_SRP | OMAP_USB2_HAS_SET_VBUS, | ||
155 | }; | ||
156 | |||
157 | static const struct usb_phy_data omap5_usb2_data = { | ||
158 | .label = "omap5_usb2", | ||
159 | .flags = 0, | ||
160 | }; | ||
161 | |||
162 | static const struct usb_phy_data dra7x_usb2_data = { | ||
163 | .label = "dra7x_usb2", | ||
164 | .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, | ||
165 | }; | ||
166 | |||
167 | static const struct usb_phy_data am437x_usb2_data = { | ||
168 | .label = "am437x_usb2", | ||
169 | .flags = 0, | ||
170 | }; | ||
171 | |||
172 | static const struct of_device_id omap_usb2_id_table[] = { | ||
173 | { | ||
174 | .compatible = "ti,omap-usb2", | ||
175 | .data = &omap_usb2_data, | ||
176 | }, | ||
177 | { | ||
178 | .compatible = "ti,omap5-usb2", | ||
179 | .data = &omap5_usb2_data, | ||
180 | }, | ||
181 | { | ||
182 | .compatible = "ti,dra7x-usb2", | ||
183 | .data = &dra7x_usb2_data, | ||
184 | }, | ||
185 | { | ||
186 | .compatible = "ti,am437x-usb2", | ||
187 | .data = &am437x_usb2_data, | ||
188 | }, | ||
189 | {}, | ||
190 | }; | ||
191 | MODULE_DEVICE_TABLE(of, omap_usb2_id_table); | ||
192 | #endif | ||
193 | |||
147 | static int omap_usb2_probe(struct platform_device *pdev) | 194 | static int omap_usb2_probe(struct platform_device *pdev) |
148 | { | 195 | { |
149 | struct omap_usb *phy; | 196 | struct omap_usb *phy; |
150 | struct phy *generic_phy; | 197 | struct phy *generic_phy; |
198 | struct resource *res; | ||
151 | struct phy_provider *phy_provider; | 199 | struct phy_provider *phy_provider; |
152 | struct usb_otg *otg; | 200 | struct usb_otg *otg; |
153 | struct device_node *node = pdev->dev.of_node; | 201 | struct device_node *node = pdev->dev.of_node; |
154 | struct device_node *control_node; | 202 | struct device_node *control_node; |
155 | struct platform_device *control_pdev; | 203 | struct platform_device *control_pdev; |
204 | const struct of_device_id *of_id; | ||
205 | struct usb_phy_data *phy_data; | ||
206 | |||
207 | of_id = of_match_device(of_match_ptr(omap_usb2_id_table), &pdev->dev); | ||
156 | 208 | ||
157 | if (!node) | 209 | if (!of_id) |
158 | return -EINVAL; | 210 | return -EINVAL; |
159 | 211 | ||
212 | phy_data = (struct usb_phy_data *)of_id->data; | ||
213 | |||
160 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | 214 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); |
161 | if (!phy) { | 215 | if (!phy) { |
162 | dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); | 216 | dev_err(&pdev->dev, "unable to allocate memory for USB2 PHY\n"); |
@@ -172,11 +226,18 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
172 | phy->dev = &pdev->dev; | 226 | phy->dev = &pdev->dev; |
173 | 227 | ||
174 | phy->phy.dev = phy->dev; | 228 | phy->phy.dev = phy->dev; |
175 | phy->phy.label = "omap-usb2"; | 229 | phy->phy.label = phy_data->label; |
176 | phy->phy.set_suspend = omap_usb2_suspend; | ||
177 | phy->phy.otg = otg; | 230 | phy->phy.otg = otg; |
178 | phy->phy.type = USB_PHY_TYPE_USB2; | 231 | phy->phy.type = USB_PHY_TYPE_USB2; |
179 | 232 | ||
233 | if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { | ||
234 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
235 | phy->phy_base = devm_ioremap_resource(&pdev->dev, res); | ||
236 | if (!phy->phy_base) | ||
237 | return -ENOMEM; | ||
238 | phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; | ||
239 | } | ||
240 | |||
180 | control_node = of_parse_phandle(node, "ctrl-module", 0); | 241 | control_node = of_parse_phandle(node, "ctrl-module", 0); |
181 | if (!control_node) { | 242 | if (!control_node) { |
182 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); | 243 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); |
@@ -190,14 +251,14 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
190 | } | 251 | } |
191 | 252 | ||
192 | phy->control_dev = &control_pdev->dev; | 253 | phy->control_dev = &control_pdev->dev; |
193 | 254 | omap_control_phy_power(phy->control_dev, 0); | |
194 | phy->is_suspended = 1; | ||
195 | omap_control_usb_phy_power(phy->control_dev, 0); | ||
196 | 255 | ||
197 | otg->set_host = omap_usb_set_host; | 256 | otg->set_host = omap_usb_set_host; |
198 | otg->set_peripheral = omap_usb_set_peripheral; | 257 | otg->set_peripheral = omap_usb_set_peripheral; |
199 | otg->set_vbus = omap_usb_set_vbus; | 258 | if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) |
200 | otg->start_srp = omap_usb_start_srp; | 259 | otg->set_vbus = omap_usb_set_vbus; |
260 | if (phy_data->flags & OMAP_USB2_HAS_START_SRP) | ||
261 | otg->start_srp = omap_usb_start_srp; | ||
201 | otg->phy = &phy->phy; | 262 | otg->phy = &phy->phy; |
202 | 263 | ||
203 | platform_set_drvdata(pdev, phy); | 264 | platform_set_drvdata(pdev, phy); |
@@ -297,14 +358,6 @@ static const struct dev_pm_ops omap_usb2_pm_ops = { | |||
297 | #define DEV_PM_OPS NULL | 358 | #define DEV_PM_OPS NULL |
298 | #endif | 359 | #endif |
299 | 360 | ||
300 | #ifdef CONFIG_OF | ||
301 | static const struct of_device_id omap_usb2_id_table[] = { | ||
302 | { .compatible = "ti,omap-usb2" }, | ||
303 | {} | ||
304 | }; | ||
305 | MODULE_DEVICE_TABLE(of, omap_usb2_id_table); | ||
306 | #endif | ||
307 | |||
308 | static struct platform_driver omap_usb2_driver = { | 361 | static struct platform_driver omap_usb2_driver = { |
309 | .probe = omap_usb2_probe, | 362 | .probe = omap_usb2_probe, |
310 | .remove = omap_usb2_remove, | 363 | .remove = omap_usb2_remove, |
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c new file mode 100644 index 000000000000..8a8c6bc8709a --- /dev/null +++ b/drivers/phy/phy-samsung-usb2.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * Samsung SoC USB 1.1/2.0 PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Kamil Debski <k.debski@samsung.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/mfd/syscon.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/phy/phy.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include "phy-samsung-usb2.h" | ||
21 | |||
22 | static int samsung_usb2_phy_power_on(struct phy *phy) | ||
23 | { | ||
24 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); | ||
25 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
26 | int ret; | ||
27 | |||
28 | dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", | ||
29 | inst->cfg->label); | ||
30 | ret = clk_prepare_enable(drv->clk); | ||
31 | if (ret) | ||
32 | goto err_main_clk; | ||
33 | ret = clk_prepare_enable(drv->ref_clk); | ||
34 | if (ret) | ||
35 | goto err_instance_clk; | ||
36 | if (inst->cfg->power_on) { | ||
37 | spin_lock(&drv->lock); | ||
38 | ret = inst->cfg->power_on(inst); | ||
39 | spin_unlock(&drv->lock); | ||
40 | } | ||
41 | |||
42 | return 0; | ||
43 | |||
44 | err_instance_clk: | ||
45 | clk_disable_unprepare(drv->clk); | ||
46 | err_main_clk: | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static int samsung_usb2_phy_power_off(struct phy *phy) | ||
51 | { | ||
52 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); | ||
53 | struct samsung_usb2_phy_driver *drv = inst->drv; | ||
54 | int ret = 0; | ||
55 | |||
56 | dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", | ||
57 | inst->cfg->label); | ||
58 | if (inst->cfg->power_off) { | ||
59 | spin_lock(&drv->lock); | ||
60 | ret = inst->cfg->power_off(inst); | ||
61 | spin_unlock(&drv->lock); | ||
62 | } | ||
63 | clk_disable_unprepare(drv->ref_clk); | ||
64 | clk_disable_unprepare(drv->clk); | ||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | static struct phy_ops samsung_usb2_phy_ops = { | ||
69 | .power_on = samsung_usb2_phy_power_on, | ||
70 | .power_off = samsung_usb2_phy_power_off, | ||
71 | .owner = THIS_MODULE, | ||
72 | }; | ||
73 | |||
74 | static struct phy *samsung_usb2_phy_xlate(struct device *dev, | ||
75 | struct of_phandle_args *args) | ||
76 | { | ||
77 | struct samsung_usb2_phy_driver *drv; | ||
78 | |||
79 | drv = dev_get_drvdata(dev); | ||
80 | if (!drv) | ||
81 | return ERR_PTR(-EINVAL); | ||
82 | |||
83 | if (WARN_ON(args->args[0] >= drv->cfg->num_phys)) | ||
84 | return ERR_PTR(-ENODEV); | ||
85 | |||
86 | return drv->instances[args->args[0]].phy; | ||
87 | } | ||
88 | |||
89 | static const struct of_device_id samsung_usb2_phy_of_match[] = { | ||
90 | #ifdef CONFIG_PHY_EXYNOS4210_USB2 | ||
91 | { | ||
92 | .compatible = "samsung,exynos4210-usb2-phy", | ||
93 | .data = &exynos4210_usb2_phy_config, | ||
94 | }, | ||
95 | #endif | ||
96 | #ifdef CONFIG_PHY_EXYNOS4X12_USB2 | ||
97 | { | ||
98 | .compatible = "samsung,exynos4x12-usb2-phy", | ||
99 | .data = &exynos4x12_usb2_phy_config, | ||
100 | }, | ||
101 | #endif | ||
102 | #ifdef CONFIG_PHY_EXYNOS5250_USB2 | ||
103 | { | ||
104 | .compatible = "samsung,exynos5250-usb2-phy", | ||
105 | .data = &exynos5250_usb2_phy_config, | ||
106 | }, | ||
107 | #endif | ||
108 | { }, | ||
109 | }; | ||
110 | |||
111 | static int samsung_usb2_phy_probe(struct platform_device *pdev) | ||
112 | { | ||
113 | const struct of_device_id *match; | ||
114 | const struct samsung_usb2_phy_config *cfg; | ||
115 | struct device *dev = &pdev->dev; | ||
116 | struct phy_provider *phy_provider; | ||
117 | struct resource *mem; | ||
118 | struct samsung_usb2_phy_driver *drv; | ||
119 | int i, ret; | ||
120 | |||
121 | if (!pdev->dev.of_node) { | ||
122 | dev_err(dev, "This driver is required to be instantiated from device tree\n"); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | match = of_match_node(samsung_usb2_phy_of_match, pdev->dev.of_node); | ||
127 | if (!match) { | ||
128 | dev_err(dev, "of_match_node() failed\n"); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | cfg = match->data; | ||
132 | |||
133 | drv = devm_kzalloc(dev, sizeof(struct samsung_usb2_phy_driver) + | ||
134 | cfg->num_phys * sizeof(struct samsung_usb2_phy_instance), | ||
135 | GFP_KERNEL); | ||
136 | if (!drv) | ||
137 | return -ENOMEM; | ||
138 | |||
139 | dev_set_drvdata(dev, drv); | ||
140 | spin_lock_init(&drv->lock); | ||
141 | |||
142 | drv->cfg = cfg; | ||
143 | drv->dev = dev; | ||
144 | |||
145 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
146 | drv->reg_phy = devm_ioremap_resource(dev, mem); | ||
147 | if (IS_ERR(drv->reg_phy)) { | ||
148 | dev_err(dev, "Failed to map register memory (phy)\n"); | ||
149 | return PTR_ERR(drv->reg_phy); | ||
150 | } | ||
151 | |||
152 | drv->reg_pmu = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||
153 | "samsung,pmureg-phandle"); | ||
154 | if (IS_ERR(drv->reg_pmu)) { | ||
155 | dev_err(dev, "Failed to map PMU registers (via syscon)\n"); | ||
156 | return PTR_ERR(drv->reg_pmu); | ||
157 | } | ||
158 | |||
159 | if (drv->cfg->has_mode_switch) { | ||
160 | drv->reg_sys = syscon_regmap_lookup_by_phandle( | ||
161 | pdev->dev.of_node, "samsung,sysreg-phandle"); | ||
162 | if (IS_ERR(drv->reg_sys)) { | ||
163 | dev_err(dev, "Failed to map system registers (via syscon)\n"); | ||
164 | return PTR_ERR(drv->reg_sys); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | drv->clk = devm_clk_get(dev, "phy"); | ||
169 | if (IS_ERR(drv->clk)) { | ||
170 | dev_err(dev, "Failed to get clock of phy controller\n"); | ||
171 | return PTR_ERR(drv->clk); | ||
172 | } | ||
173 | |||
174 | drv->ref_clk = devm_clk_get(dev, "ref"); | ||
175 | if (IS_ERR(drv->ref_clk)) { | ||
176 | dev_err(dev, "Failed to get reference clock for the phy controller\n"); | ||
177 | return PTR_ERR(drv->ref_clk); | ||
178 | } | ||
179 | |||
180 | drv->ref_rate = clk_get_rate(drv->ref_clk); | ||
181 | if (drv->cfg->rate_to_clk) { | ||
182 | ret = drv->cfg->rate_to_clk(drv->ref_rate, &drv->ref_reg_val); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | for (i = 0; i < drv->cfg->num_phys; i++) { | ||
188 | char *label = drv->cfg->phys[i].label; | ||
189 | struct samsung_usb2_phy_instance *p = &drv->instances[i]; | ||
190 | |||
191 | dev_dbg(dev, "Creating phy \"%s\"\n", label); | ||
192 | p->phy = devm_phy_create(dev, &samsung_usb2_phy_ops, NULL); | ||
193 | if (IS_ERR(p->phy)) { | ||
194 | dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n", | ||
195 | label); | ||
196 | return PTR_ERR(p->phy); | ||
197 | } | ||
198 | |||
199 | p->cfg = &drv->cfg->phys[i]; | ||
200 | p->drv = drv; | ||
201 | phy_set_bus_width(p->phy, 8); | ||
202 | phy_set_drvdata(p->phy, p); | ||
203 | } | ||
204 | |||
205 | phy_provider = devm_of_phy_provider_register(dev, | ||
206 | samsung_usb2_phy_xlate); | ||
207 | if (IS_ERR(phy_provider)) { | ||
208 | dev_err(drv->dev, "Failed to register phy provider\n"); | ||
209 | return PTR_ERR(phy_provider); | ||
210 | } | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static struct platform_driver samsung_usb2_phy_driver = { | ||
216 | .probe = samsung_usb2_phy_probe, | ||
217 | .driver = { | ||
218 | .of_match_table = samsung_usb2_phy_of_match, | ||
219 | .name = "samsung-usb2-phy", | ||
220 | .owner = THIS_MODULE, | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | module_platform_driver(samsung_usb2_phy_driver); | ||
225 | MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC USB PHY driver"); | ||
226 | MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>"); | ||
227 | MODULE_LICENSE("GPL v2"); | ||
228 | MODULE_ALIAS("platform:samsung-usb2-phy"); | ||
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h new file mode 100644 index 000000000000..45b3170652bd --- /dev/null +++ b/drivers/phy/phy-samsung-usb2.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Samsung SoC USB 1.1/2.0 PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
5 | * Author: Kamil Debski <k.debski@samsung.com> | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _PHY_EXYNOS_USB2_H | ||
13 | #define _PHY_EXYNOS_USB2_H | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/phy/phy.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | |||
21 | #define KHZ 1000 | ||
22 | #define MHZ (KHZ * KHZ) | ||
23 | |||
24 | struct samsung_usb2_phy_driver; | ||
25 | struct samsung_usb2_phy_instance; | ||
26 | struct samsung_usb2_phy_config; | ||
27 | |||
28 | struct samsung_usb2_phy_instance { | ||
29 | const struct samsung_usb2_common_phy *cfg; | ||
30 | struct phy *phy; | ||
31 | struct samsung_usb2_phy_driver *drv; | ||
32 | bool enabled; | ||
33 | }; | ||
34 | |||
35 | struct samsung_usb2_phy_driver { | ||
36 | const struct samsung_usb2_phy_config *cfg; | ||
37 | struct clk *clk; | ||
38 | struct clk *ref_clk; | ||
39 | unsigned long ref_rate; | ||
40 | u32 ref_reg_val; | ||
41 | struct device *dev; | ||
42 | void __iomem *reg_phy; | ||
43 | struct regmap *reg_pmu; | ||
44 | struct regmap *reg_sys; | ||
45 | spinlock_t lock; | ||
46 | struct samsung_usb2_phy_instance instances[0]; | ||
47 | }; | ||
48 | |||
49 | struct samsung_usb2_common_phy { | ||
50 | int (*power_on)(struct samsung_usb2_phy_instance *); | ||
51 | int (*power_off)(struct samsung_usb2_phy_instance *); | ||
52 | unsigned int id; | ||
53 | char *label; | ||
54 | }; | ||
55 | |||
56 | |||
57 | struct samsung_usb2_phy_config { | ||
58 | const struct samsung_usb2_common_phy *phys; | ||
59 | int (*rate_to_clk)(unsigned long, u32 *); | ||
60 | unsigned int num_phys; | ||
61 | bool has_mode_switch; | ||
62 | }; | ||
63 | |||
64 | extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config; | ||
65 | extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config; | ||
66 | extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config; | ||
67 | #endif | ||
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c new file mode 100644 index 000000000000..e6e6c4ba7145 --- /dev/null +++ b/drivers/phy/phy-sun4i-usb.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * Allwinner sun4i USB phy driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com> | ||
5 | * | ||
6 | * Based on code from | ||
7 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> | ||
8 | * | ||
9 | * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver | ||
10 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | ||
11 | * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | */ | ||
23 | |||
24 | #include <linux/clk.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/of.h> | ||
30 | #include <linux/of_address.h> | ||
31 | #include <linux/phy/phy.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/regulator/consumer.h> | ||
34 | #include <linux/reset.h> | ||
35 | |||
36 | #define REG_ISCR 0x00 | ||
37 | #define REG_PHYCTL 0x04 | ||
38 | #define REG_PHYBIST 0x08 | ||
39 | #define REG_PHYTUNE 0x0c | ||
40 | |||
41 | #define PHYCTL_DATA BIT(7) | ||
42 | |||
43 | #define SUNXI_AHB_ICHR8_EN BIT(10) | ||
44 | #define SUNXI_AHB_INCR4_BURST_EN BIT(9) | ||
45 | #define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) | ||
46 | #define SUNXI_ULPI_BYPASS_EN BIT(0) | ||
47 | |||
48 | /* Common Control Bits for Both PHYs */ | ||
49 | #define PHY_PLL_BW 0x03 | ||
50 | #define PHY_RES45_CAL_EN 0x0c | ||
51 | |||
52 | /* Private Control Bits for Each PHY */ | ||
53 | #define PHY_TX_AMPLITUDE_TUNE 0x20 | ||
54 | #define PHY_TX_SLEWRATE_TUNE 0x22 | ||
55 | #define PHY_VBUSVALID_TH_SEL 0x25 | ||
56 | #define PHY_PULLUP_RES_SEL 0x27 | ||
57 | #define PHY_OTG_FUNC_EN 0x28 | ||
58 | #define PHY_VBUS_DET_EN 0x29 | ||
59 | #define PHY_DISCON_TH_SEL 0x2a | ||
60 | |||
61 | #define MAX_PHYS 3 | ||
62 | |||
63 | struct sun4i_usb_phy_data { | ||
64 | struct clk *clk; | ||
65 | void __iomem *base; | ||
66 | struct mutex mutex; | ||
67 | int num_phys; | ||
68 | u32 disc_thresh; | ||
69 | struct sun4i_usb_phy { | ||
70 | struct phy *phy; | ||
71 | void __iomem *pmu; | ||
72 | struct regulator *vbus; | ||
73 | struct reset_control *reset; | ||
74 | int index; | ||
75 | } phys[MAX_PHYS]; | ||
76 | }; | ||
77 | |||
78 | #define to_sun4i_usb_phy_data(phy) \ | ||
79 | container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index]) | ||
80 | |||
81 | static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, | ||
82 | int len) | ||
83 | { | ||
84 | struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); | ||
85 | u32 temp, usbc_bit = BIT(phy->index * 2); | ||
86 | int i; | ||
87 | |||
88 | mutex_lock(&phy_data->mutex); | ||
89 | |||
90 | for (i = 0; i < len; i++) { | ||
91 | temp = readl(phy_data->base + REG_PHYCTL); | ||
92 | |||
93 | /* clear the address portion */ | ||
94 | temp &= ~(0xff << 8); | ||
95 | |||
96 | /* set the address */ | ||
97 | temp |= ((addr + i) << 8); | ||
98 | writel(temp, phy_data->base + REG_PHYCTL); | ||
99 | |||
100 | /* set the data bit and clear usbc bit*/ | ||
101 | temp = readb(phy_data->base + REG_PHYCTL); | ||
102 | if (data & 0x1) | ||
103 | temp |= PHYCTL_DATA; | ||
104 | else | ||
105 | temp &= ~PHYCTL_DATA; | ||
106 | temp &= ~usbc_bit; | ||
107 | writeb(temp, phy_data->base + REG_PHYCTL); | ||
108 | |||
109 | /* pulse usbc_bit */ | ||
110 | temp = readb(phy_data->base + REG_PHYCTL); | ||
111 | temp |= usbc_bit; | ||
112 | writeb(temp, phy_data->base + REG_PHYCTL); | ||
113 | |||
114 | temp = readb(phy_data->base + REG_PHYCTL); | ||
115 | temp &= ~usbc_bit; | ||
116 | writeb(temp, phy_data->base + REG_PHYCTL); | ||
117 | |||
118 | data >>= 1; | ||
119 | } | ||
120 | mutex_unlock(&phy_data->mutex); | ||
121 | } | ||
122 | |||
123 | static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) | ||
124 | { | ||
125 | u32 bits, reg_value; | ||
126 | |||
127 | if (!phy->pmu) | ||
128 | return; | ||
129 | |||
130 | bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | | ||
131 | SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; | ||
132 | |||
133 | reg_value = readl(phy->pmu); | ||
134 | |||
135 | if (enable) | ||
136 | reg_value |= bits; | ||
137 | else | ||
138 | reg_value &= ~bits; | ||
139 | |||
140 | writel(reg_value, phy->pmu); | ||
141 | } | ||
142 | |||
143 | static int sun4i_usb_phy_init(struct phy *_phy) | ||
144 | { | ||
145 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
146 | struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); | ||
147 | int ret; | ||
148 | |||
149 | ret = clk_prepare_enable(data->clk); | ||
150 | if (ret) | ||
151 | return ret; | ||
152 | |||
153 | ret = reset_control_deassert(phy->reset); | ||
154 | if (ret) { | ||
155 | clk_disable_unprepare(data->clk); | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | /* Adjust PHY's magnitude and rate */ | ||
160 | sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); | ||
161 | |||
162 | /* Disconnect threshold adjustment */ | ||
163 | sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); | ||
164 | |||
165 | sun4i_usb_phy_passby(phy, 1); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int sun4i_usb_phy_exit(struct phy *_phy) | ||
171 | { | ||
172 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
173 | struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); | ||
174 | |||
175 | sun4i_usb_phy_passby(phy, 0); | ||
176 | reset_control_assert(phy->reset); | ||
177 | clk_disable_unprepare(data->clk); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int sun4i_usb_phy_power_on(struct phy *_phy) | ||
183 | { | ||
184 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
185 | int ret = 0; | ||
186 | |||
187 | if (phy->vbus) | ||
188 | ret = regulator_enable(phy->vbus); | ||
189 | |||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | static int sun4i_usb_phy_power_off(struct phy *_phy) | ||
194 | { | ||
195 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
196 | |||
197 | if (phy->vbus) | ||
198 | regulator_disable(phy->vbus); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static struct phy_ops sun4i_usb_phy_ops = { | ||
204 | .init = sun4i_usb_phy_init, | ||
205 | .exit = sun4i_usb_phy_exit, | ||
206 | .power_on = sun4i_usb_phy_power_on, | ||
207 | .power_off = sun4i_usb_phy_power_off, | ||
208 | .owner = THIS_MODULE, | ||
209 | }; | ||
210 | |||
211 | static struct phy *sun4i_usb_phy_xlate(struct device *dev, | ||
212 | struct of_phandle_args *args) | ||
213 | { | ||
214 | struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); | ||
215 | |||
216 | if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys)) | ||
217 | return ERR_PTR(-ENODEV); | ||
218 | |||
219 | return data->phys[args->args[0]].phy; | ||
220 | } | ||
221 | |||
222 | static int sun4i_usb_phy_probe(struct platform_device *pdev) | ||
223 | { | ||
224 | struct sun4i_usb_phy_data *data; | ||
225 | struct device *dev = &pdev->dev; | ||
226 | struct device_node *np = dev->of_node; | ||
227 | void __iomem *pmu = NULL; | ||
228 | struct phy_provider *phy_provider; | ||
229 | struct reset_control *reset; | ||
230 | struct regulator *vbus; | ||
231 | struct resource *res; | ||
232 | struct phy *phy; | ||
233 | char name[16]; | ||
234 | int i; | ||
235 | |||
236 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
237 | if (!data) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | mutex_init(&data->mutex); | ||
241 | |||
242 | if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy")) | ||
243 | data->num_phys = 2; | ||
244 | else | ||
245 | data->num_phys = 3; | ||
246 | |||
247 | if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) | ||
248 | data->disc_thresh = 3; | ||
249 | else | ||
250 | data->disc_thresh = 2; | ||
251 | |||
252 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); | ||
253 | data->base = devm_ioremap_resource(dev, res); | ||
254 | if (IS_ERR(data->base)) | ||
255 | return PTR_ERR(data->base); | ||
256 | |||
257 | data->clk = devm_clk_get(dev, "usb_phy"); | ||
258 | if (IS_ERR(data->clk)) { | ||
259 | dev_err(dev, "could not get usb_phy clock\n"); | ||
260 | return PTR_ERR(data->clk); | ||
261 | } | ||
262 | |||
263 | /* Skip 0, 0 is the phy for otg which is not yet supported. */ | ||
264 | for (i = 1; i < data->num_phys; i++) { | ||
265 | snprintf(name, sizeof(name), "usb%d_vbus", i); | ||
266 | vbus = devm_regulator_get_optional(dev, name); | ||
267 | if (IS_ERR(vbus)) { | ||
268 | if (PTR_ERR(vbus) == -EPROBE_DEFER) | ||
269 | return -EPROBE_DEFER; | ||
270 | vbus = NULL; | ||
271 | } | ||
272 | |||
273 | snprintf(name, sizeof(name), "usb%d_reset", i); | ||
274 | reset = devm_reset_control_get(dev, name); | ||
275 | if (IS_ERR(reset)) { | ||
276 | dev_err(dev, "failed to get reset %s\n", name); | ||
277 | return PTR_ERR(reset); | ||
278 | } | ||
279 | |||
280 | if (i) { /* No pmu for usbc0 */ | ||
281 | snprintf(name, sizeof(name), "pmu%d", i); | ||
282 | res = platform_get_resource_byname(pdev, | ||
283 | IORESOURCE_MEM, name); | ||
284 | pmu = devm_ioremap_resource(dev, res); | ||
285 | if (IS_ERR(pmu)) | ||
286 | return PTR_ERR(pmu); | ||
287 | } | ||
288 | |||
289 | phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL); | ||
290 | if (IS_ERR(phy)) { | ||
291 | dev_err(dev, "failed to create PHY %d\n", i); | ||
292 | return PTR_ERR(phy); | ||
293 | } | ||
294 | |||
295 | data->phys[i].phy = phy; | ||
296 | data->phys[i].pmu = pmu; | ||
297 | data->phys[i].vbus = vbus; | ||
298 | data->phys[i].reset = reset; | ||
299 | data->phys[i].index = i; | ||
300 | phy_set_drvdata(phy, &data->phys[i]); | ||
301 | } | ||
302 | |||
303 | dev_set_drvdata(dev, data); | ||
304 | phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate); | ||
305 | if (IS_ERR(phy_provider)) | ||
306 | return PTR_ERR(phy_provider); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static const struct of_device_id sun4i_usb_phy_of_match[] = { | ||
312 | { .compatible = "allwinner,sun4i-a10-usb-phy" }, | ||
313 | { .compatible = "allwinner,sun5i-a13-usb-phy" }, | ||
314 | { .compatible = "allwinner,sun7i-a20-usb-phy" }, | ||
315 | { }, | ||
316 | }; | ||
317 | MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); | ||
318 | |||
319 | static struct platform_driver sun4i_usb_phy_driver = { | ||
320 | .probe = sun4i_usb_phy_probe, | ||
321 | .driver = { | ||
322 | .of_match_table = sun4i_usb_phy_of_match, | ||
323 | .name = "sun4i-usb-phy", | ||
324 | .owner = THIS_MODULE, | ||
325 | } | ||
326 | }; | ||
327 | module_platform_driver(sun4i_usb_phy_driver); | ||
328 | |||
329 | MODULE_DESCRIPTION("Allwinner sun4i USB phy driver"); | ||
330 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
331 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c new file mode 100644 index 000000000000..591367654613 --- /dev/null +++ b/drivers/phy/phy-ti-pipe3.c | |||
@@ -0,0 +1,470 @@ | |||
1 | /* | ||
2 | * phy-ti-pipe3 - PIPE3 PHY driver. | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
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 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/phy/phy.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/clk.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/pm_runtime.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/phy/omap_control_phy.h> | ||
30 | #include <linux/of_platform.h> | ||
31 | |||
32 | #define PLL_STATUS 0x00000004 | ||
33 | #define PLL_GO 0x00000008 | ||
34 | #define PLL_CONFIGURATION1 0x0000000C | ||
35 | #define PLL_CONFIGURATION2 0x00000010 | ||
36 | #define PLL_CONFIGURATION3 0x00000014 | ||
37 | #define PLL_CONFIGURATION4 0x00000020 | ||
38 | |||
39 | #define PLL_REGM_MASK 0x001FFE00 | ||
40 | #define PLL_REGM_SHIFT 0x9 | ||
41 | #define PLL_REGM_F_MASK 0x0003FFFF | ||
42 | #define PLL_REGM_F_SHIFT 0x0 | ||
43 | #define PLL_REGN_MASK 0x000001FE | ||
44 | #define PLL_REGN_SHIFT 0x1 | ||
45 | #define PLL_SELFREQDCO_MASK 0x0000000E | ||
46 | #define PLL_SELFREQDCO_SHIFT 0x1 | ||
47 | #define PLL_SD_MASK 0x0003FC00 | ||
48 | #define PLL_SD_SHIFT 10 | ||
49 | #define SET_PLL_GO 0x1 | ||
50 | #define PLL_LDOPWDN BIT(15) | ||
51 | #define PLL_TICOPWDN BIT(16) | ||
52 | #define PLL_LOCK 0x2 | ||
53 | #define PLL_IDLE 0x1 | ||
54 | |||
55 | /* | ||
56 | * This is an Empirical value that works, need to confirm the actual | ||
57 | * value required for the PIPE3PHY_PLL_CONFIGURATION2.PLL_IDLE status | ||
58 | * to be correctly reflected in the PIPE3PHY_PLL_STATUS register. | ||
59 | */ | ||
60 | #define PLL_IDLE_TIME 100 /* in milliseconds */ | ||
61 | #define PLL_LOCK_TIME 100 /* in milliseconds */ | ||
62 | |||
63 | struct pipe3_dpll_params { | ||
64 | u16 m; | ||
65 | u8 n; | ||
66 | u8 freq:3; | ||
67 | u8 sd; | ||
68 | u32 mf; | ||
69 | }; | ||
70 | |||
71 | struct pipe3_dpll_map { | ||
72 | unsigned long rate; | ||
73 | struct pipe3_dpll_params params; | ||
74 | }; | ||
75 | |||
76 | struct ti_pipe3 { | ||
77 | void __iomem *pll_ctrl_base; | ||
78 | struct device *dev; | ||
79 | struct device *control_dev; | ||
80 | struct clk *wkupclk; | ||
81 | struct clk *sys_clk; | ||
82 | struct clk *refclk; | ||
83 | struct pipe3_dpll_map *dpll_map; | ||
84 | }; | ||
85 | |||
86 | static struct pipe3_dpll_map dpll_map_usb[] = { | ||
87 | {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ | ||
88 | {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ | ||
89 | {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ | ||
90 | {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ | ||
91 | {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ | ||
92 | {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ | ||
93 | { }, /* Terminator */ | ||
94 | }; | ||
95 | |||
96 | static struct pipe3_dpll_map dpll_map_sata[] = { | ||
97 | {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ | ||
98 | {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ | ||
99 | {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ | ||
100 | {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ | ||
101 | {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ | ||
102 | {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ | ||
103 | { }, /* Terminator */ | ||
104 | }; | ||
105 | |||
106 | static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset) | ||
107 | { | ||
108 | return __raw_readl(addr + offset); | ||
109 | } | ||
110 | |||
111 | static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset, | ||
112 | u32 data) | ||
113 | { | ||
114 | __raw_writel(data, addr + offset); | ||
115 | } | ||
116 | |||
117 | static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy) | ||
118 | { | ||
119 | unsigned long rate; | ||
120 | struct pipe3_dpll_map *dpll_map = phy->dpll_map; | ||
121 | |||
122 | rate = clk_get_rate(phy->sys_clk); | ||
123 | |||
124 | for (; dpll_map->rate; dpll_map++) { | ||
125 | if (rate == dpll_map->rate) | ||
126 | return &dpll_map->params; | ||
127 | } | ||
128 | |||
129 | dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate); | ||
130 | |||
131 | return NULL; | ||
132 | } | ||
133 | |||
134 | static int ti_pipe3_power_off(struct phy *x) | ||
135 | { | ||
136 | struct ti_pipe3 *phy = phy_get_drvdata(x); | ||
137 | |||
138 | omap_control_phy_power(phy->control_dev, 0); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int ti_pipe3_power_on(struct phy *x) | ||
144 | { | ||
145 | struct ti_pipe3 *phy = phy_get_drvdata(x); | ||
146 | |||
147 | omap_control_phy_power(phy->control_dev, 1); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy) | ||
153 | { | ||
154 | u32 val; | ||
155 | unsigned long timeout; | ||
156 | |||
157 | timeout = jiffies + msecs_to_jiffies(PLL_LOCK_TIME); | ||
158 | do { | ||
159 | cpu_relax(); | ||
160 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
161 | if (val & PLL_LOCK) | ||
162 | break; | ||
163 | } while (!time_after(jiffies, timeout)); | ||
164 | |||
165 | if (!(val & PLL_LOCK)) { | ||
166 | dev_err(phy->dev, "DPLL failed to lock\n"); | ||
167 | return -EBUSY; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int ti_pipe3_dpll_program(struct ti_pipe3 *phy) | ||
174 | { | ||
175 | u32 val; | ||
176 | struct pipe3_dpll_params *dpll_params; | ||
177 | |||
178 | dpll_params = ti_pipe3_get_dpll_params(phy); | ||
179 | if (!dpll_params) | ||
180 | return -EINVAL; | ||
181 | |||
182 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
183 | val &= ~PLL_REGN_MASK; | ||
184 | val |= dpll_params->n << PLL_REGN_SHIFT; | ||
185 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
186 | |||
187 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
188 | val &= ~PLL_SELFREQDCO_MASK; | ||
189 | val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; | ||
190 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
191 | |||
192 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
193 | val &= ~PLL_REGM_MASK; | ||
194 | val |= dpll_params->m << PLL_REGM_SHIFT; | ||
195 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
196 | |||
197 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); | ||
198 | val &= ~PLL_REGM_F_MASK; | ||
199 | val |= dpll_params->mf << PLL_REGM_F_SHIFT; | ||
200 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); | ||
201 | |||
202 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); | ||
203 | val &= ~PLL_SD_MASK; | ||
204 | val |= dpll_params->sd << PLL_SD_SHIFT; | ||
205 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); | ||
206 | |||
207 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); | ||
208 | |||
209 | return ti_pipe3_dpll_wait_lock(phy); | ||
210 | } | ||
211 | |||
212 | static int ti_pipe3_init(struct phy *x) | ||
213 | { | ||
214 | struct ti_pipe3 *phy = phy_get_drvdata(x); | ||
215 | u32 val; | ||
216 | int ret = 0; | ||
217 | |||
218 | /* Bring it out of IDLE if it is IDLE */ | ||
219 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
220 | if (val & PLL_IDLE) { | ||
221 | val &= ~PLL_IDLE; | ||
222 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
223 | ret = ti_pipe3_dpll_wait_lock(phy); | ||
224 | } | ||
225 | |||
226 | /* Program the DPLL only if not locked */ | ||
227 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
228 | if (!(val & PLL_LOCK)) | ||
229 | if (ti_pipe3_dpll_program(phy)) | ||
230 | return -EINVAL; | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static int ti_pipe3_exit(struct phy *x) | ||
236 | { | ||
237 | struct ti_pipe3 *phy = phy_get_drvdata(x); | ||
238 | u32 val; | ||
239 | unsigned long timeout; | ||
240 | |||
241 | /* SATA DPLL can't be powered down due to Errata i783 */ | ||
242 | if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) | ||
243 | return 0; | ||
244 | |||
245 | /* Put DPLL in IDLE mode */ | ||
246 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
247 | val |= PLL_IDLE; | ||
248 | ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
249 | |||
250 | /* wait for LDO and Oscillator to power down */ | ||
251 | timeout = jiffies + msecs_to_jiffies(PLL_IDLE_TIME); | ||
252 | do { | ||
253 | cpu_relax(); | ||
254 | val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
255 | if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) | ||
256 | break; | ||
257 | } while (!time_after(jiffies, timeout)); | ||
258 | |||
259 | if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { | ||
260 | dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n", | ||
261 | val); | ||
262 | return -EBUSY; | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | static struct phy_ops ops = { | ||
268 | .init = ti_pipe3_init, | ||
269 | .exit = ti_pipe3_exit, | ||
270 | .power_on = ti_pipe3_power_on, | ||
271 | .power_off = ti_pipe3_power_off, | ||
272 | .owner = THIS_MODULE, | ||
273 | }; | ||
274 | |||
275 | #ifdef CONFIG_OF | ||
276 | static const struct of_device_id ti_pipe3_id_table[]; | ||
277 | #endif | ||
278 | |||
279 | static int ti_pipe3_probe(struct platform_device *pdev) | ||
280 | { | ||
281 | struct ti_pipe3 *phy; | ||
282 | struct phy *generic_phy; | ||
283 | struct phy_provider *phy_provider; | ||
284 | struct resource *res; | ||
285 | struct device_node *node = pdev->dev.of_node; | ||
286 | struct device_node *control_node; | ||
287 | struct platform_device *control_pdev; | ||
288 | const struct of_device_id *match; | ||
289 | |||
290 | match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev); | ||
291 | if (!match) | ||
292 | return -EINVAL; | ||
293 | |||
294 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | ||
295 | if (!phy) { | ||
296 | dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n"); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | |||
300 | phy->dpll_map = (struct pipe3_dpll_map *)match->data; | ||
301 | if (!phy->dpll_map) { | ||
302 | dev_err(&pdev->dev, "no DPLL data\n"); | ||
303 | return -EINVAL; | ||
304 | } | ||
305 | |||
306 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); | ||
307 | phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); | ||
308 | if (IS_ERR(phy->pll_ctrl_base)) | ||
309 | return PTR_ERR(phy->pll_ctrl_base); | ||
310 | |||
311 | phy->dev = &pdev->dev; | ||
312 | |||
313 | if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { | ||
314 | |||
315 | phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); | ||
316 | if (IS_ERR(phy->wkupclk)) { | ||
317 | dev_err(&pdev->dev, "unable to get wkupclk\n"); | ||
318 | return PTR_ERR(phy->wkupclk); | ||
319 | } | ||
320 | |||
321 | phy->refclk = devm_clk_get(phy->dev, "refclk"); | ||
322 | if (IS_ERR(phy->refclk)) { | ||
323 | dev_err(&pdev->dev, "unable to get refclk\n"); | ||
324 | return PTR_ERR(phy->refclk); | ||
325 | } | ||
326 | } else { | ||
327 | phy->wkupclk = ERR_PTR(-ENODEV); | ||
328 | phy->refclk = ERR_PTR(-ENODEV); | ||
329 | } | ||
330 | |||
331 | phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); | ||
332 | if (IS_ERR(phy->sys_clk)) { | ||
333 | dev_err(&pdev->dev, "unable to get sysclk\n"); | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | |||
337 | control_node = of_parse_phandle(node, "ctrl-module", 0); | ||
338 | if (!control_node) { | ||
339 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); | ||
340 | return -EINVAL; | ||
341 | } | ||
342 | |||
343 | control_pdev = of_find_device_by_node(control_node); | ||
344 | if (!control_pdev) { | ||
345 | dev_err(&pdev->dev, "Failed to get control device\n"); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | phy->control_dev = &control_pdev->dev; | ||
350 | |||
351 | omap_control_phy_power(phy->control_dev, 0); | ||
352 | |||
353 | platform_set_drvdata(pdev, phy); | ||
354 | pm_runtime_enable(phy->dev); | ||
355 | |||
356 | generic_phy = devm_phy_create(phy->dev, &ops, NULL); | ||
357 | if (IS_ERR(generic_phy)) | ||
358 | return PTR_ERR(generic_phy); | ||
359 | |||
360 | phy_set_drvdata(generic_phy, phy); | ||
361 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
362 | of_phy_simple_xlate); | ||
363 | if (IS_ERR(phy_provider)) | ||
364 | return PTR_ERR(phy_provider); | ||
365 | |||
366 | pm_runtime_get(&pdev->dev); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int ti_pipe3_remove(struct platform_device *pdev) | ||
372 | { | ||
373 | if (!pm_runtime_suspended(&pdev->dev)) | ||
374 | pm_runtime_put(&pdev->dev); | ||
375 | pm_runtime_disable(&pdev->dev); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | #ifdef CONFIG_PM_RUNTIME | ||
381 | |||
382 | static int ti_pipe3_runtime_suspend(struct device *dev) | ||
383 | { | ||
384 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
385 | |||
386 | if (!IS_ERR(phy->wkupclk)) | ||
387 | clk_disable_unprepare(phy->wkupclk); | ||
388 | if (!IS_ERR(phy->refclk)) | ||
389 | clk_disable_unprepare(phy->refclk); | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int ti_pipe3_runtime_resume(struct device *dev) | ||
395 | { | ||
396 | u32 ret = 0; | ||
397 | struct ti_pipe3 *phy = dev_get_drvdata(dev); | ||
398 | |||
399 | if (!IS_ERR(phy->refclk)) { | ||
400 | ret = clk_prepare_enable(phy->refclk); | ||
401 | if (ret) { | ||
402 | dev_err(phy->dev, "Failed to enable refclk %d\n", ret); | ||
403 | goto err1; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | if (!IS_ERR(phy->wkupclk)) { | ||
408 | ret = clk_prepare_enable(phy->wkupclk); | ||
409 | if (ret) { | ||
410 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | ||
411 | goto err2; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | return 0; | ||
416 | |||
417 | err2: | ||
418 | if (!IS_ERR(phy->refclk)) | ||
419 | clk_disable_unprepare(phy->refclk); | ||
420 | |||
421 | err1: | ||
422 | return ret; | ||
423 | } | ||
424 | |||
425 | static const struct dev_pm_ops ti_pipe3_pm_ops = { | ||
426 | SET_RUNTIME_PM_OPS(ti_pipe3_runtime_suspend, | ||
427 | ti_pipe3_runtime_resume, NULL) | ||
428 | }; | ||
429 | |||
430 | #define DEV_PM_OPS (&ti_pipe3_pm_ops) | ||
431 | #else | ||
432 | #define DEV_PM_OPS NULL | ||
433 | #endif | ||
434 | |||
435 | #ifdef CONFIG_OF | ||
436 | static const struct of_device_id ti_pipe3_id_table[] = { | ||
437 | { | ||
438 | .compatible = "ti,phy-usb3", | ||
439 | .data = dpll_map_usb, | ||
440 | }, | ||
441 | { | ||
442 | .compatible = "ti,omap-usb3", | ||
443 | .data = dpll_map_usb, | ||
444 | }, | ||
445 | { | ||
446 | .compatible = "ti,phy-pipe3-sata", | ||
447 | .data = dpll_map_sata, | ||
448 | }, | ||
449 | {} | ||
450 | }; | ||
451 | MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); | ||
452 | #endif | ||
453 | |||
454 | static struct platform_driver ti_pipe3_driver = { | ||
455 | .probe = ti_pipe3_probe, | ||
456 | .remove = ti_pipe3_remove, | ||
457 | .driver = { | ||
458 | .name = "ti-pipe3", | ||
459 | .owner = THIS_MODULE, | ||
460 | .pm = DEV_PM_OPS, | ||
461 | .of_match_table = of_match_ptr(ti_pipe3_id_table), | ||
462 | }, | ||
463 | }; | ||
464 | |||
465 | module_platform_driver(ti_pipe3_driver); | ||
466 | |||
467 | MODULE_ALIAS("platform: ti_pipe3"); | ||
468 | MODULE_AUTHOR("Texas Instruments Inc."); | ||
469 | MODULE_DESCRIPTION("TI PIPE3 phy driver"); | ||
470 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index c3ace1db8136..2e0e9b3774c8 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
@@ -338,7 +338,7 @@ static void twl4030_usb_set_mode(struct twl4030_usb *twl, int mode) | |||
338 | dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", | 338 | dev_err(twl->dev, "unsupported T2 transceiver mode %d\n", |
339 | mode); | 339 | mode); |
340 | break; | 340 | break; |
341 | }; | 341 | } |
342 | } | 342 | } |
343 | 343 | ||
344 | static void twl4030_i2c_access(struct twl4030_usb *twl, int on) | 344 | static void twl4030_i2c_access(struct twl4030_usb *twl, int on) |
@@ -661,7 +661,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
661 | struct phy_provider *phy_provider; | 661 | struct phy_provider *phy_provider; |
662 | struct phy_init_data *init_data = NULL; | 662 | struct phy_init_data *init_data = NULL; |
663 | 663 | ||
664 | twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); | 664 | twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); |
665 | if (!twl) | 665 | if (!twl) |
666 | return -ENOMEM; | 666 | return -ENOMEM; |
667 | 667 | ||
@@ -676,7 +676,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
676 | return -EINVAL; | 676 | return -EINVAL; |
677 | } | 677 | } |
678 | 678 | ||
679 | otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); | 679 | otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); |
680 | if (!otg) | 680 | if (!otg) |
681 | return -ENOMEM; | 681 | return -ENOMEM; |
682 | 682 | ||
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c new file mode 100644 index 000000000000..4aa1ccd1511f --- /dev/null +++ b/drivers/phy/phy-xgene.c | |||
@@ -0,0 +1,1750 @@ | |||
1 | /* | ||
2 | * AppliedMicro X-Gene Multi-purpose PHY driver | ||
3 | * | ||
4 | * Copyright (c) 2014, Applied Micro Circuits Corporation | ||
5 | * Author: Loc Ho <lho@apm.com> | ||
6 | * Tuan Phan <tphan@apm.com> | ||
7 | * Suman Tripathi <stripathi@apm.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | * The APM X-Gene PHY consists of two PLL clock macro's (CMU) and lanes. | ||
23 | * The first PLL clock macro is used for internal reference clock. The second | ||
24 | * PLL clock macro is used to generate the clock for the PHY. This driver | ||
25 | * configures the first PLL CMU, the second PLL CMU, and programs the PHY to | ||
26 | * operate according to the mode of operation. The first PLL CMU is only | ||
27 | * required if internal clock is enabled. | ||
28 | * | ||
29 | * Logical Layer Out Of HW module units: | ||
30 | * | ||
31 | * ----------------- | ||
32 | * | Internal | |------| | ||
33 | * | Ref PLL CMU |----| | ------------- --------- | ||
34 | * ------------ ---- | MUX |-----|PHY PLL CMU|----| Serdes| | ||
35 | * | | | | --------- | ||
36 | * External Clock ------| | ------------- | ||
37 | * |------| | ||
38 | * | ||
39 | * The Ref PLL CMU CSR (Configuration System Registers) is accessed | ||
40 | * indirectly from the SDS offset at 0x2000. It is only required for | ||
41 | * internal reference clock. | ||
42 | * The PHY PLL CMU CSR is accessed indirectly from the SDS offset at 0x0000. | ||
43 | * The Serdes CSR is accessed indirectly from the SDS offset at 0x0400. | ||
44 | * | ||
45 | * The Ref PLL CMU can be located within the same PHY IP or outside the PHY IP | ||
46 | * due to shared Ref PLL CMU. For PHY with Ref PLL CMU shared with another IP, | ||
47 | * it is located outside the PHY IP. This is the case for the PHY located | ||
48 | * at 0x1f23a000 (SATA Port 4/5). For such PHY, another resource is required | ||
49 | * to located the SDS/Ref PLL CMU module and its clock for that IP enabled. | ||
50 | * | ||
51 | * Currently, this driver only supports Gen3 SATA mode with external clock. | ||
52 | */ | ||
53 | #include <linux/module.h> | ||
54 | #include <linux/platform_device.h> | ||
55 | #include <linux/io.h> | ||
56 | #include <linux/delay.h> | ||
57 | #include <linux/phy/phy.h> | ||
58 | #include <linux/clk.h> | ||
59 | |||
60 | /* Max 2 lanes per a PHY unit */ | ||
61 | #define MAX_LANE 2 | ||
62 | |||
63 | /* Register offset inside the PHY */ | ||
64 | #define SERDES_PLL_INDIRECT_OFFSET 0x0000 | ||
65 | #define SERDES_PLL_REF_INDIRECT_OFFSET 0x2000 | ||
66 | #define SERDES_INDIRECT_OFFSET 0x0400 | ||
67 | #define SERDES_LANE_STRIDE 0x0200 | ||
68 | |||
69 | /* Some default Serdes parameters */ | ||
70 | #define DEFAULT_SATA_TXBOOST_GAIN { 0x1e, 0x1e, 0x1e } | ||
71 | #define DEFAULT_SATA_TXEYEDIRECTION { 0x0, 0x0, 0x0 } | ||
72 | #define DEFAULT_SATA_TXEYETUNING { 0xa, 0xa, 0xa } | ||
73 | #define DEFAULT_SATA_SPD_SEL { 0x1, 0x3, 0x7 } | ||
74 | #define DEFAULT_SATA_TXAMP { 0x8, 0x8, 0x8 } | ||
75 | #define DEFAULT_SATA_TXCN1 { 0x2, 0x2, 0x2 } | ||
76 | #define DEFAULT_SATA_TXCN2 { 0x0, 0x0, 0x0 } | ||
77 | #define DEFAULT_SATA_TXCP1 { 0xa, 0xa, 0xa } | ||
78 | |||
79 | #define SATA_SPD_SEL_GEN3 0x7 | ||
80 | #define SATA_SPD_SEL_GEN2 0x3 | ||
81 | #define SATA_SPD_SEL_GEN1 0x1 | ||
82 | |||
83 | #define SSC_DISABLE 0 | ||
84 | #define SSC_ENABLE 1 | ||
85 | |||
86 | #define FBDIV_VAL_50M 0x77 | ||
87 | #define REFDIV_VAL_50M 0x1 | ||
88 | #define FBDIV_VAL_100M 0x3B | ||
89 | #define REFDIV_VAL_100M 0x0 | ||
90 | |||
91 | /* SATA Clock/Reset CSR */ | ||
92 | #define SATACLKENREG 0x00000000 | ||
93 | #define SATA0_CORE_CLKEN 0x00000002 | ||
94 | #define SATA1_CORE_CLKEN 0x00000004 | ||
95 | #define SATASRESETREG 0x00000004 | ||
96 | #define SATA_MEM_RESET_MASK 0x00000020 | ||
97 | #define SATA_MEM_RESET_RD(src) (((src) & 0x00000020) >> 5) | ||
98 | #define SATA_SDS_RESET_MASK 0x00000004 | ||
99 | #define SATA_CSR_RESET_MASK 0x00000001 | ||
100 | #define SATA_CORE_RESET_MASK 0x00000002 | ||
101 | #define SATA_PMCLK_RESET_MASK 0x00000010 | ||
102 | #define SATA_PCLK_RESET_MASK 0x00000008 | ||
103 | |||
104 | /* SDS CSR used for PHY Indirect access */ | ||
105 | #define SATA_ENET_SDS_PCS_CTL0 0x00000000 | ||
106 | #define REGSPEC_CFG_I_TX_WORDMODE0_SET(dst, src) \ | ||
107 | (((dst) & ~0x00070000) | (((u32) (src) << 16) & 0x00070000)) | ||
108 | #define REGSPEC_CFG_I_RX_WORDMODE0_SET(dst, src) \ | ||
109 | (((dst) & ~0x00e00000) | (((u32) (src) << 21) & 0x00e00000)) | ||
110 | #define SATA_ENET_SDS_CTL0 0x0000000c | ||
111 | #define REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(dst, src) \ | ||
112 | (((dst) & ~0x00007fff) | (((u32) (src)) & 0x00007fff)) | ||
113 | #define SATA_ENET_SDS_CTL1 0x00000010 | ||
114 | #define CFG_I_SPD_SEL_CDR_OVR1_SET(dst, src) \ | ||
115 | (((dst) & ~0x0000000f) | (((u32) (src)) & 0x0000000f)) | ||
116 | #define SATA_ENET_SDS_RST_CTL 0x00000024 | ||
117 | #define SATA_ENET_SDS_IND_CMD_REG 0x0000003c | ||
118 | #define CFG_IND_WR_CMD_MASK 0x00000001 | ||
119 | #define CFG_IND_RD_CMD_MASK 0x00000002 | ||
120 | #define CFG_IND_CMD_DONE_MASK 0x00000004 | ||
121 | #define CFG_IND_ADDR_SET(dst, src) \ | ||
122 | (((dst) & ~0x003ffff0) | (((u32) (src) << 4) & 0x003ffff0)) | ||
123 | #define SATA_ENET_SDS_IND_RDATA_REG 0x00000040 | ||
124 | #define SATA_ENET_SDS_IND_WDATA_REG 0x00000044 | ||
125 | #define SATA_ENET_CLK_MACRO_REG 0x0000004c | ||
126 | #define I_RESET_B_SET(dst, src) \ | ||
127 | (((dst) & ~0x00000001) | (((u32) (src)) & 0x00000001)) | ||
128 | #define I_PLL_FBDIV_SET(dst, src) \ | ||
129 | (((dst) & ~0x001ff000) | (((u32) (src) << 12) & 0x001ff000)) | ||
130 | #define I_CUSTOMEROV_SET(dst, src) \ | ||
131 | (((dst) & ~0x00000f80) | (((u32) (src) << 7) & 0x00000f80)) | ||
132 | #define O_PLL_LOCK_RD(src) (((src) & 0x40000000) >> 30) | ||
133 | #define O_PLL_READY_RD(src) (((src) & 0x80000000) >> 31) | ||
134 | |||
135 | /* PLL Clock Macro Unit (CMU) CSR accessing from SDS indirectly */ | ||
136 | #define CMU_REG0 0x00000 | ||
137 | #define CMU_REG0_PLL_REF_SEL_MASK 0x00002000 | ||
138 | #define CMU_REG0_PLL_REF_SEL_SET(dst, src) \ | ||
139 | (((dst) & ~0x00002000) | (((u32) (src) << 13) & 0x00002000)) | ||
140 | #define CMU_REG0_PDOWN_MASK 0x00004000 | ||
141 | #define CMU_REG0_CAL_COUNT_RESOL_SET(dst, src) \ | ||
142 | (((dst) & ~0x000000e0) | (((u32) (src) << 5) & 0x000000e0)) | ||
143 | #define CMU_REG1 0x00002 | ||
144 | #define CMU_REG1_PLL_CP_SET(dst, src) \ | ||
145 | (((dst) & ~0x00003c00) | (((u32) (src) << 10) & 0x00003c00)) | ||
146 | #define CMU_REG1_PLL_MANUALCAL_SET(dst, src) \ | ||
147 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
148 | #define CMU_REG1_PLL_CP_SEL_SET(dst, src) \ | ||
149 | (((dst) & ~0x000003e0) | (((u32) (src) << 5) & 0x000003e0)) | ||
150 | #define CMU_REG1_REFCLK_CMOS_SEL_MASK 0x00000001 | ||
151 | #define CMU_REG1_REFCLK_CMOS_SEL_SET(dst, src) \ | ||
152 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
153 | #define CMU_REG2 0x00004 | ||
154 | #define CMU_REG2_PLL_REFDIV_SET(dst, src) \ | ||
155 | (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) | ||
156 | #define CMU_REG2_PLL_LFRES_SET(dst, src) \ | ||
157 | (((dst) & ~0x0000001e) | (((u32) (src) << 1) & 0x0000001e)) | ||
158 | #define CMU_REG2_PLL_FBDIV_SET(dst, src) \ | ||
159 | (((dst) & ~0x00003fe0) | (((u32) (src) << 5) & 0x00003fe0)) | ||
160 | #define CMU_REG3 0x00006 | ||
161 | #define CMU_REG3_VCOVARSEL_SET(dst, src) \ | ||
162 | (((dst) & ~0x0000000f) | (((u32) (src) << 0) & 0x0000000f)) | ||
163 | #define CMU_REG3_VCO_MOMSEL_INIT_SET(dst, src) \ | ||
164 | (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) | ||
165 | #define CMU_REG3_VCO_MANMOMSEL_SET(dst, src) \ | ||
166 | (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) | ||
167 | #define CMU_REG4 0x00008 | ||
168 | #define CMU_REG5 0x0000a | ||
169 | #define CMU_REG5_PLL_LFSMCAP_SET(dst, src) \ | ||
170 | (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) | ||
171 | #define CMU_REG5_PLL_LOCK_RESOLUTION_SET(dst, src) \ | ||
172 | (((dst) & ~0x0000000e) | (((u32) (src) << 1) & 0x0000000e)) | ||
173 | #define CMU_REG5_PLL_LFCAP_SET(dst, src) \ | ||
174 | (((dst) & ~0x00003000) | (((u32) (src) << 12) & 0x00003000)) | ||
175 | #define CMU_REG5_PLL_RESETB_MASK 0x00000001 | ||
176 | #define CMU_REG6 0x0000c | ||
177 | #define CMU_REG6_PLL_VREGTRIM_SET(dst, src) \ | ||
178 | (((dst) & ~0x00000600) | (((u32) (src) << 9) & 0x00000600)) | ||
179 | #define CMU_REG6_MAN_PVT_CAL_SET(dst, src) \ | ||
180 | (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) | ||
181 | #define CMU_REG7 0x0000e | ||
182 | #define CMU_REG7_PLL_CALIB_DONE_RD(src) ((0x00004000 & (u32) (src)) >> 14) | ||
183 | #define CMU_REG7_VCO_CAL_FAIL_RD(src) ((0x00000c00 & (u32) (src)) >> 10) | ||
184 | #define CMU_REG8 0x00010 | ||
185 | #define CMU_REG9 0x00012 | ||
186 | #define CMU_REG9_WORD_LEN_8BIT 0x000 | ||
187 | #define CMU_REG9_WORD_LEN_10BIT 0x001 | ||
188 | #define CMU_REG9_WORD_LEN_16BIT 0x002 | ||
189 | #define CMU_REG9_WORD_LEN_20BIT 0x003 | ||
190 | #define CMU_REG9_WORD_LEN_32BIT 0x004 | ||
191 | #define CMU_REG9_WORD_LEN_40BIT 0x005 | ||
192 | #define CMU_REG9_WORD_LEN_64BIT 0x006 | ||
193 | #define CMU_REG9_WORD_LEN_66BIT 0x007 | ||
194 | #define CMU_REG9_TX_WORD_MODE_CH1_SET(dst, src) \ | ||
195 | (((dst) & ~0x00000380) | (((u32) (src) << 7) & 0x00000380)) | ||
196 | #define CMU_REG9_TX_WORD_MODE_CH0_SET(dst, src) \ | ||
197 | (((dst) & ~0x00000070) | (((u32) (src) << 4) & 0x00000070)) | ||
198 | #define CMU_REG9_PLL_POST_DIVBY2_SET(dst, src) \ | ||
199 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
200 | #define CMU_REG9_VBG_BYPASSB_SET(dst, src) \ | ||
201 | (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) | ||
202 | #define CMU_REG9_IGEN_BYPASS_SET(dst, src) \ | ||
203 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
204 | #define CMU_REG10 0x00014 | ||
205 | #define CMU_REG10_VREG_REFSEL_SET(dst, src) \ | ||
206 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
207 | #define CMU_REG11 0x00016 | ||
208 | #define CMU_REG12 0x00018 | ||
209 | #define CMU_REG12_STATE_DELAY9_SET(dst, src) \ | ||
210 | (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) | ||
211 | #define CMU_REG13 0x0001a | ||
212 | #define CMU_REG14 0x0001c | ||
213 | #define CMU_REG15 0x0001e | ||
214 | #define CMU_REG16 0x00020 | ||
215 | #define CMU_REG16_PVT_DN_MAN_ENA_MASK 0x00000001 | ||
216 | #define CMU_REG16_PVT_UP_MAN_ENA_MASK 0x00000002 | ||
217 | #define CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(dst, src) \ | ||
218 | (((dst) & ~0x0000001c) | (((u32) (src) << 2) & 0x0000001c)) | ||
219 | #define CMU_REG16_CALIBRATION_DONE_OVERRIDE_SET(dst, src) \ | ||
220 | (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) | ||
221 | #define CMU_REG16_BYPASS_PLL_LOCK_SET(dst, src) \ | ||
222 | (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) | ||
223 | #define CMU_REG17 0x00022 | ||
224 | #define CMU_REG17_PVT_CODE_R2A_SET(dst, src) \ | ||
225 | (((dst) & ~0x00007f00) | (((u32) (src) << 8) & 0x00007f00)) | ||
226 | #define CMU_REG17_RESERVED_7_SET(dst, src) \ | ||
227 | (((dst) & ~0x000000e0) | (((u32) (src) << 5) & 0x000000e0)) | ||
228 | #define CMU_REG17_PVT_TERM_MAN_ENA_MASK 0x00008000 | ||
229 | #define CMU_REG18 0x00024 | ||
230 | #define CMU_REG19 0x00026 | ||
231 | #define CMU_REG20 0x00028 | ||
232 | #define CMU_REG21 0x0002a | ||
233 | #define CMU_REG22 0x0002c | ||
234 | #define CMU_REG23 0x0002e | ||
235 | #define CMU_REG24 0x00030 | ||
236 | #define CMU_REG25 0x00032 | ||
237 | #define CMU_REG26 0x00034 | ||
238 | #define CMU_REG26_FORCE_PLL_LOCK_SET(dst, src) \ | ||
239 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
240 | #define CMU_REG27 0x00036 | ||
241 | #define CMU_REG28 0x00038 | ||
242 | #define CMU_REG29 0x0003a | ||
243 | #define CMU_REG30 0x0003c | ||
244 | #define CMU_REG30_LOCK_COUNT_SET(dst, src) \ | ||
245 | (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) | ||
246 | #define CMU_REG30_PCIE_MODE_SET(dst, src) \ | ||
247 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
248 | #define CMU_REG31 0x0003e | ||
249 | #define CMU_REG32 0x00040 | ||
250 | #define CMU_REG32_FORCE_VCOCAL_START_MASK 0x00004000 | ||
251 | #define CMU_REG32_PVT_CAL_WAIT_SEL_SET(dst, src) \ | ||
252 | (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) | ||
253 | #define CMU_REG32_IREF_ADJ_SET(dst, src) \ | ||
254 | (((dst) & ~0x00000180) | (((u32) (src) << 7) & 0x00000180)) | ||
255 | #define CMU_REG33 0x00042 | ||
256 | #define CMU_REG34 0x00044 | ||
257 | #define CMU_REG34_VCO_CAL_VTH_LO_MAX_SET(dst, src) \ | ||
258 | (((dst) & ~0x0000000f) | (((u32) (src) << 0) & 0x0000000f)) | ||
259 | #define CMU_REG34_VCO_CAL_VTH_HI_MAX_SET(dst, src) \ | ||
260 | (((dst) & ~0x00000f00) | (((u32) (src) << 8) & 0x00000f00)) | ||
261 | #define CMU_REG34_VCO_CAL_VTH_LO_MIN_SET(dst, src) \ | ||
262 | (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) | ||
263 | #define CMU_REG34_VCO_CAL_VTH_HI_MIN_SET(dst, src) \ | ||
264 | (((dst) & ~0x0000f000) | (((u32) (src) << 12) & 0x0000f000)) | ||
265 | #define CMU_REG35 0x00046 | ||
266 | #define CMU_REG35_PLL_SSC_MOD_SET(dst, src) \ | ||
267 | (((dst) & ~0x0000fe00) | (((u32) (src) << 9) & 0x0000fe00)) | ||
268 | #define CMU_REG36 0x00048 | ||
269 | #define CMU_REG36_PLL_SSC_EN_SET(dst, src) \ | ||
270 | (((dst) & ~0x00000010) | (((u32) (src) << 4) & 0x00000010)) | ||
271 | #define CMU_REG36_PLL_SSC_VSTEP_SET(dst, src) \ | ||
272 | (((dst) & ~0x0000ffc0) | (((u32) (src) << 6) & 0x0000ffc0)) | ||
273 | #define CMU_REG36_PLL_SSC_DSMSEL_SET(dst, src) \ | ||
274 | (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) | ||
275 | #define CMU_REG37 0x0004a | ||
276 | #define CMU_REG38 0x0004c | ||
277 | #define CMU_REG39 0x0004e | ||
278 | |||
279 | /* PHY lane CSR accessing from SDS indirectly */ | ||
280 | #define RXTX_REG0 0x000 | ||
281 | #define RXTX_REG0_CTLE_EQ_HR_SET(dst, src) \ | ||
282 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
283 | #define RXTX_REG0_CTLE_EQ_QR_SET(dst, src) \ | ||
284 | (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) | ||
285 | #define RXTX_REG0_CTLE_EQ_FR_SET(dst, src) \ | ||
286 | (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) | ||
287 | #define RXTX_REG1 0x002 | ||
288 | #define RXTX_REG1_RXACVCM_SET(dst, src) \ | ||
289 | (((dst) & ~0x0000f000) | (((u32) (src) << 12) & 0x0000f000)) | ||
290 | #define RXTX_REG1_CTLE_EQ_SET(dst, src) \ | ||
291 | (((dst) & ~0x00000f80) | (((u32) (src) << 7) & 0x00000f80)) | ||
292 | #define RXTX_REG1_RXVREG1_SET(dst, src) \ | ||
293 | (((dst) & ~0x00000060) | (((u32) (src) << 5) & 0x00000060)) | ||
294 | #define RXTX_REG1_RXIREF_ADJ_SET(dst, src) \ | ||
295 | (((dst) & ~0x00000006) | (((u32) (src) << 1) & 0x00000006)) | ||
296 | #define RXTX_REG2 0x004 | ||
297 | #define RXTX_REG2_VTT_ENA_SET(dst, src) \ | ||
298 | (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) | ||
299 | #define RXTX_REG2_TX_FIFO_ENA_SET(dst, src) \ | ||
300 | (((dst) & ~0x00000020) | (((u32) (src) << 5) & 0x00000020)) | ||
301 | #define RXTX_REG2_VTT_SEL_SET(dst, src) \ | ||
302 | (((dst) & ~0x000000c0) | (((u32) (src) << 6) & 0x000000c0)) | ||
303 | #define RXTX_REG4 0x008 | ||
304 | #define RXTX_REG4_TX_LOOPBACK_BUF_EN_MASK 0x00000040 | ||
305 | #define RXTX_REG4_TX_DATA_RATE_SET(dst, src) \ | ||
306 | (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) | ||
307 | #define RXTX_REG4_TX_WORD_MODE_SET(dst, src) \ | ||
308 | (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) | ||
309 | #define RXTX_REG5 0x00a | ||
310 | #define RXTX_REG5_TX_CN1_SET(dst, src) \ | ||
311 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
312 | #define RXTX_REG5_TX_CP1_SET(dst, src) \ | ||
313 | (((dst) & ~0x000007e0) | (((u32) (src) << 5) & 0x000007e0)) | ||
314 | #define RXTX_REG5_TX_CN2_SET(dst, src) \ | ||
315 | (((dst) & ~0x0000001f) | (((u32) (src) << 0) & 0x0000001f)) | ||
316 | #define RXTX_REG6 0x00c | ||
317 | #define RXTX_REG6_TXAMP_CNTL_SET(dst, src) \ | ||
318 | (((dst) & ~0x00000780) | (((u32) (src) << 7) & 0x00000780)) | ||
319 | #define RXTX_REG6_TXAMP_ENA_SET(dst, src) \ | ||
320 | (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) | ||
321 | #define RXTX_REG6_RX_BIST_ERRCNT_RD_SET(dst, src) \ | ||
322 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
323 | #define RXTX_REG6_TX_IDLE_SET(dst, src) \ | ||
324 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
325 | #define RXTX_REG6_RX_BIST_RESYNC_SET(dst, src) \ | ||
326 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
327 | #define RXTX_REG7 0x00e | ||
328 | #define RXTX_REG7_RESETB_RXD_MASK 0x00000100 | ||
329 | #define RXTX_REG7_RESETB_RXA_MASK 0x00000080 | ||
330 | #define RXTX_REG7_BIST_ENA_RX_SET(dst, src) \ | ||
331 | (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) | ||
332 | #define RXTX_REG7_RX_WORD_MODE_SET(dst, src) \ | ||
333 | (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) | ||
334 | #define RXTX_REG8 0x010 | ||
335 | #define RXTX_REG8_CDR_LOOP_ENA_SET(dst, src) \ | ||
336 | (((dst) & ~0x00004000) | (((u32) (src) << 14) & 0x00004000)) | ||
337 | #define RXTX_REG8_CDR_BYPASS_RXLOS_SET(dst, src) \ | ||
338 | (((dst) & ~0x00000800) | (((u32) (src) << 11) & 0x00000800)) | ||
339 | #define RXTX_REG8_SSC_ENABLE_SET(dst, src) \ | ||
340 | (((dst) & ~0x00000200) | (((u32) (src) << 9) & 0x00000200)) | ||
341 | #define RXTX_REG8_SD_VREF_SET(dst, src) \ | ||
342 | (((dst) & ~0x000000f0) | (((u32) (src) << 4) & 0x000000f0)) | ||
343 | #define RXTX_REG8_SD_DISABLE_SET(dst, src) \ | ||
344 | (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) | ||
345 | #define RXTX_REG7 0x00e | ||
346 | #define RXTX_REG7_RESETB_RXD_SET(dst, src) \ | ||
347 | (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) | ||
348 | #define RXTX_REG7_RESETB_RXA_SET(dst, src) \ | ||
349 | (((dst) & ~0x00000080) | (((u32) (src) << 7) & 0x00000080)) | ||
350 | #define RXTX_REG7_LOOP_BACK_ENA_CTLE_MASK 0x00004000 | ||
351 | #define RXTX_REG7_LOOP_BACK_ENA_CTLE_SET(dst, src) \ | ||
352 | (((dst) & ~0x00004000) | (((u32) (src) << 14) & 0x00004000)) | ||
353 | #define RXTX_REG11 0x016 | ||
354 | #define RXTX_REG11_PHASE_ADJUST_LIMIT_SET(dst, src) \ | ||
355 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
356 | #define RXTX_REG12 0x018 | ||
357 | #define RXTX_REG12_LATCH_OFF_ENA_SET(dst, src) \ | ||
358 | (((dst) & ~0x00002000) | (((u32) (src) << 13) & 0x00002000)) | ||
359 | #define RXTX_REG12_SUMOS_ENABLE_SET(dst, src) \ | ||
360 | (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) | ||
361 | #define RXTX_REG12_RX_DET_TERM_ENABLE_MASK 0x00000002 | ||
362 | #define RXTX_REG12_RX_DET_TERM_ENABLE_SET(dst, src) \ | ||
363 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
364 | #define RXTX_REG13 0x01a | ||
365 | #define RXTX_REG14 0x01c | ||
366 | #define RXTX_REG14_CLTE_LATCAL_MAN_PROG_SET(dst, src) \ | ||
367 | (((dst) & ~0x0000003f) | (((u32) (src) << 0) & 0x0000003f)) | ||
368 | #define RXTX_REG14_CTLE_LATCAL_MAN_ENA_SET(dst, src) \ | ||
369 | (((dst) & ~0x00000040) | (((u32) (src) << 6) & 0x00000040)) | ||
370 | #define RXTX_REG26 0x034 | ||
371 | #define RXTX_REG26_PERIOD_ERROR_LATCH_SET(dst, src) \ | ||
372 | (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) | ||
373 | #define RXTX_REG26_BLWC_ENA_SET(dst, src) \ | ||
374 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
375 | #define RXTX_REG21 0x02a | ||
376 | #define RXTX_REG21_DO_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) | ||
377 | #define RXTX_REG21_XO_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) | ||
378 | #define RXTX_REG21_LATCH_CAL_FAIL_ODD_RD(src) ((0x0000000f & (u32)(src))) | ||
379 | #define RXTX_REG22 0x02c | ||
380 | #define RXTX_REG22_SO_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) | ||
381 | #define RXTX_REG22_EO_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) | ||
382 | #define RXTX_REG22_LATCH_CAL_FAIL_EVEN_RD(src) ((0x0000000f & (u32)(src))) | ||
383 | #define RXTX_REG23 0x02e | ||
384 | #define RXTX_REG23_DE_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) | ||
385 | #define RXTX_REG23_XE_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) | ||
386 | #define RXTX_REG24 0x030 | ||
387 | #define RXTX_REG24_EE_LATCH_CALOUT_RD(src) ((0x0000fc00 & (u32) (src)) >> 10) | ||
388 | #define RXTX_REG24_SE_LATCH_CALOUT_RD(src) ((0x000003f0 & (u32) (src)) >> 4) | ||
389 | #define RXTX_REG27 0x036 | ||
390 | #define RXTX_REG28 0x038 | ||
391 | #define RXTX_REG31 0x03e | ||
392 | #define RXTX_REG38 0x04c | ||
393 | #define RXTX_REG38_CUSTOMER_PINMODE_INV_SET(dst, src) \ | ||
394 | (((dst) & 0x0000fffe) | (((u32) (src) << 1) & 0x0000fffe)) | ||
395 | #define RXTX_REG39 0x04e | ||
396 | #define RXTX_REG40 0x050 | ||
397 | #define RXTX_REG41 0x052 | ||
398 | #define RXTX_REG42 0x054 | ||
399 | #define RXTX_REG43 0x056 | ||
400 | #define RXTX_REG44 0x058 | ||
401 | #define RXTX_REG45 0x05a | ||
402 | #define RXTX_REG46 0x05c | ||
403 | #define RXTX_REG47 0x05e | ||
404 | #define RXTX_REG48 0x060 | ||
405 | #define RXTX_REG49 0x062 | ||
406 | #define RXTX_REG50 0x064 | ||
407 | #define RXTX_REG51 0x066 | ||
408 | #define RXTX_REG52 0x068 | ||
409 | #define RXTX_REG53 0x06a | ||
410 | #define RXTX_REG54 0x06c | ||
411 | #define RXTX_REG55 0x06e | ||
412 | #define RXTX_REG61 0x07a | ||
413 | #define RXTX_REG61_ISCAN_INBERT_SET(dst, src) \ | ||
414 | (((dst) & ~0x00000010) | (((u32) (src) << 4) & 0x00000010)) | ||
415 | #define RXTX_REG61_LOADFREQ_SHIFT_SET(dst, src) \ | ||
416 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
417 | #define RXTX_REG61_EYE_COUNT_WIDTH_SEL_SET(dst, src) \ | ||
418 | (((dst) & ~0x000000c0) | (((u32) (src) << 6) & 0x000000c0)) | ||
419 | #define RXTX_REG61_SPD_SEL_CDR_SET(dst, src) \ | ||
420 | (((dst) & ~0x00003c00) | (((u32) (src) << 10) & 0x00003c00)) | ||
421 | #define RXTX_REG62 0x07c | ||
422 | #define RXTX_REG62_PERIOD_H1_QLATCH_SET(dst, src) \ | ||
423 | (((dst) & ~0x00003800) | (((u32) (src) << 11) & 0x00003800)) | ||
424 | #define RXTX_REG81 0x0a2 | ||
425 | #define RXTX_REG89_MU_TH7_SET(dst, src) \ | ||
426 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
427 | #define RXTX_REG89_MU_TH8_SET(dst, src) \ | ||
428 | (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) | ||
429 | #define RXTX_REG89_MU_TH9_SET(dst, src) \ | ||
430 | (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) | ||
431 | #define RXTX_REG96 0x0c0 | ||
432 | #define RXTX_REG96_MU_FREQ1_SET(dst, src) \ | ||
433 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
434 | #define RXTX_REG96_MU_FREQ2_SET(dst, src) \ | ||
435 | (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) | ||
436 | #define RXTX_REG96_MU_FREQ3_SET(dst, src) \ | ||
437 | (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) | ||
438 | #define RXTX_REG99 0x0c6 | ||
439 | #define RXTX_REG99_MU_PHASE1_SET(dst, src) \ | ||
440 | (((dst) & ~0x0000f800) | (((u32) (src) << 11) & 0x0000f800)) | ||
441 | #define RXTX_REG99_MU_PHASE2_SET(dst, src) \ | ||
442 | (((dst) & ~0x000007c0) | (((u32) (src) << 6) & 0x000007c0)) | ||
443 | #define RXTX_REG99_MU_PHASE3_SET(dst, src) \ | ||
444 | (((dst) & ~0x0000003e) | (((u32) (src) << 1) & 0x0000003e)) | ||
445 | #define RXTX_REG102 0x0cc | ||
446 | #define RXTX_REG102_FREQLOOP_LIMIT_SET(dst, src) \ | ||
447 | (((dst) & ~0x00000060) | (((u32) (src) << 5) & 0x00000060)) | ||
448 | #define RXTX_REG114 0x0e4 | ||
449 | #define RXTX_REG121 0x0f2 | ||
450 | #define RXTX_REG121_SUMOS_CAL_CODE_RD(src) ((0x0000003e & (u32)(src)) >> 0x1) | ||
451 | #define RXTX_REG125 0x0fa | ||
452 | #define RXTX_REG125_PQ_REG_SET(dst, src) \ | ||
453 | (((dst) & ~0x0000fe00) | (((u32) (src) << 9) & 0x0000fe00)) | ||
454 | #define RXTX_REG125_SIGN_PQ_SET(dst, src) \ | ||
455 | (((dst) & ~0x00000100) | (((u32) (src) << 8) & 0x00000100)) | ||
456 | #define RXTX_REG125_SIGN_PQ_2C_SET(dst, src) \ | ||
457 | (((dst) & ~0x00000080) | (((u32) (src) << 7) & 0x00000080)) | ||
458 | #define RXTX_REG125_PHZ_MANUALCODE_SET(dst, src) \ | ||
459 | (((dst) & ~0x0000007c) | (((u32) (src) << 2) & 0x0000007c)) | ||
460 | #define RXTX_REG125_PHZ_MANUAL_SET(dst, src) \ | ||
461 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
462 | #define RXTX_REG127 0x0fe | ||
463 | #define RXTX_REG127_FORCE_SUM_CAL_START_MASK 0x00000002 | ||
464 | #define RXTX_REG127_FORCE_LAT_CAL_START_MASK 0x00000004 | ||
465 | #define RXTX_REG127_FORCE_SUM_CAL_START_SET(dst, src) \ | ||
466 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
467 | #define RXTX_REG127_FORCE_LAT_CAL_START_SET(dst, src) \ | ||
468 | (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) | ||
469 | #define RXTX_REG127_LATCH_MAN_CAL_ENA_SET(dst, src) \ | ||
470 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
471 | #define RXTX_REG127_DO_LATCH_MANCAL_SET(dst, src) \ | ||
472 | (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) | ||
473 | #define RXTX_REG127_XO_LATCH_MANCAL_SET(dst, src) \ | ||
474 | (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) | ||
475 | #define RXTX_REG128 0x100 | ||
476 | #define RXTX_REG128_LATCH_CAL_WAIT_SEL_SET(dst, src) \ | ||
477 | (((dst) & ~0x0000000c) | (((u32) (src) << 2) & 0x0000000c)) | ||
478 | #define RXTX_REG128_EO_LATCH_MANCAL_SET(dst, src) \ | ||
479 | (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) | ||
480 | #define RXTX_REG128_SO_LATCH_MANCAL_SET(dst, src) \ | ||
481 | (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) | ||
482 | #define RXTX_REG129 0x102 | ||
483 | #define RXTX_REG129_DE_LATCH_MANCAL_SET(dst, src) \ | ||
484 | (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) | ||
485 | #define RXTX_REG129_XE_LATCH_MANCAL_SET(dst, src) \ | ||
486 | (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) | ||
487 | #define RXTX_REG130 0x104 | ||
488 | #define RXTX_REG130_EE_LATCH_MANCAL_SET(dst, src) \ | ||
489 | (((dst) & ~0x0000fc00) | (((u32) (src) << 10) & 0x0000fc00)) | ||
490 | #define RXTX_REG130_SE_LATCH_MANCAL_SET(dst, src) \ | ||
491 | (((dst) & ~0x000003f0) | (((u32) (src) << 4) & 0x000003f0)) | ||
492 | #define RXTX_REG145 0x122 | ||
493 | #define RXTX_REG145_TX_IDLE_SATA_SET(dst, src) \ | ||
494 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
495 | #define RXTX_REG145_RXES_ENA_SET(dst, src) \ | ||
496 | (((dst) & ~0x00000002) | (((u32) (src) << 1) & 0x00000002)) | ||
497 | #define RXTX_REG145_RXDFE_CONFIG_SET(dst, src) \ | ||
498 | (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) | ||
499 | #define RXTX_REG145_RXVWES_LATENA_SET(dst, src) \ | ||
500 | (((dst) & ~0x00000004) | (((u32) (src) << 2) & 0x00000004)) | ||
501 | #define RXTX_REG147 0x126 | ||
502 | #define RXTX_REG148 0x128 | ||
503 | |||
504 | /* Clock macro type */ | ||
505 | enum cmu_type_t { | ||
506 | REF_CMU = 0, /* Clock macro is the internal reference clock */ | ||
507 | PHY_CMU = 1, /* Clock macro is the PLL for the Serdes */ | ||
508 | }; | ||
509 | |||
510 | enum mux_type_t { | ||
511 | MUX_SELECT_ATA = 0, /* Switch the MUX to ATA */ | ||
512 | MUX_SELECT_SGMMII = 0, /* Switch the MUX to SGMII */ | ||
513 | }; | ||
514 | |||
515 | enum clk_type_t { | ||
516 | CLK_EXT_DIFF = 0, /* External differential */ | ||
517 | CLK_INT_DIFF = 1, /* Internal differential */ | ||
518 | CLK_INT_SING = 2, /* Internal single ended */ | ||
519 | }; | ||
520 | |||
521 | enum phy_mode { | ||
522 | MODE_SATA = 0, /* List them for simple reference */ | ||
523 | MODE_SGMII = 1, | ||
524 | MODE_PCIE = 2, | ||
525 | MODE_USB = 3, | ||
526 | MODE_XFI = 4, | ||
527 | MODE_MAX | ||
528 | }; | ||
529 | |||
530 | struct xgene_sata_override_param { | ||
531 | u32 speed[MAX_LANE]; /* Index for override parameter per lane */ | ||
532 | u32 txspeed[3]; /* Tx speed */ | ||
533 | u32 txboostgain[MAX_LANE*3]; /* Tx freq boost and gain control */ | ||
534 | u32 txeyetuning[MAX_LANE*3]; /* Tx eye tuning */ | ||
535 | u32 txeyedirection[MAX_LANE*3]; /* Tx eye tuning direction */ | ||
536 | u32 txamplitude[MAX_LANE*3]; /* Tx amplitude control */ | ||
537 | u32 txprecursor_cn1[MAX_LANE*3]; /* Tx emphasis taps 1st pre-cursor */ | ||
538 | u32 txprecursor_cn2[MAX_LANE*3]; /* Tx emphasis taps 2nd pre-cursor */ | ||
539 | u32 txpostcursor_cp1[MAX_LANE*3]; /* Tx emphasis taps post-cursor */ | ||
540 | }; | ||
541 | |||
542 | struct xgene_phy_ctx { | ||
543 | struct device *dev; | ||
544 | struct phy *phy; | ||
545 | enum phy_mode mode; /* Mode of operation */ | ||
546 | enum clk_type_t clk_type; /* Input clock selection */ | ||
547 | void __iomem *sds_base; /* PHY CSR base addr */ | ||
548 | struct clk *clk; /* Optional clock */ | ||
549 | |||
550 | /* Override Serdes parameters */ | ||
551 | struct xgene_sata_override_param sata_param; | ||
552 | }; | ||
553 | |||
554 | /* | ||
555 | * For chip earlier than A3 version, enable this flag. | ||
556 | * To enable, pass boot argument phy_xgene.preA3Chip=1 | ||
557 | */ | ||
558 | static int preA3Chip; | ||
559 | MODULE_PARM_DESC(preA3Chip, "Enable pre-A3 chip support (1=enable 0=disable)"); | ||
560 | module_param_named(preA3Chip, preA3Chip, int, 0444); | ||
561 | |||
562 | static void sds_wr(void __iomem *csr_base, u32 indirect_cmd_reg, | ||
563 | u32 indirect_data_reg, u32 addr, u32 data) | ||
564 | { | ||
565 | unsigned long deadline = jiffies + HZ; | ||
566 | u32 val; | ||
567 | u32 cmd; | ||
568 | |||
569 | cmd = CFG_IND_WR_CMD_MASK | CFG_IND_CMD_DONE_MASK; | ||
570 | cmd = CFG_IND_ADDR_SET(cmd, addr); | ||
571 | writel(data, csr_base + indirect_data_reg); | ||
572 | readl(csr_base + indirect_data_reg); /* Force a barrier */ | ||
573 | writel(cmd, csr_base + indirect_cmd_reg); | ||
574 | readl(csr_base + indirect_cmd_reg); /* Force a barrier */ | ||
575 | do { | ||
576 | val = readl(csr_base + indirect_cmd_reg); | ||
577 | } while (!(val & CFG_IND_CMD_DONE_MASK) && | ||
578 | time_before(jiffies, deadline)); | ||
579 | if (!(val & CFG_IND_CMD_DONE_MASK)) | ||
580 | pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n", | ||
581 | csr_base + indirect_cmd_reg, addr, data); | ||
582 | } | ||
583 | |||
584 | static void sds_rd(void __iomem *csr_base, u32 indirect_cmd_reg, | ||
585 | u32 indirect_data_reg, u32 addr, u32 *data) | ||
586 | { | ||
587 | unsigned long deadline = jiffies + HZ; | ||
588 | u32 val; | ||
589 | u32 cmd; | ||
590 | |||
591 | cmd = CFG_IND_RD_CMD_MASK | CFG_IND_CMD_DONE_MASK; | ||
592 | cmd = CFG_IND_ADDR_SET(cmd, addr); | ||
593 | writel(cmd, csr_base + indirect_cmd_reg); | ||
594 | readl(csr_base + indirect_cmd_reg); /* Force a barrier */ | ||
595 | do { | ||
596 | val = readl(csr_base + indirect_cmd_reg); | ||
597 | } while (!(val & CFG_IND_CMD_DONE_MASK) && | ||
598 | time_before(jiffies, deadline)); | ||
599 | *data = readl(csr_base + indirect_data_reg); | ||
600 | if (!(val & CFG_IND_CMD_DONE_MASK)) | ||
601 | pr_err("SDS WR timeout at 0x%p offset 0x%08X value 0x%08X\n", | ||
602 | csr_base + indirect_cmd_reg, addr, *data); | ||
603 | } | ||
604 | |||
605 | static void cmu_wr(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, | ||
606 | u32 reg, u32 data) | ||
607 | { | ||
608 | void __iomem *sds_base = ctx->sds_base; | ||
609 | u32 val; | ||
610 | |||
611 | if (cmu_type == REF_CMU) | ||
612 | reg += SERDES_PLL_REF_INDIRECT_OFFSET; | ||
613 | else | ||
614 | reg += SERDES_PLL_INDIRECT_OFFSET; | ||
615 | sds_wr(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
616 | SATA_ENET_SDS_IND_WDATA_REG, reg, data); | ||
617 | sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
618 | SATA_ENET_SDS_IND_RDATA_REG, reg, &val); | ||
619 | pr_debug("CMU WR addr 0x%X value 0x%08X <-> 0x%08X\n", reg, data, val); | ||
620 | } | ||
621 | |||
622 | static void cmu_rd(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, | ||
623 | u32 reg, u32 *data) | ||
624 | { | ||
625 | void __iomem *sds_base = ctx->sds_base; | ||
626 | |||
627 | if (cmu_type == REF_CMU) | ||
628 | reg += SERDES_PLL_REF_INDIRECT_OFFSET; | ||
629 | else | ||
630 | reg += SERDES_PLL_INDIRECT_OFFSET; | ||
631 | sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
632 | SATA_ENET_SDS_IND_RDATA_REG, reg, data); | ||
633 | pr_debug("CMU RD addr 0x%X value 0x%08X\n", reg, *data); | ||
634 | } | ||
635 | |||
636 | static void cmu_toggle1to0(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, | ||
637 | u32 reg, u32 bits) | ||
638 | { | ||
639 | u32 val; | ||
640 | |||
641 | cmu_rd(ctx, cmu_type, reg, &val); | ||
642 | val |= bits; | ||
643 | cmu_wr(ctx, cmu_type, reg, val); | ||
644 | cmu_rd(ctx, cmu_type, reg, &val); | ||
645 | val &= ~bits; | ||
646 | cmu_wr(ctx, cmu_type, reg, val); | ||
647 | } | ||
648 | |||
649 | static void cmu_clrbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, | ||
650 | u32 reg, u32 bits) | ||
651 | { | ||
652 | u32 val; | ||
653 | |||
654 | cmu_rd(ctx, cmu_type, reg, &val); | ||
655 | val &= ~bits; | ||
656 | cmu_wr(ctx, cmu_type, reg, val); | ||
657 | } | ||
658 | |||
659 | static void cmu_setbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type, | ||
660 | u32 reg, u32 bits) | ||
661 | { | ||
662 | u32 val; | ||
663 | |||
664 | cmu_rd(ctx, cmu_type, reg, &val); | ||
665 | val |= bits; | ||
666 | cmu_wr(ctx, cmu_type, reg, val); | ||
667 | } | ||
668 | |||
669 | static void serdes_wr(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 data) | ||
670 | { | ||
671 | void __iomem *sds_base = ctx->sds_base; | ||
672 | u32 val; | ||
673 | |||
674 | reg += SERDES_INDIRECT_OFFSET; | ||
675 | reg += lane * SERDES_LANE_STRIDE; | ||
676 | sds_wr(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
677 | SATA_ENET_SDS_IND_WDATA_REG, reg, data); | ||
678 | sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
679 | SATA_ENET_SDS_IND_RDATA_REG, reg, &val); | ||
680 | pr_debug("SERDES WR addr 0x%X value 0x%08X <-> 0x%08X\n", reg, data, | ||
681 | val); | ||
682 | } | ||
683 | |||
684 | static void serdes_rd(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 *data) | ||
685 | { | ||
686 | void __iomem *sds_base = ctx->sds_base; | ||
687 | |||
688 | reg += SERDES_INDIRECT_OFFSET; | ||
689 | reg += lane * SERDES_LANE_STRIDE; | ||
690 | sds_rd(sds_base, SATA_ENET_SDS_IND_CMD_REG, | ||
691 | SATA_ENET_SDS_IND_RDATA_REG, reg, data); | ||
692 | pr_debug("SERDES RD addr 0x%X value 0x%08X\n", reg, *data); | ||
693 | } | ||
694 | |||
695 | static void serdes_clrbits(struct xgene_phy_ctx *ctx, int lane, u32 reg, | ||
696 | u32 bits) | ||
697 | { | ||
698 | u32 val; | ||
699 | |||
700 | serdes_rd(ctx, lane, reg, &val); | ||
701 | val &= ~bits; | ||
702 | serdes_wr(ctx, lane, reg, val); | ||
703 | } | ||
704 | |||
705 | static void serdes_setbits(struct xgene_phy_ctx *ctx, int lane, u32 reg, | ||
706 | u32 bits) | ||
707 | { | ||
708 | u32 val; | ||
709 | |||
710 | serdes_rd(ctx, lane, reg, &val); | ||
711 | val |= bits; | ||
712 | serdes_wr(ctx, lane, reg, val); | ||
713 | } | ||
714 | |||
715 | static void xgene_phy_cfg_cmu_clk_type(struct xgene_phy_ctx *ctx, | ||
716 | enum cmu_type_t cmu_type, | ||
717 | enum clk_type_t clk_type) | ||
718 | { | ||
719 | u32 val; | ||
720 | |||
721 | /* Set the reset sequence delay for TX ready assertion */ | ||
722 | cmu_rd(ctx, cmu_type, CMU_REG12, &val); | ||
723 | val = CMU_REG12_STATE_DELAY9_SET(val, 0x1); | ||
724 | cmu_wr(ctx, cmu_type, CMU_REG12, val); | ||
725 | /* Set the programmable stage delays between various enable stages */ | ||
726 | cmu_wr(ctx, cmu_type, CMU_REG13, 0x0222); | ||
727 | cmu_wr(ctx, cmu_type, CMU_REG14, 0x2225); | ||
728 | |||
729 | /* Configure clock type */ | ||
730 | if (clk_type == CLK_EXT_DIFF) { | ||
731 | /* Select external clock mux */ | ||
732 | cmu_rd(ctx, cmu_type, CMU_REG0, &val); | ||
733 | val = CMU_REG0_PLL_REF_SEL_SET(val, 0x0); | ||
734 | cmu_wr(ctx, cmu_type, CMU_REG0, val); | ||
735 | /* Select CMOS as reference clock */ | ||
736 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
737 | val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x0); | ||
738 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
739 | dev_dbg(ctx->dev, "Set external reference clock\n"); | ||
740 | } else if (clk_type == CLK_INT_DIFF) { | ||
741 | /* Select internal clock mux */ | ||
742 | cmu_rd(ctx, cmu_type, CMU_REG0, &val); | ||
743 | val = CMU_REG0_PLL_REF_SEL_SET(val, 0x1); | ||
744 | cmu_wr(ctx, cmu_type, CMU_REG0, val); | ||
745 | /* Select CMOS as reference clock */ | ||
746 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
747 | val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x1); | ||
748 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
749 | dev_dbg(ctx->dev, "Set internal reference clock\n"); | ||
750 | } else if (clk_type == CLK_INT_SING) { | ||
751 | /* | ||
752 | * NOTE: This clock type is NOT support for controller | ||
753 | * whose internal clock shared in the PCIe controller | ||
754 | * | ||
755 | * Select internal clock mux | ||
756 | */ | ||
757 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
758 | val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x1); | ||
759 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
760 | /* Select CML as reference clock */ | ||
761 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
762 | val = CMU_REG1_REFCLK_CMOS_SEL_SET(val, 0x0); | ||
763 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
764 | dev_dbg(ctx->dev, | ||
765 | "Set internal single ended reference clock\n"); | ||
766 | } | ||
767 | } | ||
768 | |||
769 | static void xgene_phy_sata_cfg_cmu_core(struct xgene_phy_ctx *ctx, | ||
770 | enum cmu_type_t cmu_type, | ||
771 | enum clk_type_t clk_type) | ||
772 | { | ||
773 | u32 val; | ||
774 | int ref_100MHz; | ||
775 | |||
776 | if (cmu_type == REF_CMU) { | ||
777 | /* Set VCO calibration voltage threshold */ | ||
778 | cmu_rd(ctx, cmu_type, CMU_REG34, &val); | ||
779 | val = CMU_REG34_VCO_CAL_VTH_LO_MAX_SET(val, 0x7); | ||
780 | val = CMU_REG34_VCO_CAL_VTH_HI_MAX_SET(val, 0xc); | ||
781 | val = CMU_REG34_VCO_CAL_VTH_LO_MIN_SET(val, 0x3); | ||
782 | val = CMU_REG34_VCO_CAL_VTH_HI_MIN_SET(val, 0x8); | ||
783 | cmu_wr(ctx, cmu_type, CMU_REG34, val); | ||
784 | } | ||
785 | |||
786 | /* Set the VCO calibration counter */ | ||
787 | cmu_rd(ctx, cmu_type, CMU_REG0, &val); | ||
788 | if (cmu_type == REF_CMU || preA3Chip) | ||
789 | val = CMU_REG0_CAL_COUNT_RESOL_SET(val, 0x4); | ||
790 | else | ||
791 | val = CMU_REG0_CAL_COUNT_RESOL_SET(val, 0x7); | ||
792 | cmu_wr(ctx, cmu_type, CMU_REG0, val); | ||
793 | |||
794 | /* Configure PLL for calibration */ | ||
795 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
796 | val = CMU_REG1_PLL_CP_SET(val, 0x1); | ||
797 | if (cmu_type == REF_CMU || preA3Chip) | ||
798 | val = CMU_REG1_PLL_CP_SEL_SET(val, 0x5); | ||
799 | else | ||
800 | val = CMU_REG1_PLL_CP_SEL_SET(val, 0x3); | ||
801 | if (cmu_type == REF_CMU) | ||
802 | val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x0); | ||
803 | else | ||
804 | val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x1); | ||
805 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
806 | |||
807 | if (cmu_type != REF_CMU) | ||
808 | cmu_clrbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); | ||
809 | |||
810 | /* Configure the PLL for either 100MHz or 50MHz */ | ||
811 | cmu_rd(ctx, cmu_type, CMU_REG2, &val); | ||
812 | if (cmu_type == REF_CMU) { | ||
813 | val = CMU_REG2_PLL_LFRES_SET(val, 0xa); | ||
814 | ref_100MHz = 1; | ||
815 | } else { | ||
816 | val = CMU_REG2_PLL_LFRES_SET(val, 0x3); | ||
817 | if (clk_type == CLK_EXT_DIFF) | ||
818 | ref_100MHz = 0; | ||
819 | else | ||
820 | ref_100MHz = 1; | ||
821 | } | ||
822 | if (ref_100MHz) { | ||
823 | val = CMU_REG2_PLL_FBDIV_SET(val, FBDIV_VAL_100M); | ||
824 | val = CMU_REG2_PLL_REFDIV_SET(val, REFDIV_VAL_100M); | ||
825 | } else { | ||
826 | val = CMU_REG2_PLL_FBDIV_SET(val, FBDIV_VAL_50M); | ||
827 | val = CMU_REG2_PLL_REFDIV_SET(val, REFDIV_VAL_50M); | ||
828 | } | ||
829 | cmu_wr(ctx, cmu_type, CMU_REG2, val); | ||
830 | |||
831 | /* Configure the VCO */ | ||
832 | cmu_rd(ctx, cmu_type, CMU_REG3, &val); | ||
833 | if (cmu_type == REF_CMU) { | ||
834 | val = CMU_REG3_VCOVARSEL_SET(val, 0x3); | ||
835 | val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x10); | ||
836 | } else { | ||
837 | val = CMU_REG3_VCOVARSEL_SET(val, 0xF); | ||
838 | if (preA3Chip) | ||
839 | val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x15); | ||
840 | else | ||
841 | val = CMU_REG3_VCO_MOMSEL_INIT_SET(val, 0x1a); | ||
842 | val = CMU_REG3_VCO_MANMOMSEL_SET(val, 0x15); | ||
843 | } | ||
844 | cmu_wr(ctx, cmu_type, CMU_REG3, val); | ||
845 | |||
846 | /* Disable force PLL lock */ | ||
847 | cmu_rd(ctx, cmu_type, CMU_REG26, &val); | ||
848 | val = CMU_REG26_FORCE_PLL_LOCK_SET(val, 0x0); | ||
849 | cmu_wr(ctx, cmu_type, CMU_REG26, val); | ||
850 | |||
851 | /* Setup PLL loop filter */ | ||
852 | cmu_rd(ctx, cmu_type, CMU_REG5, &val); | ||
853 | val = CMU_REG5_PLL_LFSMCAP_SET(val, 0x3); | ||
854 | val = CMU_REG5_PLL_LFCAP_SET(val, 0x3); | ||
855 | if (cmu_type == REF_CMU || !preA3Chip) | ||
856 | val = CMU_REG5_PLL_LOCK_RESOLUTION_SET(val, 0x7); | ||
857 | else | ||
858 | val = CMU_REG5_PLL_LOCK_RESOLUTION_SET(val, 0x4); | ||
859 | cmu_wr(ctx, cmu_type, CMU_REG5, val); | ||
860 | |||
861 | /* Enable or disable manual calibration */ | ||
862 | cmu_rd(ctx, cmu_type, CMU_REG6, &val); | ||
863 | val = CMU_REG6_PLL_VREGTRIM_SET(val, preA3Chip ? 0x0 : 0x2); | ||
864 | val = CMU_REG6_MAN_PVT_CAL_SET(val, preA3Chip ? 0x1 : 0x0); | ||
865 | cmu_wr(ctx, cmu_type, CMU_REG6, val); | ||
866 | |||
867 | /* Configure lane for 20-bits */ | ||
868 | if (cmu_type == PHY_CMU) { | ||
869 | cmu_rd(ctx, cmu_type, CMU_REG9, &val); | ||
870 | val = CMU_REG9_TX_WORD_MODE_CH1_SET(val, | ||
871 | CMU_REG9_WORD_LEN_20BIT); | ||
872 | val = CMU_REG9_TX_WORD_MODE_CH0_SET(val, | ||
873 | CMU_REG9_WORD_LEN_20BIT); | ||
874 | val = CMU_REG9_PLL_POST_DIVBY2_SET(val, 0x1); | ||
875 | if (!preA3Chip) { | ||
876 | val = CMU_REG9_VBG_BYPASSB_SET(val, 0x0); | ||
877 | val = CMU_REG9_IGEN_BYPASS_SET(val , 0x0); | ||
878 | } | ||
879 | cmu_wr(ctx, cmu_type, CMU_REG9, val); | ||
880 | |||
881 | if (!preA3Chip) { | ||
882 | cmu_rd(ctx, cmu_type, CMU_REG10, &val); | ||
883 | val = CMU_REG10_VREG_REFSEL_SET(val, 0x1); | ||
884 | cmu_wr(ctx, cmu_type, CMU_REG10, val); | ||
885 | } | ||
886 | } | ||
887 | |||
888 | cmu_rd(ctx, cmu_type, CMU_REG16, &val); | ||
889 | val = CMU_REG16_CALIBRATION_DONE_OVERRIDE_SET(val, 0x1); | ||
890 | val = CMU_REG16_BYPASS_PLL_LOCK_SET(val, 0x1); | ||
891 | if (cmu_type == REF_CMU || preA3Chip) | ||
892 | val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x4); | ||
893 | else | ||
894 | val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x7); | ||
895 | cmu_wr(ctx, cmu_type, CMU_REG16, val); | ||
896 | |||
897 | /* Configure for SATA */ | ||
898 | cmu_rd(ctx, cmu_type, CMU_REG30, &val); | ||
899 | val = CMU_REG30_PCIE_MODE_SET(val, 0x0); | ||
900 | val = CMU_REG30_LOCK_COUNT_SET(val, 0x3); | ||
901 | cmu_wr(ctx, cmu_type, CMU_REG30, val); | ||
902 | |||
903 | /* Disable state machine bypass */ | ||
904 | cmu_wr(ctx, cmu_type, CMU_REG31, 0xF); | ||
905 | |||
906 | cmu_rd(ctx, cmu_type, CMU_REG32, &val); | ||
907 | val = CMU_REG32_PVT_CAL_WAIT_SEL_SET(val, 0x3); | ||
908 | if (cmu_type == REF_CMU || preA3Chip) | ||
909 | val = CMU_REG32_IREF_ADJ_SET(val, 0x3); | ||
910 | else | ||
911 | val = CMU_REG32_IREF_ADJ_SET(val, 0x1); | ||
912 | cmu_wr(ctx, cmu_type, CMU_REG32, val); | ||
913 | |||
914 | /* Set VCO calibration threshold */ | ||
915 | if (cmu_type != REF_CMU && preA3Chip) | ||
916 | cmu_wr(ctx, cmu_type, CMU_REG34, 0x8d27); | ||
917 | else | ||
918 | cmu_wr(ctx, cmu_type, CMU_REG34, 0x873c); | ||
919 | |||
920 | /* Set CTLE Override and override waiting from state machine */ | ||
921 | cmu_wr(ctx, cmu_type, CMU_REG37, 0xF00F); | ||
922 | } | ||
923 | |||
924 | static void xgene_phy_ssc_enable(struct xgene_phy_ctx *ctx, | ||
925 | enum cmu_type_t cmu_type) | ||
926 | { | ||
927 | u32 val; | ||
928 | |||
929 | /* Set SSC modulation value */ | ||
930 | cmu_rd(ctx, cmu_type, CMU_REG35, &val); | ||
931 | val = CMU_REG35_PLL_SSC_MOD_SET(val, 98); | ||
932 | cmu_wr(ctx, cmu_type, CMU_REG35, val); | ||
933 | |||
934 | /* Enable SSC, set vertical step and DSM value */ | ||
935 | cmu_rd(ctx, cmu_type, CMU_REG36, &val); | ||
936 | val = CMU_REG36_PLL_SSC_VSTEP_SET(val, 30); | ||
937 | val = CMU_REG36_PLL_SSC_EN_SET(val, 1); | ||
938 | val = CMU_REG36_PLL_SSC_DSMSEL_SET(val, 1); | ||
939 | cmu_wr(ctx, cmu_type, CMU_REG36, val); | ||
940 | |||
941 | /* Reset the PLL */ | ||
942 | cmu_clrbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); | ||
943 | cmu_setbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); | ||
944 | |||
945 | /* Force VCO calibration to restart */ | ||
946 | cmu_toggle1to0(ctx, cmu_type, CMU_REG32, | ||
947 | CMU_REG32_FORCE_VCOCAL_START_MASK); | ||
948 | } | ||
949 | |||
950 | static void xgene_phy_sata_cfg_lanes(struct xgene_phy_ctx *ctx) | ||
951 | { | ||
952 | u32 val; | ||
953 | u32 reg; | ||
954 | int i; | ||
955 | int lane; | ||
956 | |||
957 | for (lane = 0; lane < MAX_LANE; lane++) { | ||
958 | serdes_wr(ctx, lane, RXTX_REG147, 0x6); | ||
959 | |||
960 | /* Set boost control for quarter, half, and full rate */ | ||
961 | serdes_rd(ctx, lane, RXTX_REG0, &val); | ||
962 | val = RXTX_REG0_CTLE_EQ_HR_SET(val, 0x10); | ||
963 | val = RXTX_REG0_CTLE_EQ_QR_SET(val, 0x10); | ||
964 | val = RXTX_REG0_CTLE_EQ_FR_SET(val, 0x10); | ||
965 | serdes_wr(ctx, lane, RXTX_REG0, val); | ||
966 | |||
967 | /* Set boost control value */ | ||
968 | serdes_rd(ctx, lane, RXTX_REG1, &val); | ||
969 | val = RXTX_REG1_RXACVCM_SET(val, 0x7); | ||
970 | val = RXTX_REG1_CTLE_EQ_SET(val, | ||
971 | ctx->sata_param.txboostgain[lane * 3 + | ||
972 | ctx->sata_param.speed[lane]]); | ||
973 | serdes_wr(ctx, lane, RXTX_REG1, val); | ||
974 | |||
975 | /* Latch VTT value based on the termination to ground and | ||
976 | enable TX FIFO */ | ||
977 | serdes_rd(ctx, lane, RXTX_REG2, &val); | ||
978 | val = RXTX_REG2_VTT_ENA_SET(val, 0x1); | ||
979 | val = RXTX_REG2_VTT_SEL_SET(val, 0x1); | ||
980 | val = RXTX_REG2_TX_FIFO_ENA_SET(val, 0x1); | ||
981 | serdes_wr(ctx, lane, RXTX_REG2, val); | ||
982 | |||
983 | /* Configure Tx for 20-bits */ | ||
984 | serdes_rd(ctx, lane, RXTX_REG4, &val); | ||
985 | val = RXTX_REG4_TX_WORD_MODE_SET(val, CMU_REG9_WORD_LEN_20BIT); | ||
986 | serdes_wr(ctx, lane, RXTX_REG4, val); | ||
987 | |||
988 | if (!preA3Chip) { | ||
989 | serdes_rd(ctx, lane, RXTX_REG1, &val); | ||
990 | val = RXTX_REG1_RXVREG1_SET(val, 0x2); | ||
991 | val = RXTX_REG1_RXIREF_ADJ_SET(val, 0x2); | ||
992 | serdes_wr(ctx, lane, RXTX_REG1, val); | ||
993 | } | ||
994 | |||
995 | /* Set pre-emphasis first 1 and 2, and post-emphasis values */ | ||
996 | serdes_rd(ctx, lane, RXTX_REG5, &val); | ||
997 | val = RXTX_REG5_TX_CN1_SET(val, | ||
998 | ctx->sata_param.txprecursor_cn1[lane * 3 + | ||
999 | ctx->sata_param.speed[lane]]); | ||
1000 | val = RXTX_REG5_TX_CP1_SET(val, | ||
1001 | ctx->sata_param.txpostcursor_cp1[lane * 3 + | ||
1002 | ctx->sata_param.speed[lane]]); | ||
1003 | val = RXTX_REG5_TX_CN2_SET(val, | ||
1004 | ctx->sata_param.txprecursor_cn2[lane * 3 + | ||
1005 | ctx->sata_param.speed[lane]]); | ||
1006 | serdes_wr(ctx, lane, RXTX_REG5, val); | ||
1007 | |||
1008 | /* Set TX amplitude value */ | ||
1009 | serdes_rd(ctx, lane, RXTX_REG6, &val); | ||
1010 | val = RXTX_REG6_TXAMP_CNTL_SET(val, | ||
1011 | ctx->sata_param.txamplitude[lane * 3 + | ||
1012 | ctx->sata_param.speed[lane]]); | ||
1013 | val = RXTX_REG6_TXAMP_ENA_SET(val, 0x1); | ||
1014 | val = RXTX_REG6_TX_IDLE_SET(val, 0x0); | ||
1015 | val = RXTX_REG6_RX_BIST_RESYNC_SET(val, 0x0); | ||
1016 | val = RXTX_REG6_RX_BIST_ERRCNT_RD_SET(val, 0x0); | ||
1017 | serdes_wr(ctx, lane, RXTX_REG6, val); | ||
1018 | |||
1019 | /* Configure Rx for 20-bits */ | ||
1020 | serdes_rd(ctx, lane, RXTX_REG7, &val); | ||
1021 | val = RXTX_REG7_BIST_ENA_RX_SET(val, 0x0); | ||
1022 | val = RXTX_REG7_RX_WORD_MODE_SET(val, CMU_REG9_WORD_LEN_20BIT); | ||
1023 | serdes_wr(ctx, lane, RXTX_REG7, val); | ||
1024 | |||
1025 | /* Set CDR and LOS values and enable Rx SSC */ | ||
1026 | serdes_rd(ctx, lane, RXTX_REG8, &val); | ||
1027 | val = RXTX_REG8_CDR_LOOP_ENA_SET(val, 0x1); | ||
1028 | val = RXTX_REG8_CDR_BYPASS_RXLOS_SET(val, 0x0); | ||
1029 | val = RXTX_REG8_SSC_ENABLE_SET(val, 0x1); | ||
1030 | val = RXTX_REG8_SD_DISABLE_SET(val, 0x0); | ||
1031 | val = RXTX_REG8_SD_VREF_SET(val, 0x4); | ||
1032 | serdes_wr(ctx, lane, RXTX_REG8, val); | ||
1033 | |||
1034 | /* Set phase adjust upper/lower limits */ | ||
1035 | serdes_rd(ctx, lane, RXTX_REG11, &val); | ||
1036 | val = RXTX_REG11_PHASE_ADJUST_LIMIT_SET(val, 0x0); | ||
1037 | serdes_wr(ctx, lane, RXTX_REG11, val); | ||
1038 | |||
1039 | /* Enable Latch Off; disable SUMOS and Tx termination */ | ||
1040 | serdes_rd(ctx, lane, RXTX_REG12, &val); | ||
1041 | val = RXTX_REG12_LATCH_OFF_ENA_SET(val, 0x1); | ||
1042 | val = RXTX_REG12_SUMOS_ENABLE_SET(val, 0x0); | ||
1043 | val = RXTX_REG12_RX_DET_TERM_ENABLE_SET(val, 0x0); | ||
1044 | serdes_wr(ctx, lane, RXTX_REG12, val); | ||
1045 | |||
1046 | /* Set period error latch to 512T and enable BWL */ | ||
1047 | serdes_rd(ctx, lane, RXTX_REG26, &val); | ||
1048 | val = RXTX_REG26_PERIOD_ERROR_LATCH_SET(val, 0x0); | ||
1049 | val = RXTX_REG26_BLWC_ENA_SET(val, 0x1); | ||
1050 | serdes_wr(ctx, lane, RXTX_REG26, val); | ||
1051 | |||
1052 | serdes_wr(ctx, lane, RXTX_REG28, 0x0); | ||
1053 | |||
1054 | /* Set DFE loop preset value */ | ||
1055 | serdes_wr(ctx, lane, RXTX_REG31, 0x0); | ||
1056 | |||
1057 | /* Set Eye Monitor counter width to 12-bit */ | ||
1058 | serdes_rd(ctx, lane, RXTX_REG61, &val); | ||
1059 | val = RXTX_REG61_ISCAN_INBERT_SET(val, 0x1); | ||
1060 | val = RXTX_REG61_LOADFREQ_SHIFT_SET(val, 0x0); | ||
1061 | val = RXTX_REG61_EYE_COUNT_WIDTH_SEL_SET(val, 0x0); | ||
1062 | serdes_wr(ctx, lane, RXTX_REG61, val); | ||
1063 | |||
1064 | serdes_rd(ctx, lane, RXTX_REG62, &val); | ||
1065 | val = RXTX_REG62_PERIOD_H1_QLATCH_SET(val, 0x0); | ||
1066 | serdes_wr(ctx, lane, RXTX_REG62, val); | ||
1067 | |||
1068 | /* Set BW select tap X for DFE loop */ | ||
1069 | for (i = 0; i < 9; i++) { | ||
1070 | reg = RXTX_REG81 + i * 2; | ||
1071 | serdes_rd(ctx, lane, reg, &val); | ||
1072 | val = RXTX_REG89_MU_TH7_SET(val, 0xe); | ||
1073 | val = RXTX_REG89_MU_TH8_SET(val, 0xe); | ||
1074 | val = RXTX_REG89_MU_TH9_SET(val, 0xe); | ||
1075 | serdes_wr(ctx, lane, reg, val); | ||
1076 | } | ||
1077 | |||
1078 | /* Set BW select tap X for frequency adjust loop */ | ||
1079 | for (i = 0; i < 3; i++) { | ||
1080 | reg = RXTX_REG96 + i * 2; | ||
1081 | serdes_rd(ctx, lane, reg, &val); | ||
1082 | val = RXTX_REG96_MU_FREQ1_SET(val, 0x10); | ||
1083 | val = RXTX_REG96_MU_FREQ2_SET(val, 0x10); | ||
1084 | val = RXTX_REG96_MU_FREQ3_SET(val, 0x10); | ||
1085 | serdes_wr(ctx, lane, reg, val); | ||
1086 | } | ||
1087 | |||
1088 | /* Set BW select tap X for phase adjust loop */ | ||
1089 | for (i = 0; i < 3; i++) { | ||
1090 | reg = RXTX_REG99 + i * 2; | ||
1091 | serdes_rd(ctx, lane, reg, &val); | ||
1092 | val = RXTX_REG99_MU_PHASE1_SET(val, 0x7); | ||
1093 | val = RXTX_REG99_MU_PHASE2_SET(val, 0x7); | ||
1094 | val = RXTX_REG99_MU_PHASE3_SET(val, 0x7); | ||
1095 | serdes_wr(ctx, lane, reg, val); | ||
1096 | } | ||
1097 | |||
1098 | serdes_rd(ctx, lane, RXTX_REG102, &val); | ||
1099 | val = RXTX_REG102_FREQLOOP_LIMIT_SET(val, 0x0); | ||
1100 | serdes_wr(ctx, lane, RXTX_REG102, val); | ||
1101 | |||
1102 | serdes_wr(ctx, lane, RXTX_REG114, 0xffe0); | ||
1103 | |||
1104 | serdes_rd(ctx, lane, RXTX_REG125, &val); | ||
1105 | val = RXTX_REG125_SIGN_PQ_SET(val, | ||
1106 | ctx->sata_param.txeyedirection[lane * 3 + | ||
1107 | ctx->sata_param.speed[lane]]); | ||
1108 | val = RXTX_REG125_PQ_REG_SET(val, | ||
1109 | ctx->sata_param.txeyetuning[lane * 3 + | ||
1110 | ctx->sata_param.speed[lane]]); | ||
1111 | val = RXTX_REG125_PHZ_MANUAL_SET(val, 0x1); | ||
1112 | serdes_wr(ctx, lane, RXTX_REG125, val); | ||
1113 | |||
1114 | serdes_rd(ctx, lane, RXTX_REG127, &val); | ||
1115 | val = RXTX_REG127_LATCH_MAN_CAL_ENA_SET(val, 0x0); | ||
1116 | serdes_wr(ctx, lane, RXTX_REG127, val); | ||
1117 | |||
1118 | serdes_rd(ctx, lane, RXTX_REG128, &val); | ||
1119 | val = RXTX_REG128_LATCH_CAL_WAIT_SEL_SET(val, 0x3); | ||
1120 | serdes_wr(ctx, lane, RXTX_REG128, val); | ||
1121 | |||
1122 | serdes_rd(ctx, lane, RXTX_REG145, &val); | ||
1123 | val = RXTX_REG145_RXDFE_CONFIG_SET(val, 0x3); | ||
1124 | val = RXTX_REG145_TX_IDLE_SATA_SET(val, 0x0); | ||
1125 | if (preA3Chip) { | ||
1126 | val = RXTX_REG145_RXES_ENA_SET(val, 0x1); | ||
1127 | val = RXTX_REG145_RXVWES_LATENA_SET(val, 0x1); | ||
1128 | } else { | ||
1129 | val = RXTX_REG145_RXES_ENA_SET(val, 0x0); | ||
1130 | val = RXTX_REG145_RXVWES_LATENA_SET(val, 0x0); | ||
1131 | } | ||
1132 | serdes_wr(ctx, lane, RXTX_REG145, val); | ||
1133 | |||
1134 | /* | ||
1135 | * Set Rx LOS filter clock rate, sample rate, and threshold | ||
1136 | * windows | ||
1137 | */ | ||
1138 | for (i = 0; i < 4; i++) { | ||
1139 | reg = RXTX_REG148 + i * 2; | ||
1140 | serdes_wr(ctx, lane, reg, 0xFFFF); | ||
1141 | } | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | static int xgene_phy_cal_rdy_chk(struct xgene_phy_ctx *ctx, | ||
1146 | enum cmu_type_t cmu_type, | ||
1147 | enum clk_type_t clk_type) | ||
1148 | { | ||
1149 | void __iomem *csr_serdes = ctx->sds_base; | ||
1150 | int loop; | ||
1151 | u32 val; | ||
1152 | |||
1153 | /* Release PHY main reset */ | ||
1154 | writel(0xdf, csr_serdes + SATA_ENET_SDS_RST_CTL); | ||
1155 | readl(csr_serdes + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ | ||
1156 | |||
1157 | if (cmu_type != REF_CMU) { | ||
1158 | cmu_setbits(ctx, cmu_type, CMU_REG5, CMU_REG5_PLL_RESETB_MASK); | ||
1159 | /* | ||
1160 | * As per PHY design spec, the PLL reset requires a minimum | ||
1161 | * of 800us. | ||
1162 | */ | ||
1163 | usleep_range(800, 1000); | ||
1164 | |||
1165 | cmu_rd(ctx, cmu_type, CMU_REG1, &val); | ||
1166 | val = CMU_REG1_PLL_MANUALCAL_SET(val, 0x0); | ||
1167 | cmu_wr(ctx, cmu_type, CMU_REG1, val); | ||
1168 | /* | ||
1169 | * As per PHY design spec, the PLL auto calibration requires | ||
1170 | * a minimum of 800us. | ||
1171 | */ | ||
1172 | usleep_range(800, 1000); | ||
1173 | |||
1174 | cmu_toggle1to0(ctx, cmu_type, CMU_REG32, | ||
1175 | CMU_REG32_FORCE_VCOCAL_START_MASK); | ||
1176 | /* | ||
1177 | * As per PHY design spec, the PLL requires a minimum of | ||
1178 | * 800us to settle. | ||
1179 | */ | ||
1180 | usleep_range(800, 1000); | ||
1181 | } | ||
1182 | |||
1183 | if (!preA3Chip) | ||
1184 | goto skip_manual_cal; | ||
1185 | |||
1186 | /* | ||
1187 | * Configure the termination resister calibration | ||
1188 | * The serial receive pins, RXP/RXN, have TERMination resistor | ||
1189 | * that is required to be calibrated. | ||
1190 | */ | ||
1191 | cmu_rd(ctx, cmu_type, CMU_REG17, &val); | ||
1192 | val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x12); | ||
1193 | val = CMU_REG17_RESERVED_7_SET(val, 0x0); | ||
1194 | cmu_wr(ctx, cmu_type, CMU_REG17, val); | ||
1195 | cmu_toggle1to0(ctx, cmu_type, CMU_REG17, | ||
1196 | CMU_REG17_PVT_TERM_MAN_ENA_MASK); | ||
1197 | /* | ||
1198 | * The serial transmit pins, TXP/TXN, have Pull-UP and Pull-DOWN | ||
1199 | * resistors that are required to the calibrated. | ||
1200 | * Configure the pull DOWN calibration | ||
1201 | */ | ||
1202 | cmu_rd(ctx, cmu_type, CMU_REG17, &val); | ||
1203 | val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x29); | ||
1204 | val = CMU_REG17_RESERVED_7_SET(val, 0x0); | ||
1205 | cmu_wr(ctx, cmu_type, CMU_REG17, val); | ||
1206 | cmu_toggle1to0(ctx, cmu_type, CMU_REG16, | ||
1207 | CMU_REG16_PVT_DN_MAN_ENA_MASK); | ||
1208 | /* Configure the pull UP calibration */ | ||
1209 | cmu_rd(ctx, cmu_type, CMU_REG17, &val); | ||
1210 | val = CMU_REG17_PVT_CODE_R2A_SET(val, 0x28); | ||
1211 | val = CMU_REG17_RESERVED_7_SET(val, 0x0); | ||
1212 | cmu_wr(ctx, cmu_type, CMU_REG17, val); | ||
1213 | cmu_toggle1to0(ctx, cmu_type, CMU_REG16, | ||
1214 | CMU_REG16_PVT_UP_MAN_ENA_MASK); | ||
1215 | |||
1216 | skip_manual_cal: | ||
1217 | /* Poll the PLL calibration completion status for at least 1 ms */ | ||
1218 | loop = 100; | ||
1219 | do { | ||
1220 | cmu_rd(ctx, cmu_type, CMU_REG7, &val); | ||
1221 | if (CMU_REG7_PLL_CALIB_DONE_RD(val)) | ||
1222 | break; | ||
1223 | /* | ||
1224 | * As per PHY design spec, PLL calibration status requires | ||
1225 | * a minimum of 10us to be updated. | ||
1226 | */ | ||
1227 | usleep_range(10, 100); | ||
1228 | } while (--loop > 0); | ||
1229 | |||
1230 | cmu_rd(ctx, cmu_type, CMU_REG7, &val); | ||
1231 | dev_dbg(ctx->dev, "PLL calibration %s\n", | ||
1232 | CMU_REG7_PLL_CALIB_DONE_RD(val) ? "done" : "failed"); | ||
1233 | if (CMU_REG7_VCO_CAL_FAIL_RD(val)) { | ||
1234 | dev_err(ctx->dev, | ||
1235 | "PLL calibration failed due to VCO failure\n"); | ||
1236 | return -1; | ||
1237 | } | ||
1238 | dev_dbg(ctx->dev, "PLL calibration successful\n"); | ||
1239 | |||
1240 | cmu_rd(ctx, cmu_type, CMU_REG15, &val); | ||
1241 | dev_dbg(ctx->dev, "PHY Tx is %sready\n", val & 0x300 ? "" : "not "); | ||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | static void xgene_phy_pdwn_force_vco(struct xgene_phy_ctx *ctx, | ||
1246 | enum cmu_type_t cmu_type, | ||
1247 | enum clk_type_t clk_type) | ||
1248 | { | ||
1249 | u32 val; | ||
1250 | |||
1251 | dev_dbg(ctx->dev, "Reset VCO and re-start again\n"); | ||
1252 | if (cmu_type == PHY_CMU) { | ||
1253 | cmu_rd(ctx, cmu_type, CMU_REG16, &val); | ||
1254 | val = CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(val, 0x7); | ||
1255 | cmu_wr(ctx, cmu_type, CMU_REG16, val); | ||
1256 | } | ||
1257 | |||
1258 | cmu_toggle1to0(ctx, cmu_type, CMU_REG0, CMU_REG0_PDOWN_MASK); | ||
1259 | cmu_toggle1to0(ctx, cmu_type, CMU_REG32, | ||
1260 | CMU_REG32_FORCE_VCOCAL_START_MASK); | ||
1261 | } | ||
1262 | |||
1263 | static int xgene_phy_hw_init_sata(struct xgene_phy_ctx *ctx, | ||
1264 | enum clk_type_t clk_type, int ssc_enable) | ||
1265 | { | ||
1266 | void __iomem *sds_base = ctx->sds_base; | ||
1267 | u32 val; | ||
1268 | int i; | ||
1269 | |||
1270 | /* Configure the PHY for operation */ | ||
1271 | dev_dbg(ctx->dev, "Reset PHY\n"); | ||
1272 | /* Place PHY into reset */ | ||
1273 | writel(0x0, sds_base + SATA_ENET_SDS_RST_CTL); | ||
1274 | val = readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ | ||
1275 | /* Release PHY lane from reset (active high) */ | ||
1276 | writel(0x20, sds_base + SATA_ENET_SDS_RST_CTL); | ||
1277 | readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ | ||
1278 | /* Release all PHY module out of reset except PHY main reset */ | ||
1279 | writel(0xde, sds_base + SATA_ENET_SDS_RST_CTL); | ||
1280 | readl(sds_base + SATA_ENET_SDS_RST_CTL); /* Force a barrier */ | ||
1281 | |||
1282 | /* Set the operation speed */ | ||
1283 | val = readl(sds_base + SATA_ENET_SDS_CTL1); | ||
1284 | val = CFG_I_SPD_SEL_CDR_OVR1_SET(val, | ||
1285 | ctx->sata_param.txspeed[ctx->sata_param.speed[0]]); | ||
1286 | writel(val, sds_base + SATA_ENET_SDS_CTL1); | ||
1287 | |||
1288 | dev_dbg(ctx->dev, "Set the customer pin mode to SATA\n"); | ||
1289 | val = readl(sds_base + SATA_ENET_SDS_CTL0); | ||
1290 | val = REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(val, 0x4421); | ||
1291 | writel(val, sds_base + SATA_ENET_SDS_CTL0); | ||
1292 | |||
1293 | /* Configure the clock macro unit (CMU) clock type */ | ||
1294 | xgene_phy_cfg_cmu_clk_type(ctx, PHY_CMU, clk_type); | ||
1295 | |||
1296 | /* Configure the clock macro */ | ||
1297 | xgene_phy_sata_cfg_cmu_core(ctx, PHY_CMU, clk_type); | ||
1298 | |||
1299 | /* Enable SSC if enabled */ | ||
1300 | if (ssc_enable) | ||
1301 | xgene_phy_ssc_enable(ctx, PHY_CMU); | ||
1302 | |||
1303 | /* Configure PHY lanes */ | ||
1304 | xgene_phy_sata_cfg_lanes(ctx); | ||
1305 | |||
1306 | /* Set Rx/Tx 20-bit */ | ||
1307 | val = readl(sds_base + SATA_ENET_SDS_PCS_CTL0); | ||
1308 | val = REGSPEC_CFG_I_RX_WORDMODE0_SET(val, 0x3); | ||
1309 | val = REGSPEC_CFG_I_TX_WORDMODE0_SET(val, 0x3); | ||
1310 | writel(val, sds_base + SATA_ENET_SDS_PCS_CTL0); | ||
1311 | |||
1312 | /* Start PLL calibration and try for three times */ | ||
1313 | i = 10; | ||
1314 | do { | ||
1315 | if (!xgene_phy_cal_rdy_chk(ctx, PHY_CMU, clk_type)) | ||
1316 | break; | ||
1317 | /* If failed, toggle the VCO power signal and start again */ | ||
1318 | xgene_phy_pdwn_force_vco(ctx, PHY_CMU, clk_type); | ||
1319 | } while (--i > 0); | ||
1320 | /* Even on failure, allow to continue any way */ | ||
1321 | if (i <= 0) | ||
1322 | dev_err(ctx->dev, "PLL calibration failed\n"); | ||
1323 | |||
1324 | return 0; | ||
1325 | } | ||
1326 | |||
1327 | static int xgene_phy_hw_initialize(struct xgene_phy_ctx *ctx, | ||
1328 | enum clk_type_t clk_type, | ||
1329 | int ssc_enable) | ||
1330 | { | ||
1331 | int rc; | ||
1332 | |||
1333 | dev_dbg(ctx->dev, "PHY init clk type %d\n", clk_type); | ||
1334 | |||
1335 | if (ctx->mode == MODE_SATA) { | ||
1336 | rc = xgene_phy_hw_init_sata(ctx, clk_type, ssc_enable); | ||
1337 | if (rc) | ||
1338 | return rc; | ||
1339 | } else { | ||
1340 | dev_err(ctx->dev, "Un-supported customer pin mode %d\n", | ||
1341 | ctx->mode); | ||
1342 | return -ENODEV; | ||
1343 | } | ||
1344 | |||
1345 | return 0; | ||
1346 | } | ||
1347 | |||
1348 | /* | ||
1349 | * Receiver Offset Calibration: | ||
1350 | * | ||
1351 | * Calibrate the receiver signal path offset in two steps - summar and | ||
1352 | * latch calibrations | ||
1353 | */ | ||
1354 | static void xgene_phy_force_lat_summer_cal(struct xgene_phy_ctx *ctx, int lane) | ||
1355 | { | ||
1356 | int i; | ||
1357 | struct { | ||
1358 | u32 reg; | ||
1359 | u32 val; | ||
1360 | } serdes_reg[] = { | ||
1361 | {RXTX_REG38, 0x0}, | ||
1362 | {RXTX_REG39, 0xff00}, | ||
1363 | {RXTX_REG40, 0xffff}, | ||
1364 | {RXTX_REG41, 0xffff}, | ||
1365 | {RXTX_REG42, 0xffff}, | ||
1366 | {RXTX_REG43, 0xffff}, | ||
1367 | {RXTX_REG44, 0xffff}, | ||
1368 | {RXTX_REG45, 0xffff}, | ||
1369 | {RXTX_REG46, 0xffff}, | ||
1370 | {RXTX_REG47, 0xfffc}, | ||
1371 | {RXTX_REG48, 0x0}, | ||
1372 | {RXTX_REG49, 0x0}, | ||
1373 | {RXTX_REG50, 0x0}, | ||
1374 | {RXTX_REG51, 0x0}, | ||
1375 | {RXTX_REG52, 0x0}, | ||
1376 | {RXTX_REG53, 0x0}, | ||
1377 | {RXTX_REG54, 0x0}, | ||
1378 | {RXTX_REG55, 0x0}, | ||
1379 | }; | ||
1380 | |||
1381 | /* Start SUMMER calibration */ | ||
1382 | serdes_setbits(ctx, lane, RXTX_REG127, | ||
1383 | RXTX_REG127_FORCE_SUM_CAL_START_MASK); | ||
1384 | /* | ||
1385 | * As per PHY design spec, the Summer calibration requires a minimum | ||
1386 | * of 100us to complete. | ||
1387 | */ | ||
1388 | usleep_range(100, 500); | ||
1389 | serdes_clrbits(ctx, lane, RXTX_REG127, | ||
1390 | RXTX_REG127_FORCE_SUM_CAL_START_MASK); | ||
1391 | /* | ||
1392 | * As per PHY design spec, the auto calibration requires a minimum | ||
1393 | * of 100us to complete. | ||
1394 | */ | ||
1395 | usleep_range(100, 500); | ||
1396 | |||
1397 | /* Start latch calibration */ | ||
1398 | serdes_setbits(ctx, lane, RXTX_REG127, | ||
1399 | RXTX_REG127_FORCE_LAT_CAL_START_MASK); | ||
1400 | /* | ||
1401 | * As per PHY design spec, the latch calibration requires a minimum | ||
1402 | * of 100us to complete. | ||
1403 | */ | ||
1404 | usleep_range(100, 500); | ||
1405 | serdes_clrbits(ctx, lane, RXTX_REG127, | ||
1406 | RXTX_REG127_FORCE_LAT_CAL_START_MASK); | ||
1407 | |||
1408 | /* Configure the PHY lane for calibration */ | ||
1409 | serdes_wr(ctx, lane, RXTX_REG28, 0x7); | ||
1410 | serdes_wr(ctx, lane, RXTX_REG31, 0x7e00); | ||
1411 | serdes_clrbits(ctx, lane, RXTX_REG4, | ||
1412 | RXTX_REG4_TX_LOOPBACK_BUF_EN_MASK); | ||
1413 | serdes_clrbits(ctx, lane, RXTX_REG7, | ||
1414 | RXTX_REG7_LOOP_BACK_ENA_CTLE_MASK); | ||
1415 | for (i = 0; i < ARRAY_SIZE(serdes_reg); i++) | ||
1416 | serdes_wr(ctx, lane, serdes_reg[i].reg, | ||
1417 | serdes_reg[i].val); | ||
1418 | } | ||
1419 | |||
1420 | static void xgene_phy_reset_rxd(struct xgene_phy_ctx *ctx, int lane) | ||
1421 | { | ||
1422 | /* Reset digital Rx */ | ||
1423 | serdes_clrbits(ctx, lane, RXTX_REG7, RXTX_REG7_RESETB_RXD_MASK); | ||
1424 | /* As per PHY design spec, the reset requires a minimum of 100us. */ | ||
1425 | usleep_range(100, 150); | ||
1426 | serdes_setbits(ctx, lane, RXTX_REG7, RXTX_REG7_RESETB_RXD_MASK); | ||
1427 | } | ||
1428 | |||
1429 | static int xgene_phy_get_avg(int accum, int samples) | ||
1430 | { | ||
1431 | return (accum + (samples / 2)) / samples; | ||
1432 | } | ||
1433 | |||
1434 | static void xgene_phy_gen_avg_val(struct xgene_phy_ctx *ctx, int lane) | ||
1435 | { | ||
1436 | int max_loop = 10; | ||
1437 | int avg_loop = 0; | ||
1438 | int lat_do = 0, lat_xo = 0, lat_eo = 0, lat_so = 0; | ||
1439 | int lat_de = 0, lat_xe = 0, lat_ee = 0, lat_se = 0; | ||
1440 | int sum_cal = 0; | ||
1441 | int lat_do_itr, lat_xo_itr, lat_eo_itr, lat_so_itr; | ||
1442 | int lat_de_itr, lat_xe_itr, lat_ee_itr, lat_se_itr; | ||
1443 | int sum_cal_itr; | ||
1444 | int fail_even; | ||
1445 | int fail_odd; | ||
1446 | u32 val; | ||
1447 | |||
1448 | dev_dbg(ctx->dev, "Generating avg calibration value for lane %d\n", | ||
1449 | lane); | ||
1450 | |||
1451 | /* Enable RX Hi-Z termination */ | ||
1452 | serdes_setbits(ctx, lane, RXTX_REG12, | ||
1453 | RXTX_REG12_RX_DET_TERM_ENABLE_MASK); | ||
1454 | /* Turn off DFE */ | ||
1455 | serdes_wr(ctx, lane, RXTX_REG28, 0x0000); | ||
1456 | /* DFE Presets to zero */ | ||
1457 | serdes_wr(ctx, lane, RXTX_REG31, 0x0000); | ||
1458 | |||
1459 | /* | ||
1460 | * Receiver Offset Calibration: | ||
1461 | * Calibrate the receiver signal path offset in two steps - summar | ||
1462 | * and latch calibration. | ||
1463 | * Runs the "Receiver Offset Calibration multiple times to determine | ||
1464 | * the average value to use. | ||
1465 | */ | ||
1466 | while (avg_loop < max_loop) { | ||
1467 | /* Start the calibration */ | ||
1468 | xgene_phy_force_lat_summer_cal(ctx, lane); | ||
1469 | |||
1470 | serdes_rd(ctx, lane, RXTX_REG21, &val); | ||
1471 | lat_do_itr = RXTX_REG21_DO_LATCH_CALOUT_RD(val); | ||
1472 | lat_xo_itr = RXTX_REG21_XO_LATCH_CALOUT_RD(val); | ||
1473 | fail_odd = RXTX_REG21_LATCH_CAL_FAIL_ODD_RD(val); | ||
1474 | |||
1475 | serdes_rd(ctx, lane, RXTX_REG22, &val); | ||
1476 | lat_eo_itr = RXTX_REG22_EO_LATCH_CALOUT_RD(val); | ||
1477 | lat_so_itr = RXTX_REG22_SO_LATCH_CALOUT_RD(val); | ||
1478 | fail_even = RXTX_REG22_LATCH_CAL_FAIL_EVEN_RD(val); | ||
1479 | |||
1480 | serdes_rd(ctx, lane, RXTX_REG23, &val); | ||
1481 | lat_de_itr = RXTX_REG23_DE_LATCH_CALOUT_RD(val); | ||
1482 | lat_xe_itr = RXTX_REG23_XE_LATCH_CALOUT_RD(val); | ||
1483 | |||
1484 | serdes_rd(ctx, lane, RXTX_REG24, &val); | ||
1485 | lat_ee_itr = RXTX_REG24_EE_LATCH_CALOUT_RD(val); | ||
1486 | lat_se_itr = RXTX_REG24_SE_LATCH_CALOUT_RD(val); | ||
1487 | |||
1488 | serdes_rd(ctx, lane, RXTX_REG121, &val); | ||
1489 | sum_cal_itr = RXTX_REG121_SUMOS_CAL_CODE_RD(val); | ||
1490 | |||
1491 | /* Check for failure. If passed, sum them for averaging */ | ||
1492 | if ((fail_even == 0 || fail_even == 1) && | ||
1493 | (fail_odd == 0 || fail_odd == 1)) { | ||
1494 | lat_do += lat_do_itr; | ||
1495 | lat_xo += lat_xo_itr; | ||
1496 | lat_eo += lat_eo_itr; | ||
1497 | lat_so += lat_so_itr; | ||
1498 | lat_de += lat_de_itr; | ||
1499 | lat_xe += lat_xe_itr; | ||
1500 | lat_ee += lat_ee_itr; | ||
1501 | lat_se += lat_se_itr; | ||
1502 | sum_cal += sum_cal_itr; | ||
1503 | |||
1504 | dev_dbg(ctx->dev, "Iteration %d:\n", avg_loop); | ||
1505 | dev_dbg(ctx->dev, "DO 0x%x XO 0x%x EO 0x%x SO 0x%x\n", | ||
1506 | lat_do_itr, lat_xo_itr, lat_eo_itr, | ||
1507 | lat_so_itr); | ||
1508 | dev_dbg(ctx->dev, "DE 0x%x XE 0x%x EE 0x%x SE 0x%x\n", | ||
1509 | lat_de_itr, lat_xe_itr, lat_ee_itr, | ||
1510 | lat_se_itr); | ||
1511 | dev_dbg(ctx->dev, "SUM 0x%x\n", sum_cal_itr); | ||
1512 | ++avg_loop; | ||
1513 | } else { | ||
1514 | dev_err(ctx->dev, | ||
1515 | "Receiver calibration failed at %d loop\n", | ||
1516 | avg_loop); | ||
1517 | } | ||
1518 | xgene_phy_reset_rxd(ctx, lane); | ||
1519 | } | ||
1520 | |||
1521 | /* Update latch manual calibration with average value */ | ||
1522 | serdes_rd(ctx, lane, RXTX_REG127, &val); | ||
1523 | val = RXTX_REG127_DO_LATCH_MANCAL_SET(val, | ||
1524 | xgene_phy_get_avg(lat_do, max_loop)); | ||
1525 | val = RXTX_REG127_XO_LATCH_MANCAL_SET(val, | ||
1526 | xgene_phy_get_avg(lat_xo, max_loop)); | ||
1527 | serdes_wr(ctx, lane, RXTX_REG127, val); | ||
1528 | |||
1529 | serdes_rd(ctx, lane, RXTX_REG128, &val); | ||
1530 | val = RXTX_REG128_EO_LATCH_MANCAL_SET(val, | ||
1531 | xgene_phy_get_avg(lat_eo, max_loop)); | ||
1532 | val = RXTX_REG128_SO_LATCH_MANCAL_SET(val, | ||
1533 | xgene_phy_get_avg(lat_so, max_loop)); | ||
1534 | serdes_wr(ctx, lane, RXTX_REG128, val); | ||
1535 | |||
1536 | serdes_rd(ctx, lane, RXTX_REG129, &val); | ||
1537 | val = RXTX_REG129_DE_LATCH_MANCAL_SET(val, | ||
1538 | xgene_phy_get_avg(lat_de, max_loop)); | ||
1539 | val = RXTX_REG129_XE_LATCH_MANCAL_SET(val, | ||
1540 | xgene_phy_get_avg(lat_xe, max_loop)); | ||
1541 | serdes_wr(ctx, lane, RXTX_REG129, val); | ||
1542 | |||
1543 | serdes_rd(ctx, lane, RXTX_REG130, &val); | ||
1544 | val = RXTX_REG130_EE_LATCH_MANCAL_SET(val, | ||
1545 | xgene_phy_get_avg(lat_ee, max_loop)); | ||
1546 | val = RXTX_REG130_SE_LATCH_MANCAL_SET(val, | ||
1547 | xgene_phy_get_avg(lat_se, max_loop)); | ||
1548 | serdes_wr(ctx, lane, RXTX_REG130, val); | ||
1549 | |||
1550 | /* Update SUMMER calibration with average value */ | ||
1551 | serdes_rd(ctx, lane, RXTX_REG14, &val); | ||
1552 | val = RXTX_REG14_CLTE_LATCAL_MAN_PROG_SET(val, | ||
1553 | xgene_phy_get_avg(sum_cal, max_loop)); | ||
1554 | serdes_wr(ctx, lane, RXTX_REG14, val); | ||
1555 | |||
1556 | dev_dbg(ctx->dev, "Average Value:\n"); | ||
1557 | dev_dbg(ctx->dev, "DO 0x%x XO 0x%x EO 0x%x SO 0x%x\n", | ||
1558 | xgene_phy_get_avg(lat_do, max_loop), | ||
1559 | xgene_phy_get_avg(lat_xo, max_loop), | ||
1560 | xgene_phy_get_avg(lat_eo, max_loop), | ||
1561 | xgene_phy_get_avg(lat_so, max_loop)); | ||
1562 | dev_dbg(ctx->dev, "DE 0x%x XE 0x%x EE 0x%x SE 0x%x\n", | ||
1563 | xgene_phy_get_avg(lat_de, max_loop), | ||
1564 | xgene_phy_get_avg(lat_xe, max_loop), | ||
1565 | xgene_phy_get_avg(lat_ee, max_loop), | ||
1566 | xgene_phy_get_avg(lat_se, max_loop)); | ||
1567 | dev_dbg(ctx->dev, "SUM 0x%x\n", | ||
1568 | xgene_phy_get_avg(sum_cal, max_loop)); | ||
1569 | |||
1570 | serdes_rd(ctx, lane, RXTX_REG14, &val); | ||
1571 | val = RXTX_REG14_CTLE_LATCAL_MAN_ENA_SET(val, 0x1); | ||
1572 | serdes_wr(ctx, lane, RXTX_REG14, val); | ||
1573 | dev_dbg(ctx->dev, "Enable Manual Summer calibration\n"); | ||
1574 | |||
1575 | serdes_rd(ctx, lane, RXTX_REG127, &val); | ||
1576 | val = RXTX_REG127_LATCH_MAN_CAL_ENA_SET(val, 0x1); | ||
1577 | dev_dbg(ctx->dev, "Enable Manual Latch calibration\n"); | ||
1578 | serdes_wr(ctx, lane, RXTX_REG127, val); | ||
1579 | |||
1580 | /* Disable RX Hi-Z termination */ | ||
1581 | serdes_rd(ctx, lane, RXTX_REG12, &val); | ||
1582 | val = RXTX_REG12_RX_DET_TERM_ENABLE_SET(val, 0); | ||
1583 | serdes_wr(ctx, lane, RXTX_REG12, val); | ||
1584 | /* Turn on DFE */ | ||
1585 | serdes_wr(ctx, lane, RXTX_REG28, 0x0007); | ||
1586 | /* Set DFE preset */ | ||
1587 | serdes_wr(ctx, lane, RXTX_REG31, 0x7e00); | ||
1588 | } | ||
1589 | |||
1590 | static int xgene_phy_hw_init(struct phy *phy) | ||
1591 | { | ||
1592 | struct xgene_phy_ctx *ctx = phy_get_drvdata(phy); | ||
1593 | int rc; | ||
1594 | int i; | ||
1595 | |||
1596 | rc = xgene_phy_hw_initialize(ctx, CLK_EXT_DIFF, SSC_DISABLE); | ||
1597 | if (rc) { | ||
1598 | dev_err(ctx->dev, "PHY initialize failed %d\n", rc); | ||
1599 | return rc; | ||
1600 | } | ||
1601 | |||
1602 | /* Setup clock properly after PHY configuration */ | ||
1603 | if (!IS_ERR(ctx->clk)) { | ||
1604 | /* HW requires an toggle of the clock */ | ||
1605 | clk_prepare_enable(ctx->clk); | ||
1606 | clk_disable_unprepare(ctx->clk); | ||
1607 | clk_prepare_enable(ctx->clk); | ||
1608 | } | ||
1609 | |||
1610 | /* Compute average value */ | ||
1611 | for (i = 0; i < MAX_LANE; i++) | ||
1612 | xgene_phy_gen_avg_val(ctx, i); | ||
1613 | |||
1614 | dev_dbg(ctx->dev, "PHY initialized\n"); | ||
1615 | return 0; | ||
1616 | } | ||
1617 | |||
1618 | static const struct phy_ops xgene_phy_ops = { | ||
1619 | .init = xgene_phy_hw_init, | ||
1620 | .owner = THIS_MODULE, | ||
1621 | }; | ||
1622 | |||
1623 | static struct phy *xgene_phy_xlate(struct device *dev, | ||
1624 | struct of_phandle_args *args) | ||
1625 | { | ||
1626 | struct xgene_phy_ctx *ctx = dev_get_drvdata(dev); | ||
1627 | |||
1628 | if (args->args_count <= 0) | ||
1629 | return ERR_PTR(-EINVAL); | ||
1630 | if (args->args[0] < MODE_SATA || args->args[0] >= MODE_MAX) | ||
1631 | return ERR_PTR(-EINVAL); | ||
1632 | |||
1633 | ctx->mode = args->args[0]; | ||
1634 | return ctx->phy; | ||
1635 | } | ||
1636 | |||
1637 | static void xgene_phy_get_param(struct platform_device *pdev, | ||
1638 | const char *name, u32 *buffer, | ||
1639 | int count, u32 *default_val, | ||
1640 | u32 conv_factor) | ||
1641 | { | ||
1642 | int i; | ||
1643 | |||
1644 | if (!of_property_read_u32_array(pdev->dev.of_node, name, buffer, | ||
1645 | count)) { | ||
1646 | for (i = 0; i < count; i++) | ||
1647 | buffer[i] /= conv_factor; | ||
1648 | return; | ||
1649 | } | ||
1650 | /* Does not exist, load default */ | ||
1651 | for (i = 0; i < count; i++) | ||
1652 | buffer[i] = default_val[i % 3]; | ||
1653 | } | ||
1654 | |||
1655 | static int xgene_phy_probe(struct platform_device *pdev) | ||
1656 | { | ||
1657 | struct phy_provider *phy_provider; | ||
1658 | struct xgene_phy_ctx *ctx; | ||
1659 | struct resource *res; | ||
1660 | int rc = 0; | ||
1661 | u32 default_spd[] = DEFAULT_SATA_SPD_SEL; | ||
1662 | u32 default_txboost_gain[] = DEFAULT_SATA_TXBOOST_GAIN; | ||
1663 | u32 default_txeye_direction[] = DEFAULT_SATA_TXEYEDIRECTION; | ||
1664 | u32 default_txeye_tuning[] = DEFAULT_SATA_TXEYETUNING; | ||
1665 | u32 default_txamp[] = DEFAULT_SATA_TXAMP; | ||
1666 | u32 default_txcn1[] = DEFAULT_SATA_TXCN1; | ||
1667 | u32 default_txcn2[] = DEFAULT_SATA_TXCN2; | ||
1668 | u32 default_txcp1[] = DEFAULT_SATA_TXCP1; | ||
1669 | int i; | ||
1670 | |||
1671 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); | ||
1672 | if (!ctx) | ||
1673 | return -ENOMEM; | ||
1674 | |||
1675 | ctx->dev = &pdev->dev; | ||
1676 | |||
1677 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1678 | ctx->sds_base = devm_ioremap_resource(&pdev->dev, res); | ||
1679 | if (IS_ERR(ctx->sds_base)) { | ||
1680 | rc = PTR_ERR(ctx->sds_base); | ||
1681 | goto error; | ||
1682 | } | ||
1683 | |||
1684 | /* Retrieve optional clock */ | ||
1685 | ctx->clk = clk_get(&pdev->dev, NULL); | ||
1686 | |||
1687 | /* Load override paramaters */ | ||
1688 | xgene_phy_get_param(pdev, "apm,tx-eye-tuning", | ||
1689 | ctx->sata_param.txeyetuning, 6, default_txeye_tuning, 1); | ||
1690 | xgene_phy_get_param(pdev, "apm,tx-eye-direction", | ||
1691 | ctx->sata_param.txeyedirection, 6, default_txeye_direction, 1); | ||
1692 | xgene_phy_get_param(pdev, "apm,tx-boost-gain", | ||
1693 | ctx->sata_param.txboostgain, 6, default_txboost_gain, 1); | ||
1694 | xgene_phy_get_param(pdev, "apm,tx-amplitude", | ||
1695 | ctx->sata_param.txamplitude, 6, default_txamp, 13300); | ||
1696 | xgene_phy_get_param(pdev, "apm,tx-pre-cursor1", | ||
1697 | ctx->sata_param.txprecursor_cn1, 6, default_txcn1, 18200); | ||
1698 | xgene_phy_get_param(pdev, "apm,tx-pre-cursor2", | ||
1699 | ctx->sata_param.txprecursor_cn2, 6, default_txcn2, 18200); | ||
1700 | xgene_phy_get_param(pdev, "apm,tx-post-cursor", | ||
1701 | ctx->sata_param.txpostcursor_cp1, 6, default_txcp1, 18200); | ||
1702 | xgene_phy_get_param(pdev, "apm,tx-speed", | ||
1703 | ctx->sata_param.txspeed, 3, default_spd, 1); | ||
1704 | for (i = 0; i < MAX_LANE; i++) | ||
1705 | ctx->sata_param.speed[i] = 2; /* Default to Gen3 */ | ||
1706 | |||
1707 | ctx->dev = &pdev->dev; | ||
1708 | platform_set_drvdata(pdev, ctx); | ||
1709 | |||
1710 | ctx->phy = devm_phy_create(ctx->dev, &xgene_phy_ops, NULL); | ||
1711 | if (IS_ERR(ctx->phy)) { | ||
1712 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); | ||
1713 | rc = PTR_ERR(ctx->phy); | ||
1714 | goto error; | ||
1715 | } | ||
1716 | phy_set_drvdata(ctx->phy, ctx); | ||
1717 | |||
1718 | phy_provider = devm_of_phy_provider_register(ctx->dev, | ||
1719 | xgene_phy_xlate); | ||
1720 | if (IS_ERR(phy_provider)) { | ||
1721 | rc = PTR_ERR(phy_provider); | ||
1722 | goto error; | ||
1723 | } | ||
1724 | |||
1725 | return 0; | ||
1726 | |||
1727 | error: | ||
1728 | return rc; | ||
1729 | } | ||
1730 | |||
1731 | static const struct of_device_id xgene_phy_of_match[] = { | ||
1732 | {.compatible = "apm,xgene-phy",}, | ||
1733 | {}, | ||
1734 | }; | ||
1735 | MODULE_DEVICE_TABLE(of, xgene_phy_of_match); | ||
1736 | |||
1737 | static struct platform_driver xgene_phy_driver = { | ||
1738 | .probe = xgene_phy_probe, | ||
1739 | .driver = { | ||
1740 | .name = "xgene-phy", | ||
1741 | .owner = THIS_MODULE, | ||
1742 | .of_match_table = xgene_phy_of_match, | ||
1743 | }, | ||
1744 | }; | ||
1745 | module_platform_driver(xgene_phy_driver); | ||
1746 | |||
1747 | MODULE_DESCRIPTION("APM X-Gene Multi-Purpose PHY driver"); | ||
1748 | MODULE_AUTHOR("Loc Ho <lho@apm.com>"); | ||
1749 | MODULE_LICENSE("GPL v2"); | ||
1750 | MODULE_VERSION("0.1"); | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 2e6b832e004b..e0cad4418085 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -2,10 +2,6 @@ | |||
2 | # USB device configuration | 2 | # USB device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | # These are unused now, remove them once they are no longer selected | ||
6 | config USB_ARCH_HAS_OHCI | ||
7 | bool | ||
8 | |||
9 | config USB_OHCI_BIG_ENDIAN_DESC | 5 | config USB_OHCI_BIG_ENDIAN_DESC |
10 | bool | 6 | bool |
11 | 7 | ||
@@ -17,18 +13,12 @@ config USB_OHCI_LITTLE_ENDIAN | |||
17 | default n if STB03xxx || PPC_MPC52xx | 13 | default n if STB03xxx || PPC_MPC52xx |
18 | default y | 14 | default y |
19 | 15 | ||
20 | config USB_ARCH_HAS_EHCI | ||
21 | bool | ||
22 | |||
23 | config USB_EHCI_BIG_ENDIAN_MMIO | 16 | config USB_EHCI_BIG_ENDIAN_MMIO |
24 | bool | 17 | bool |
25 | 18 | ||
26 | config USB_EHCI_BIG_ENDIAN_DESC | 19 | config USB_EHCI_BIG_ENDIAN_DESC |
27 | bool | 20 | bool |
28 | 21 | ||
29 | config USB_ARCH_HAS_XHCI | ||
30 | bool | ||
31 | |||
32 | menuconfig USB_SUPPORT | 22 | menuconfig USB_SUPPORT |
33 | bool "USB support" | 23 | bool "USB support" |
34 | depends on HAS_IOMEM | 24 | depends on HAS_IOMEM |
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 7345d2115af2..480bd4d5710a 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile | |||
@@ -10,6 +10,7 @@ ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o | |||
10 | # Glue/Bridge layers go here | 10 | # Glue/Bridge layers go here |
11 | 11 | ||
12 | obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_msm.o | 12 | obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_msm.o |
13 | obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o | ||
13 | 14 | ||
14 | # PCI doesn't provide stubs, need to check | 15 | # PCI doesn't provide stubs, need to check |
15 | ifneq ($(CONFIG_PCI),) | 16 | ifneq ($(CONFIG_PCI),) |
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h index a85713165688..83d06c1455b7 100644 --- a/drivers/usb/chipidea/bits.h +++ b/drivers/usb/chipidea/bits.h | |||
@@ -50,12 +50,14 @@ | |||
50 | #define PORTSC_PTC (0x0FUL << 16) | 50 | #define PORTSC_PTC (0x0FUL << 16) |
51 | #define PORTSC_PHCD(d) ((d) ? BIT(22) : BIT(23)) | 51 | #define PORTSC_PHCD(d) ((d) ? BIT(22) : BIT(23)) |
52 | /* PTS and PTW for non lpm version only */ | 52 | /* PTS and PTW for non lpm version only */ |
53 | #define PORTSC_PFSC BIT(24) | ||
53 | #define PORTSC_PTS(d) \ | 54 | #define PORTSC_PTS(d) \ |
54 | (u32)((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0)) | 55 | (u32)((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0)) |
55 | #define PORTSC_PTW BIT(28) | 56 | #define PORTSC_PTW BIT(28) |
56 | #define PORTSC_STS BIT(29) | 57 | #define PORTSC_STS BIT(29) |
57 | 58 | ||
58 | /* DEVLC */ | 59 | /* DEVLC */ |
60 | #define DEVLC_PFSC BIT(23) | ||
59 | #define DEVLC_PSPD (0x03UL << 25) | 61 | #define DEVLC_PSPD (0x03UL << 25) |
60 | #define DEVLC_PSPD_HS (0x02UL << 25) | 62 | #define DEVLC_PSPD_HS (0x02UL << 25) |
61 | #define DEVLC_PTW BIT(27) | 63 | #define DEVLC_PTW BIT(27) |
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 88b80f7728e4..e206406ae1d9 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h | |||
@@ -196,8 +196,6 @@ struct ci_hdrc { | |||
196 | 196 | ||
197 | struct ci_hdrc_platform_data *platdata; | 197 | struct ci_hdrc_platform_data *platdata; |
198 | int vbus_active; | 198 | int vbus_active; |
199 | /* FIXME: some day, we'll not use global phy */ | ||
200 | bool global_phy; | ||
201 | struct usb_phy *transceiver; | 199 | struct usb_phy *transceiver; |
202 | struct usb_hcd *hcd; | 200 | struct usb_hcd *hcd; |
203 | struct dentry *debugfs; | 201 | struct dentry *debugfs; |
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index c00f77257d36..2e58f8dfd311 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c | |||
@@ -96,7 +96,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
96 | { | 96 | { |
97 | struct ci_hdrc_imx_data *data; | 97 | struct ci_hdrc_imx_data *data; |
98 | struct ci_hdrc_platform_data pdata = { | 98 | struct ci_hdrc_platform_data pdata = { |
99 | .name = "ci_hdrc_imx", | 99 | .name = dev_name(&pdev->dev), |
100 | .capoffset = DEF_CAPOFFSET, | 100 | .capoffset = DEF_CAPOFFSET, |
101 | .flags = CI_HDRC_REQUIRE_TRANSCEIVER | | 101 | .flags = CI_HDRC_REQUIRE_TRANSCEIVER | |
102 | CI_HDRC_DISABLE_STREAMING, | 102 | CI_HDRC_DISABLE_STREAMING, |
diff --git a/drivers/usb/chipidea/ci_hdrc_zevio.c b/drivers/usb/chipidea/ci_hdrc_zevio.c new file mode 100644 index 000000000000..3bf6489ef5ec --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_zevio.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Based off drivers/usb/chipidea/ci_hdrc_msm.c | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/usb/gadget.h> | ||
15 | #include <linux/usb/chipidea.h> | ||
16 | |||
17 | #include "ci.h" | ||
18 | |||
19 | static struct ci_hdrc_platform_data ci_hdrc_zevio_platdata = { | ||
20 | .name = "ci_hdrc_zevio", | ||
21 | .flags = CI_HDRC_REGS_SHARED, | ||
22 | .capoffset = DEF_CAPOFFSET, | ||
23 | }; | ||
24 | |||
25 | static int ci_hdrc_zevio_probe(struct platform_device *pdev) | ||
26 | { | ||
27 | struct platform_device *ci_pdev; | ||
28 | |||
29 | dev_dbg(&pdev->dev, "ci_hdrc_zevio_probe\n"); | ||
30 | |||
31 | ci_pdev = ci_hdrc_add_device(&pdev->dev, | ||
32 | pdev->resource, pdev->num_resources, | ||
33 | &ci_hdrc_zevio_platdata); | ||
34 | |||
35 | if (IS_ERR(ci_pdev)) { | ||
36 | dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n"); | ||
37 | return PTR_ERR(ci_pdev); | ||
38 | } | ||
39 | |||
40 | platform_set_drvdata(pdev, ci_pdev); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static int ci_hdrc_zevio_remove(struct platform_device *pdev) | ||
46 | { | ||
47 | struct platform_device *ci_pdev = platform_get_drvdata(pdev); | ||
48 | |||
49 | ci_hdrc_remove_device(ci_pdev); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static const struct of_device_id ci_hdrc_zevio_dt_ids[] = { | ||
55 | { .compatible = "lsi,zevio-usb", }, | ||
56 | { /* sentinel */ } | ||
57 | }; | ||
58 | |||
59 | static struct platform_driver ci_hdrc_zevio_driver = { | ||
60 | .probe = ci_hdrc_zevio_probe, | ||
61 | .remove = ci_hdrc_zevio_remove, | ||
62 | .driver = { | ||
63 | .name = "zevio_usb", | ||
64 | .owner = THIS_MODULE, | ||
65 | .of_match_table = ci_hdrc_zevio_dt_ids, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | MODULE_DEVICE_TABLE(of, ci_hdrc_zevio_dt_ids); | ||
70 | module_platform_driver(ci_hdrc_zevio_driver); | ||
71 | |||
72 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 33f22bc6ad7f..ca6831c5b763 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/usb/otg.h> | 64 | #include <linux/usb/otg.h> |
65 | #include <linux/usb/chipidea.h> | 65 | #include <linux/usb/chipidea.h> |
66 | #include <linux/usb/of.h> | 66 | #include <linux/usb/of.h> |
67 | #include <linux/of.h> | ||
67 | #include <linux/phy.h> | 68 | #include <linux/phy.h> |
68 | #include <linux/regulator/consumer.h> | 69 | #include <linux/regulator/consumer.h> |
69 | 70 | ||
@@ -298,6 +299,13 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode) | |||
298 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) | 299 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) |
299 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | 300 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); |
300 | 301 | ||
302 | if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) { | ||
303 | if (ci->hw_bank.lpm) | ||
304 | hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC); | ||
305 | else | ||
306 | hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC); | ||
307 | } | ||
308 | |||
301 | /* USBMODE should be configured step by step */ | 309 | /* USBMODE should be configured step by step */ |
302 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | 310 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); |
303 | hw_write(ci, OP_USBMODE, USBMODE_CM, mode); | 311 | hw_write(ci, OP_USBMODE, USBMODE_CM, mode); |
@@ -412,6 +420,9 @@ static int ci_get_platdata(struct device *dev, | |||
412 | } | 420 | } |
413 | } | 421 | } |
414 | 422 | ||
423 | if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) | ||
424 | platdata->flags |= CI_HDRC_FORCE_FULLSPEED; | ||
425 | |||
415 | return 0; | 426 | return 0; |
416 | } | 427 | } |
417 | 428 | ||
@@ -496,33 +507,6 @@ static void ci_get_otg_capable(struct ci_hdrc *ci) | |||
496 | } | 507 | } |
497 | } | 508 | } |
498 | 509 | ||
499 | static int ci_usb_phy_init(struct ci_hdrc *ci) | ||
500 | { | ||
501 | if (ci->platdata->phy) { | ||
502 | ci->transceiver = ci->platdata->phy; | ||
503 | return usb_phy_init(ci->transceiver); | ||
504 | } else { | ||
505 | ci->global_phy = true; | ||
506 | ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | ||
507 | if (IS_ERR(ci->transceiver)) | ||
508 | ci->transceiver = NULL; | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | static void ci_usb_phy_destroy(struct ci_hdrc *ci) | ||
515 | { | ||
516 | if (!ci->transceiver) | ||
517 | return; | ||
518 | |||
519 | otg_set_peripheral(ci->transceiver->otg, NULL); | ||
520 | if (ci->global_phy) | ||
521 | usb_put_phy(ci->transceiver); | ||
522 | else | ||
523 | usb_phy_shutdown(ci->transceiver); | ||
524 | } | ||
525 | |||
526 | static int ci_hdrc_probe(struct platform_device *pdev) | 510 | static int ci_hdrc_probe(struct platform_device *pdev) |
527 | { | 511 | { |
528 | struct device *dev = &pdev->dev; | 512 | struct device *dev = &pdev->dev; |
@@ -532,7 +516,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
532 | int ret; | 516 | int ret; |
533 | enum usb_dr_mode dr_mode; | 517 | enum usb_dr_mode dr_mode; |
534 | 518 | ||
535 | if (!dev->platform_data) { | 519 | if (!dev_get_platdata(dev)) { |
536 | dev_err(dev, "platform data missing\n"); | 520 | dev_err(dev, "platform data missing\n"); |
537 | return -ENODEV; | 521 | return -ENODEV; |
538 | } | 522 | } |
@@ -549,7 +533,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
549 | } | 533 | } |
550 | 534 | ||
551 | ci->dev = dev; | 535 | ci->dev = dev; |
552 | ci->platdata = dev->platform_data; | 536 | ci->platdata = dev_get_platdata(dev); |
553 | ci->imx28_write_fix = !!(ci->platdata->flags & | 537 | ci->imx28_write_fix = !!(ci->platdata->flags & |
554 | CI_HDRC_IMX28_WRITE_FIX); | 538 | CI_HDRC_IMX28_WRITE_FIX); |
555 | 539 | ||
@@ -561,7 +545,26 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
561 | 545 | ||
562 | hw_phymode_configure(ci); | 546 | hw_phymode_configure(ci); |
563 | 547 | ||
564 | ret = ci_usb_phy_init(ci); | 548 | if (ci->platdata->phy) |
549 | ci->transceiver = ci->platdata->phy; | ||
550 | else | ||
551 | ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
552 | |||
553 | if (IS_ERR(ci->transceiver)) { | ||
554 | ret = PTR_ERR(ci->transceiver); | ||
555 | /* | ||
556 | * if -ENXIO is returned, it means PHY layer wasn't | ||
557 | * enabled, so it makes no sense to return -EPROBE_DEFER | ||
558 | * in that case, since no PHY driver will ever probe. | ||
559 | */ | ||
560 | if (ret == -ENXIO) | ||
561 | return ret; | ||
562 | |||
563 | dev_err(dev, "no usb2 phy configured\n"); | ||
564 | return -EPROBE_DEFER; | ||
565 | } | ||
566 | |||
567 | ret = usb_phy_init(ci->transceiver); | ||
565 | if (ret) { | 568 | if (ret) { |
566 | dev_err(dev, "unable to init phy: %d\n", ret); | 569 | dev_err(dev, "unable to init phy: %d\n", ret); |
567 | return ret; | 570 | return ret; |
@@ -572,8 +575,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
572 | ci->irq = platform_get_irq(pdev, 0); | 575 | ci->irq = platform_get_irq(pdev, 0); |
573 | if (ci->irq < 0) { | 576 | if (ci->irq < 0) { |
574 | dev_err(dev, "missing IRQ\n"); | 577 | dev_err(dev, "missing IRQ\n"); |
575 | ret = -ENODEV; | 578 | ret = ci->irq; |
576 | goto destroy_phy; | 579 | goto deinit_phy; |
577 | } | 580 | } |
578 | 581 | ||
579 | ci_get_otg_capable(ci); | 582 | ci_get_otg_capable(ci); |
@@ -590,23 +593,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
590 | ret = ci_hdrc_gadget_init(ci); | 593 | ret = ci_hdrc_gadget_init(ci); |
591 | if (ret) | 594 | if (ret) |
592 | dev_info(dev, "doesn't support gadget\n"); | 595 | dev_info(dev, "doesn't support gadget\n"); |
593 | if (!ret && ci->transceiver) { | ||
594 | ret = otg_set_peripheral(ci->transceiver->otg, | ||
595 | &ci->gadget); | ||
596 | /* | ||
597 | * If we implement all USB functions using chipidea drivers, | ||
598 | * it doesn't need to call above API, meanwhile, if we only | ||
599 | * use gadget function, calling above API is useless. | ||
600 | */ | ||
601 | if (ret && ret != -ENOTSUPP) | ||
602 | goto destroy_phy; | ||
603 | } | ||
604 | } | 596 | } |
605 | 597 | ||
606 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { | 598 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { |
607 | dev_err(dev, "no supported roles\n"); | 599 | dev_err(dev, "no supported roles\n"); |
608 | ret = -ENODEV; | 600 | ret = -ENODEV; |
609 | goto destroy_phy; | 601 | goto deinit_phy; |
610 | } | 602 | } |
611 | 603 | ||
612 | if (ci->is_otg) { | 604 | if (ci->is_otg) { |
@@ -663,8 +655,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
663 | free_irq(ci->irq, ci); | 655 | free_irq(ci->irq, ci); |
664 | stop: | 656 | stop: |
665 | ci_role_destroy(ci); | 657 | ci_role_destroy(ci); |
666 | destroy_phy: | 658 | deinit_phy: |
667 | ci_usb_phy_destroy(ci); | 659 | usb_phy_shutdown(ci->transceiver); |
668 | 660 | ||
669 | return ret; | 661 | return ret; |
670 | } | 662 | } |
@@ -677,7 +669,8 @@ static int ci_hdrc_remove(struct platform_device *pdev) | |||
677 | free_irq(ci->irq, ci); | 669 | free_irq(ci->irq, ci); |
678 | ci_role_destroy(ci); | 670 | ci_role_destroy(ci); |
679 | ci_hdrc_enter_lpm(ci, true); | 671 | ci_hdrc_enter_lpm(ci, true); |
680 | ci_usb_phy_destroy(ci); | 672 | usb_phy_shutdown(ci->transceiver); |
673 | kfree(ci->hw_bank.regmap); | ||
681 | 674 | ||
682 | return 0; | 675 | return 0; |
683 | } | 676 | } |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 4ab2cb62dfce..7739c64ef259 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -178,19 +178,6 @@ static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
181 | * hw_test_and_clear_setup_status: test & clear setup status (execute without | ||
182 | * interruption) | ||
183 | * @n: endpoint number | ||
184 | * | ||
185 | * This function returns setup status | ||
186 | */ | ||
187 | static int hw_test_and_clear_setup_status(struct ci_hdrc *ci, int n) | ||
188 | { | ||
189 | n = ep_to_bit(ci, n); | ||
190 | return hw_test_and_clear(ci, OP_ENDPTSETUPSTAT, BIT(n)); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * hw_ep_prime: primes endpoint (execute without interruption) | 181 | * hw_ep_prime: primes endpoint (execute without interruption) |
195 | * @num: endpoint number | 182 | * @num: endpoint number |
196 | * @dir: endpoint direction | 183 | * @dir: endpoint direction |
@@ -962,6 +949,156 @@ __acquires(hwep->lock) | |||
962 | } | 949 | } |
963 | 950 | ||
964 | /** | 951 | /** |
952 | * isr_setup_packet_handler: setup packet handler | ||
953 | * @ci: UDC descriptor | ||
954 | * | ||
955 | * This function handles setup packet | ||
956 | */ | ||
957 | static void isr_setup_packet_handler(struct ci_hdrc *ci) | ||
958 | __releases(ci->lock) | ||
959 | __acquires(ci->lock) | ||
960 | { | ||
961 | struct ci_hw_ep *hwep = &ci->ci_hw_ep[0]; | ||
962 | struct usb_ctrlrequest req; | ||
963 | int type, num, dir, err = -EINVAL; | ||
964 | u8 tmode = 0; | ||
965 | |||
966 | /* | ||
967 | * Flush data and handshake transactions of previous | ||
968 | * setup packet. | ||
969 | */ | ||
970 | _ep_nuke(ci->ep0out); | ||
971 | _ep_nuke(ci->ep0in); | ||
972 | |||
973 | /* read_setup_packet */ | ||
974 | do { | ||
975 | hw_test_and_set_setup_guard(ci); | ||
976 | memcpy(&req, &hwep->qh.ptr->setup, sizeof(req)); | ||
977 | } while (!hw_test_and_clear_setup_guard(ci)); | ||
978 | |||
979 | type = req.bRequestType; | ||
980 | |||
981 | ci->ep0_dir = (type & USB_DIR_IN) ? TX : RX; | ||
982 | |||
983 | switch (req.bRequest) { | ||
984 | case USB_REQ_CLEAR_FEATURE: | ||
985 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
986 | le16_to_cpu(req.wValue) == | ||
987 | USB_ENDPOINT_HALT) { | ||
988 | if (req.wLength != 0) | ||
989 | break; | ||
990 | num = le16_to_cpu(req.wIndex); | ||
991 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
992 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
993 | if (dir) /* TX */ | ||
994 | num += ci->hw_ep_max / 2; | ||
995 | if (!ci->ci_hw_ep[num].wedge) { | ||
996 | spin_unlock(&ci->lock); | ||
997 | err = usb_ep_clear_halt( | ||
998 | &ci->ci_hw_ep[num].ep); | ||
999 | spin_lock(&ci->lock); | ||
1000 | if (err) | ||
1001 | break; | ||
1002 | } | ||
1003 | err = isr_setup_status_phase(ci); | ||
1004 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && | ||
1005 | le16_to_cpu(req.wValue) == | ||
1006 | USB_DEVICE_REMOTE_WAKEUP) { | ||
1007 | if (req.wLength != 0) | ||
1008 | break; | ||
1009 | ci->remote_wakeup = 0; | ||
1010 | err = isr_setup_status_phase(ci); | ||
1011 | } else { | ||
1012 | goto delegate; | ||
1013 | } | ||
1014 | break; | ||
1015 | case USB_REQ_GET_STATUS: | ||
1016 | if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && | ||
1017 | type != (USB_DIR_IN|USB_RECIP_ENDPOINT) && | ||
1018 | type != (USB_DIR_IN|USB_RECIP_INTERFACE)) | ||
1019 | goto delegate; | ||
1020 | if (le16_to_cpu(req.wLength) != 2 || | ||
1021 | le16_to_cpu(req.wValue) != 0) | ||
1022 | break; | ||
1023 | err = isr_get_status_response(ci, &req); | ||
1024 | break; | ||
1025 | case USB_REQ_SET_ADDRESS: | ||
1026 | if (type != (USB_DIR_OUT|USB_RECIP_DEVICE)) | ||
1027 | goto delegate; | ||
1028 | if (le16_to_cpu(req.wLength) != 0 || | ||
1029 | le16_to_cpu(req.wIndex) != 0) | ||
1030 | break; | ||
1031 | ci->address = (u8)le16_to_cpu(req.wValue); | ||
1032 | ci->setaddr = true; | ||
1033 | err = isr_setup_status_phase(ci); | ||
1034 | break; | ||
1035 | case USB_REQ_SET_FEATURE: | ||
1036 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
1037 | le16_to_cpu(req.wValue) == | ||
1038 | USB_ENDPOINT_HALT) { | ||
1039 | if (req.wLength != 0) | ||
1040 | break; | ||
1041 | num = le16_to_cpu(req.wIndex); | ||
1042 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
1043 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
1044 | if (dir) /* TX */ | ||
1045 | num += ci->hw_ep_max / 2; | ||
1046 | |||
1047 | spin_unlock(&ci->lock); | ||
1048 | err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep); | ||
1049 | spin_lock(&ci->lock); | ||
1050 | if (!err) | ||
1051 | isr_setup_status_phase(ci); | ||
1052 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { | ||
1053 | if (req.wLength != 0) | ||
1054 | break; | ||
1055 | switch (le16_to_cpu(req.wValue)) { | ||
1056 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1057 | ci->remote_wakeup = 1; | ||
1058 | err = isr_setup_status_phase(ci); | ||
1059 | break; | ||
1060 | case USB_DEVICE_TEST_MODE: | ||
1061 | tmode = le16_to_cpu(req.wIndex) >> 8; | ||
1062 | switch (tmode) { | ||
1063 | case TEST_J: | ||
1064 | case TEST_K: | ||
1065 | case TEST_SE0_NAK: | ||
1066 | case TEST_PACKET: | ||
1067 | case TEST_FORCE_EN: | ||
1068 | ci->test_mode = tmode; | ||
1069 | err = isr_setup_status_phase( | ||
1070 | ci); | ||
1071 | break; | ||
1072 | default: | ||
1073 | break; | ||
1074 | } | ||
1075 | default: | ||
1076 | goto delegate; | ||
1077 | } | ||
1078 | } else { | ||
1079 | goto delegate; | ||
1080 | } | ||
1081 | break; | ||
1082 | default: | ||
1083 | delegate: | ||
1084 | if (req.wLength == 0) /* no data phase */ | ||
1085 | ci->ep0_dir = TX; | ||
1086 | |||
1087 | spin_unlock(&ci->lock); | ||
1088 | err = ci->driver->setup(&ci->gadget, &req); | ||
1089 | spin_lock(&ci->lock); | ||
1090 | break; | ||
1091 | } | ||
1092 | |||
1093 | if (err < 0) { | ||
1094 | spin_unlock(&ci->lock); | ||
1095 | if (usb_ep_set_halt(&hwep->ep)) | ||
1096 | dev_err(ci->dev, "error: ep_set_halt\n"); | ||
1097 | spin_lock(&ci->lock); | ||
1098 | } | ||
1099 | } | ||
1100 | |||
1101 | /** | ||
965 | * isr_tr_complete_handler: transaction complete interrupt handler | 1102 | * isr_tr_complete_handler: transaction complete interrupt handler |
966 | * @ci: UDC descriptor | 1103 | * @ci: UDC descriptor |
967 | * | 1104 | * |
@@ -972,12 +1109,10 @@ __releases(ci->lock) | |||
972 | __acquires(ci->lock) | 1109 | __acquires(ci->lock) |
973 | { | 1110 | { |
974 | unsigned i; | 1111 | unsigned i; |
975 | u8 tmode = 0; | 1112 | int err; |
976 | 1113 | ||
977 | for (i = 0; i < ci->hw_ep_max; i++) { | 1114 | for (i = 0; i < ci->hw_ep_max; i++) { |
978 | struct ci_hw_ep *hwep = &ci->ci_hw_ep[i]; | 1115 | struct ci_hw_ep *hwep = &ci->ci_hw_ep[i]; |
979 | int type, num, dir, err = -EINVAL; | ||
980 | struct usb_ctrlrequest req; | ||
981 | 1116 | ||
982 | if (hwep->ep.desc == NULL) | 1117 | if (hwep->ep.desc == NULL) |
983 | continue; /* not configured */ | 1118 | continue; /* not configured */ |
@@ -997,148 +1132,10 @@ __acquires(ci->lock) | |||
997 | } | 1132 | } |
998 | } | 1133 | } |
999 | 1134 | ||
1000 | if (hwep->type != USB_ENDPOINT_XFER_CONTROL || | 1135 | /* Only handle setup packet below */ |
1001 | !hw_test_and_clear_setup_status(ci, i)) | 1136 | if (i == 0 && |
1002 | continue; | 1137 | hw_test_and_clear(ci, OP_ENDPTSETUPSTAT, BIT(0))) |
1003 | 1138 | isr_setup_packet_handler(ci); | |
1004 | if (i != 0) { | ||
1005 | dev_warn(ci->dev, "ctrl traffic at endpoint %d\n", i); | ||
1006 | continue; | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
1010 | * Flush data and handshake transactions of previous | ||
1011 | * setup packet. | ||
1012 | */ | ||
1013 | _ep_nuke(ci->ep0out); | ||
1014 | _ep_nuke(ci->ep0in); | ||
1015 | |||
1016 | /* read_setup_packet */ | ||
1017 | do { | ||
1018 | hw_test_and_set_setup_guard(ci); | ||
1019 | memcpy(&req, &hwep->qh.ptr->setup, sizeof(req)); | ||
1020 | } while (!hw_test_and_clear_setup_guard(ci)); | ||
1021 | |||
1022 | type = req.bRequestType; | ||
1023 | |||
1024 | ci->ep0_dir = (type & USB_DIR_IN) ? TX : RX; | ||
1025 | |||
1026 | switch (req.bRequest) { | ||
1027 | case USB_REQ_CLEAR_FEATURE: | ||
1028 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
1029 | le16_to_cpu(req.wValue) == | ||
1030 | USB_ENDPOINT_HALT) { | ||
1031 | if (req.wLength != 0) | ||
1032 | break; | ||
1033 | num = le16_to_cpu(req.wIndex); | ||
1034 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
1035 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
1036 | if (dir) /* TX */ | ||
1037 | num += ci->hw_ep_max/2; | ||
1038 | if (!ci->ci_hw_ep[num].wedge) { | ||
1039 | spin_unlock(&ci->lock); | ||
1040 | err = usb_ep_clear_halt( | ||
1041 | &ci->ci_hw_ep[num].ep); | ||
1042 | spin_lock(&ci->lock); | ||
1043 | if (err) | ||
1044 | break; | ||
1045 | } | ||
1046 | err = isr_setup_status_phase(ci); | ||
1047 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && | ||
1048 | le16_to_cpu(req.wValue) == | ||
1049 | USB_DEVICE_REMOTE_WAKEUP) { | ||
1050 | if (req.wLength != 0) | ||
1051 | break; | ||
1052 | ci->remote_wakeup = 0; | ||
1053 | err = isr_setup_status_phase(ci); | ||
1054 | } else { | ||
1055 | goto delegate; | ||
1056 | } | ||
1057 | break; | ||
1058 | case USB_REQ_GET_STATUS: | ||
1059 | if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && | ||
1060 | type != (USB_DIR_IN|USB_RECIP_ENDPOINT) && | ||
1061 | type != (USB_DIR_IN|USB_RECIP_INTERFACE)) | ||
1062 | goto delegate; | ||
1063 | if (le16_to_cpu(req.wLength) != 2 || | ||
1064 | le16_to_cpu(req.wValue) != 0) | ||
1065 | break; | ||
1066 | err = isr_get_status_response(ci, &req); | ||
1067 | break; | ||
1068 | case USB_REQ_SET_ADDRESS: | ||
1069 | if (type != (USB_DIR_OUT|USB_RECIP_DEVICE)) | ||
1070 | goto delegate; | ||
1071 | if (le16_to_cpu(req.wLength) != 0 || | ||
1072 | le16_to_cpu(req.wIndex) != 0) | ||
1073 | break; | ||
1074 | ci->address = (u8)le16_to_cpu(req.wValue); | ||
1075 | ci->setaddr = true; | ||
1076 | err = isr_setup_status_phase(ci); | ||
1077 | break; | ||
1078 | case USB_REQ_SET_FEATURE: | ||
1079 | if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && | ||
1080 | le16_to_cpu(req.wValue) == | ||
1081 | USB_ENDPOINT_HALT) { | ||
1082 | if (req.wLength != 0) | ||
1083 | break; | ||
1084 | num = le16_to_cpu(req.wIndex); | ||
1085 | dir = num & USB_ENDPOINT_DIR_MASK; | ||
1086 | num &= USB_ENDPOINT_NUMBER_MASK; | ||
1087 | if (dir) /* TX */ | ||
1088 | num += ci->hw_ep_max/2; | ||
1089 | |||
1090 | spin_unlock(&ci->lock); | ||
1091 | err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep); | ||
1092 | spin_lock(&ci->lock); | ||
1093 | if (!err) | ||
1094 | isr_setup_status_phase(ci); | ||
1095 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { | ||
1096 | if (req.wLength != 0) | ||
1097 | break; | ||
1098 | switch (le16_to_cpu(req.wValue)) { | ||
1099 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1100 | ci->remote_wakeup = 1; | ||
1101 | err = isr_setup_status_phase(ci); | ||
1102 | break; | ||
1103 | case USB_DEVICE_TEST_MODE: | ||
1104 | tmode = le16_to_cpu(req.wIndex) >> 8; | ||
1105 | switch (tmode) { | ||
1106 | case TEST_J: | ||
1107 | case TEST_K: | ||
1108 | case TEST_SE0_NAK: | ||
1109 | case TEST_PACKET: | ||
1110 | case TEST_FORCE_EN: | ||
1111 | ci->test_mode = tmode; | ||
1112 | err = isr_setup_status_phase( | ||
1113 | ci); | ||
1114 | break; | ||
1115 | default: | ||
1116 | break; | ||
1117 | } | ||
1118 | default: | ||
1119 | goto delegate; | ||
1120 | } | ||
1121 | } else { | ||
1122 | goto delegate; | ||
1123 | } | ||
1124 | break; | ||
1125 | default: | ||
1126 | delegate: | ||
1127 | if (req.wLength == 0) /* no data phase */ | ||
1128 | ci->ep0_dir = TX; | ||
1129 | |||
1130 | spin_unlock(&ci->lock); | ||
1131 | err = ci->driver->setup(&ci->gadget, &req); | ||
1132 | spin_lock(&ci->lock); | ||
1133 | break; | ||
1134 | } | ||
1135 | |||
1136 | if (err < 0) { | ||
1137 | spin_unlock(&ci->lock); | ||
1138 | if (usb_ep_set_halt(&hwep->ep)) | ||
1139 | dev_err(ci->dev, "error: ep_set_halt\n"); | ||
1140 | spin_lock(&ci->lock); | ||
1141 | } | ||
1142 | } | 1139 | } |
1143 | } | 1140 | } |
1144 | 1141 | ||
@@ -1193,6 +1190,11 @@ static int ep_enable(struct usb_ep *ep, | |||
1193 | 1190 | ||
1194 | hwep->qh.ptr->td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ | 1191 | hwep->qh.ptr->td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ |
1195 | 1192 | ||
1193 | if (hwep->num != 0 && hwep->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1194 | dev_err(hwep->ci->dev, "Set control xfer at non-ep0\n"); | ||
1195 | retval = -EINVAL; | ||
1196 | } | ||
1197 | |||
1196 | /* | 1198 | /* |
1197 | * Enable endpoints in the HW other than ep0 as ep0 | 1199 | * Enable endpoints in the HW other than ep0 as ep0 |
1198 | * is always enabled | 1200 | * is always enabled |
@@ -1837,12 +1839,6 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci) | |||
1837 | 1839 | ||
1838 | dma_pool_destroy(ci->td_pool); | 1840 | dma_pool_destroy(ci->td_pool); |
1839 | dma_pool_destroy(ci->qh_pool); | 1841 | dma_pool_destroy(ci->qh_pool); |
1840 | |||
1841 | if (ci->transceiver) { | ||
1842 | otg_set_peripheral(ci->transceiver->otg, NULL); | ||
1843 | if (ci->global_phy) | ||
1844 | usb_put_phy(ci->transceiver); | ||
1845 | } | ||
1846 | } | 1842 | } |
1847 | 1843 | ||
1848 | static int udc_id_switch_for_device(struct ci_hdrc *ci) | 1844 | static int udc_id_switch_for_device(struct ci_hdrc *ci) |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 062967c90b2a..1ab4df1de2da 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -10,7 +10,6 @@ | |||
10 | 10 | ||
11 | 11 | ||
12 | #define USB_MAXALTSETTING 128 /* Hard limit */ | 12 | #define USB_MAXALTSETTING 128 /* Hard limit */ |
13 | #define USB_MAXENDPOINTS 30 /* Hard limit */ | ||
14 | 13 | ||
15 | #define USB_MAXCONFIG 8 /* Arbitrary limit */ | 14 | #define USB_MAXCONFIG 8 /* Arbitrary limit */ |
16 | 15 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 2a8afe6754b8..257876ea03a1 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -769,6 +769,88 @@ static int check_ctrlrecip(struct usb_dev_state *ps, unsigned int requesttype, | |||
769 | return ret; | 769 | return ret; |
770 | } | 770 | } |
771 | 771 | ||
772 | static struct usb_host_endpoint *ep_to_host_endpoint(struct usb_device *dev, | ||
773 | unsigned char ep) | ||
774 | { | ||
775 | if (ep & USB_ENDPOINT_DIR_MASK) | ||
776 | return dev->ep_in[ep & USB_ENDPOINT_NUMBER_MASK]; | ||
777 | else | ||
778 | return dev->ep_out[ep & USB_ENDPOINT_NUMBER_MASK]; | ||
779 | } | ||
780 | |||
781 | static int parse_usbdevfs_streams(struct usb_dev_state *ps, | ||
782 | struct usbdevfs_streams __user *streams, | ||
783 | unsigned int *num_streams_ret, | ||
784 | unsigned int *num_eps_ret, | ||
785 | struct usb_host_endpoint ***eps_ret, | ||
786 | struct usb_interface **intf_ret) | ||
787 | { | ||
788 | unsigned int i, num_streams, num_eps; | ||
789 | struct usb_host_endpoint **eps; | ||
790 | struct usb_interface *intf = NULL; | ||
791 | unsigned char ep; | ||
792 | int ifnum, ret; | ||
793 | |||
794 | if (get_user(num_streams, &streams->num_streams) || | ||
795 | get_user(num_eps, &streams->num_eps)) | ||
796 | return -EFAULT; | ||
797 | |||
798 | if (num_eps < 1 || num_eps > USB_MAXENDPOINTS) | ||
799 | return -EINVAL; | ||
800 | |||
801 | /* The XHCI controller allows max 2 ^ 16 streams */ | ||
802 | if (num_streams_ret && (num_streams < 2 || num_streams > 65536)) | ||
803 | return -EINVAL; | ||
804 | |||
805 | eps = kmalloc(num_eps * sizeof(*eps), GFP_KERNEL); | ||
806 | if (!eps) | ||
807 | return -ENOMEM; | ||
808 | |||
809 | for (i = 0; i < num_eps; i++) { | ||
810 | if (get_user(ep, &streams->eps[i])) { | ||
811 | ret = -EFAULT; | ||
812 | goto error; | ||
813 | } | ||
814 | eps[i] = ep_to_host_endpoint(ps->dev, ep); | ||
815 | if (!eps[i]) { | ||
816 | ret = -EINVAL; | ||
817 | goto error; | ||
818 | } | ||
819 | |||
820 | /* usb_alloc/free_streams operate on an usb_interface */ | ||
821 | ifnum = findintfep(ps->dev, ep); | ||
822 | if (ifnum < 0) { | ||
823 | ret = ifnum; | ||
824 | goto error; | ||
825 | } | ||
826 | |||
827 | if (i == 0) { | ||
828 | ret = checkintf(ps, ifnum); | ||
829 | if (ret < 0) | ||
830 | goto error; | ||
831 | intf = usb_ifnum_to_if(ps->dev, ifnum); | ||
832 | } else { | ||
833 | /* Verify all eps belong to the same interface */ | ||
834 | if (ifnum != intf->altsetting->desc.bInterfaceNumber) { | ||
835 | ret = -EINVAL; | ||
836 | goto error; | ||
837 | } | ||
838 | } | ||
839 | } | ||
840 | |||
841 | if (num_streams_ret) | ||
842 | *num_streams_ret = num_streams; | ||
843 | *num_eps_ret = num_eps; | ||
844 | *eps_ret = eps; | ||
845 | *intf_ret = intf; | ||
846 | |||
847 | return 0; | ||
848 | |||
849 | error: | ||
850 | kfree(eps); | ||
851 | return ret; | ||
852 | } | ||
853 | |||
772 | static int match_devt(struct device *dev, void *data) | 854 | static int match_devt(struct device *dev, void *data) |
773 | { | 855 | { |
774 | return dev->devt == (dev_t) (unsigned long) data; | 856 | return dev->devt == (dev_t) (unsigned long) data; |
@@ -1043,6 +1125,20 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg) | |||
1043 | return ret; | 1125 | return ret; |
1044 | } | 1126 | } |
1045 | 1127 | ||
1128 | static void check_reset_of_active_ep(struct usb_device *udev, | ||
1129 | unsigned int epnum, char *ioctl_name) | ||
1130 | { | ||
1131 | struct usb_host_endpoint **eps; | ||
1132 | struct usb_host_endpoint *ep; | ||
1133 | |||
1134 | eps = (epnum & USB_DIR_IN) ? udev->ep_in : udev->ep_out; | ||
1135 | ep = eps[epnum & 0x0f]; | ||
1136 | if (ep && !list_empty(&ep->urb_list)) | ||
1137 | dev_warn(&udev->dev, "Process %d (%s) called USBDEVFS_%s for active endpoint 0x%02x\n", | ||
1138 | task_pid_nr(current), current->comm, | ||
1139 | ioctl_name, epnum); | ||
1140 | } | ||
1141 | |||
1046 | static int proc_resetep(struct usb_dev_state *ps, void __user *arg) | 1142 | static int proc_resetep(struct usb_dev_state *ps, void __user *arg) |
1047 | { | 1143 | { |
1048 | unsigned int ep; | 1144 | unsigned int ep; |
@@ -1056,6 +1152,7 @@ static int proc_resetep(struct usb_dev_state *ps, void __user *arg) | |||
1056 | ret = checkintf(ps, ret); | 1152 | ret = checkintf(ps, ret); |
1057 | if (ret) | 1153 | if (ret) |
1058 | return ret; | 1154 | return ret; |
1155 | check_reset_of_active_ep(ps->dev, ep, "RESETEP"); | ||
1059 | usb_reset_endpoint(ps->dev, ep); | 1156 | usb_reset_endpoint(ps->dev, ep); |
1060 | return 0; | 1157 | return 0; |
1061 | } | 1158 | } |
@@ -1074,6 +1171,7 @@ static int proc_clearhalt(struct usb_dev_state *ps, void __user *arg) | |||
1074 | ret = checkintf(ps, ret); | 1171 | ret = checkintf(ps, ret); |
1075 | if (ret) | 1172 | if (ret) |
1076 | return ret; | 1173 | return ret; |
1174 | check_reset_of_active_ep(ps->dev, ep, "CLEAR_HALT"); | ||
1077 | if (ep & USB_DIR_IN) | 1175 | if (ep & USB_DIR_IN) |
1078 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); | 1176 | pipe = usb_rcvbulkpipe(ps->dev, ep & 0x7f); |
1079 | else | 1177 | else |
@@ -1127,6 +1225,9 @@ static int proc_setintf(struct usb_dev_state *ps, void __user *arg) | |||
1127 | return -EFAULT; | 1225 | return -EFAULT; |
1128 | if ((ret = checkintf(ps, setintf.interface))) | 1226 | if ((ret = checkintf(ps, setintf.interface))) |
1129 | return ret; | 1227 | return ret; |
1228 | |||
1229 | destroy_async_on_interface(ps, setintf.interface); | ||
1230 | |||
1130 | return usb_set_interface(ps->dev, setintf.interface, | 1231 | return usb_set_interface(ps->dev, setintf.interface, |
1131 | setintf.altsetting); | 1232 | setintf.altsetting); |
1132 | } | 1233 | } |
@@ -1189,6 +1290,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1189 | struct usb_ctrlrequest *dr = NULL; | 1290 | struct usb_ctrlrequest *dr = NULL; |
1190 | unsigned int u, totlen, isofrmlen; | 1291 | unsigned int u, totlen, isofrmlen; |
1191 | int i, ret, is_in, num_sgs = 0, ifnum = -1; | 1292 | int i, ret, is_in, num_sgs = 0, ifnum = -1; |
1293 | int number_of_packets = 0; | ||
1294 | unsigned int stream_id = 0; | ||
1192 | void *buf; | 1295 | void *buf; |
1193 | 1296 | ||
1194 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | | 1297 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | |
@@ -1209,15 +1312,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1209 | if (ret) | 1312 | if (ret) |
1210 | return ret; | 1313 | return ret; |
1211 | } | 1314 | } |
1212 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { | 1315 | ep = ep_to_host_endpoint(ps->dev, uurb->endpoint); |
1213 | is_in = 1; | ||
1214 | ep = ps->dev->ep_in[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | ||
1215 | } else { | ||
1216 | is_in = 0; | ||
1217 | ep = ps->dev->ep_out[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | ||
1218 | } | ||
1219 | if (!ep) | 1316 | if (!ep) |
1220 | return -ENOENT; | 1317 | return -ENOENT; |
1318 | is_in = (uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0; | ||
1221 | 1319 | ||
1222 | u = 0; | 1320 | u = 0; |
1223 | switch(uurb->type) { | 1321 | switch(uurb->type) { |
@@ -1242,7 +1340,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1242 | le16_to_cpup(&dr->wIndex)); | 1340 | le16_to_cpup(&dr->wIndex)); |
1243 | if (ret) | 1341 | if (ret) |
1244 | goto error; | 1342 | goto error; |
1245 | uurb->number_of_packets = 0; | ||
1246 | uurb->buffer_length = le16_to_cpup(&dr->wLength); | 1343 | uurb->buffer_length = le16_to_cpup(&dr->wLength); |
1247 | uurb->buffer += 8; | 1344 | uurb->buffer += 8; |
1248 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { | 1345 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { |
@@ -1272,17 +1369,17 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1272 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; | 1369 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; |
1273 | goto interrupt_urb; | 1370 | goto interrupt_urb; |
1274 | } | 1371 | } |
1275 | uurb->number_of_packets = 0; | ||
1276 | num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); | 1372 | num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); |
1277 | if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) | 1373 | if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) |
1278 | num_sgs = 0; | 1374 | num_sgs = 0; |
1375 | if (ep->streams) | ||
1376 | stream_id = uurb->stream_id; | ||
1279 | break; | 1377 | break; |
1280 | 1378 | ||
1281 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1379 | case USBDEVFS_URB_TYPE_INTERRUPT: |
1282 | if (!usb_endpoint_xfer_int(&ep->desc)) | 1380 | if (!usb_endpoint_xfer_int(&ep->desc)) |
1283 | return -EINVAL; | 1381 | return -EINVAL; |
1284 | interrupt_urb: | 1382 | interrupt_urb: |
1285 | uurb->number_of_packets = 0; | ||
1286 | break; | 1383 | break; |
1287 | 1384 | ||
1288 | case USBDEVFS_URB_TYPE_ISO: | 1385 | case USBDEVFS_URB_TYPE_ISO: |
@@ -1292,15 +1389,16 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1292 | return -EINVAL; | 1389 | return -EINVAL; |
1293 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 1390 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
1294 | return -EINVAL; | 1391 | return -EINVAL; |
1392 | number_of_packets = uurb->number_of_packets; | ||
1295 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * | 1393 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * |
1296 | uurb->number_of_packets; | 1394 | number_of_packets; |
1297 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1395 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
1298 | return -ENOMEM; | 1396 | return -ENOMEM; |
1299 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { | 1397 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { |
1300 | ret = -EFAULT; | 1398 | ret = -EFAULT; |
1301 | goto error; | 1399 | goto error; |
1302 | } | 1400 | } |
1303 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1401 | for (totlen = u = 0; u < number_of_packets; u++) { |
1304 | /* | 1402 | /* |
1305 | * arbitrary limit need for USB 3.0 | 1403 | * arbitrary limit need for USB 3.0 |
1306 | * bMaxBurst (0~15 allowed, 1~16 packets) | 1404 | * bMaxBurst (0~15 allowed, 1~16 packets) |
@@ -1331,7 +1429,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1331 | ret = -EFAULT; | 1429 | ret = -EFAULT; |
1332 | goto error; | 1430 | goto error; |
1333 | } | 1431 | } |
1334 | as = alloc_async(uurb->number_of_packets); | 1432 | as = alloc_async(number_of_packets); |
1335 | if (!as) { | 1433 | if (!as) { |
1336 | ret = -ENOMEM; | 1434 | ret = -ENOMEM; |
1337 | goto error; | 1435 | goto error; |
@@ -1425,7 +1523,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1425 | as->urb->setup_packet = (unsigned char *)dr; | 1523 | as->urb->setup_packet = (unsigned char *)dr; |
1426 | dr = NULL; | 1524 | dr = NULL; |
1427 | as->urb->start_frame = uurb->start_frame; | 1525 | as->urb->start_frame = uurb->start_frame; |
1428 | as->urb->number_of_packets = uurb->number_of_packets; | 1526 | as->urb->number_of_packets = number_of_packets; |
1527 | as->urb->stream_id = stream_id; | ||
1429 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || | 1528 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || |
1430 | ps->dev->speed == USB_SPEED_HIGH) | 1529 | ps->dev->speed == USB_SPEED_HIGH) |
1431 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); | 1530 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); |
@@ -1433,7 +1532,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
1433 | as->urb->interval = ep->desc.bInterval; | 1532 | as->urb->interval = ep->desc.bInterval; |
1434 | as->urb->context = as; | 1533 | as->urb->context = as; |
1435 | as->urb->complete = async_completed; | 1534 | as->urb->complete = async_completed; |
1436 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1535 | for (totlen = u = 0; u < number_of_packets; u++) { |
1437 | as->urb->iso_frame_desc[u].offset = totlen; | 1536 | as->urb->iso_frame_desc[u].offset = totlen; |
1438 | as->urb->iso_frame_desc[u].length = isopkt[u].length; | 1537 | as->urb->iso_frame_desc[u].length = isopkt[u].length; |
1439 | totlen += isopkt[u].length; | 1538 | totlen += isopkt[u].length; |
@@ -1983,6 +2082,45 @@ static int proc_disconnect_claim(struct usb_dev_state *ps, void __user *arg) | |||
1983 | return claimintf(ps, dc.interface); | 2082 | return claimintf(ps, dc.interface); |
1984 | } | 2083 | } |
1985 | 2084 | ||
2085 | static int proc_alloc_streams(struct usb_dev_state *ps, void __user *arg) | ||
2086 | { | ||
2087 | unsigned num_streams, num_eps; | ||
2088 | struct usb_host_endpoint **eps; | ||
2089 | struct usb_interface *intf; | ||
2090 | int r; | ||
2091 | |||
2092 | r = parse_usbdevfs_streams(ps, arg, &num_streams, &num_eps, | ||
2093 | &eps, &intf); | ||
2094 | if (r) | ||
2095 | return r; | ||
2096 | |||
2097 | destroy_async_on_interface(ps, | ||
2098 | intf->altsetting[0].desc.bInterfaceNumber); | ||
2099 | |||
2100 | r = usb_alloc_streams(intf, eps, num_eps, num_streams, GFP_KERNEL); | ||
2101 | kfree(eps); | ||
2102 | return r; | ||
2103 | } | ||
2104 | |||
2105 | static int proc_free_streams(struct usb_dev_state *ps, void __user *arg) | ||
2106 | { | ||
2107 | unsigned num_eps; | ||
2108 | struct usb_host_endpoint **eps; | ||
2109 | struct usb_interface *intf; | ||
2110 | int r; | ||
2111 | |||
2112 | r = parse_usbdevfs_streams(ps, arg, NULL, &num_eps, &eps, &intf); | ||
2113 | if (r) | ||
2114 | return r; | ||
2115 | |||
2116 | destroy_async_on_interface(ps, | ||
2117 | intf->altsetting[0].desc.bInterfaceNumber); | ||
2118 | |||
2119 | r = usb_free_streams(intf, eps, num_eps, GFP_KERNEL); | ||
2120 | kfree(eps); | ||
2121 | return r; | ||
2122 | } | ||
2123 | |||
1986 | /* | 2124 | /* |
1987 | * NOTE: All requests here that have interface numbers as parameters | 2125 | * NOTE: All requests here that have interface numbers as parameters |
1988 | * are assuming that somehow the configuration has been prevented from | 2126 | * are assuming that somehow the configuration has been prevented from |
@@ -2159,6 +2297,12 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, | |||
2159 | case USBDEVFS_DISCONNECT_CLAIM: | 2297 | case USBDEVFS_DISCONNECT_CLAIM: |
2160 | ret = proc_disconnect_claim(ps, p); | 2298 | ret = proc_disconnect_claim(ps, p); |
2161 | break; | 2299 | break; |
2300 | case USBDEVFS_ALLOC_STREAMS: | ||
2301 | ret = proc_alloc_streams(ps, p); | ||
2302 | break; | ||
2303 | case USBDEVFS_FREE_STREAMS: | ||
2304 | ret = proc_free_streams(ps, p); | ||
2305 | break; | ||
2162 | } | 2306 | } |
2163 | usb_unlock_device(dev); | 2307 | usb_unlock_device(dev); |
2164 | if (ret >= 0) | 2308 | if (ret >= 0) |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ab90a0156828..888881e5f292 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -312,9 +312,9 @@ static int usb_probe_interface(struct device *dev) | |||
312 | return error; | 312 | return error; |
313 | } | 313 | } |
314 | 314 | ||
315 | id = usb_match_id(intf, driver->id_table); | 315 | id = usb_match_dynamic_id(intf, driver); |
316 | if (!id) | 316 | if (!id) |
317 | id = usb_match_dynamic_id(intf, driver); | 317 | id = usb_match_id(intf, driver->id_table); |
318 | if (!id) | 318 | if (!id) |
319 | return error; | 319 | return error; |
320 | 320 | ||
@@ -400,8 +400,9 @@ static int usb_unbind_interface(struct device *dev) | |||
400 | { | 400 | { |
401 | struct usb_driver *driver = to_usb_driver(dev->driver); | 401 | struct usb_driver *driver = to_usb_driver(dev->driver); |
402 | struct usb_interface *intf = to_usb_interface(dev); | 402 | struct usb_interface *intf = to_usb_interface(dev); |
403 | struct usb_host_endpoint *ep, **eps = NULL; | ||
403 | struct usb_device *udev; | 404 | struct usb_device *udev; |
404 | int error, r, lpm_disable_error; | 405 | int i, j, error, r, lpm_disable_error; |
405 | 406 | ||
406 | intf->condition = USB_INTERFACE_UNBINDING; | 407 | intf->condition = USB_INTERFACE_UNBINDING; |
407 | 408 | ||
@@ -425,6 +426,26 @@ static int usb_unbind_interface(struct device *dev) | |||
425 | driver->disconnect(intf); | 426 | driver->disconnect(intf); |
426 | usb_cancel_queued_reset(intf); | 427 | usb_cancel_queued_reset(intf); |
427 | 428 | ||
429 | /* Free streams */ | ||
430 | for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { | ||
431 | ep = &intf->cur_altsetting->endpoint[i]; | ||
432 | if (ep->streams == 0) | ||
433 | continue; | ||
434 | if (j == 0) { | ||
435 | eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *), | ||
436 | GFP_KERNEL); | ||
437 | if (!eps) { | ||
438 | dev_warn(dev, "oom, leaking streams\n"); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | eps[j++] = ep; | ||
443 | } | ||
444 | if (j) { | ||
445 | usb_free_streams(intf, eps, j, GFP_KERNEL); | ||
446 | kfree(eps); | ||
447 | } | ||
448 | |||
428 | /* Reset other interface state. | 449 | /* Reset other interface state. |
429 | * We cannot do a Set-Interface if the device is suspended or | 450 | * We cannot do a Set-Interface if the device is suspended or |
430 | * if it is prepared for a system sleep (since installing a new | 451 | * if it is prepared for a system sleep (since installing a new |
@@ -990,8 +1011,7 @@ EXPORT_SYMBOL_GPL(usb_deregister); | |||
990 | * it doesn't support pre_reset/post_reset/reset_resume or | 1011 | * it doesn't support pre_reset/post_reset/reset_resume or |
991 | * because it doesn't support suspend/resume. | 1012 | * because it doesn't support suspend/resume. |
992 | * | 1013 | * |
993 | * The caller must hold @intf's device's lock, but not its pm_mutex | 1014 | * The caller must hold @intf's device's lock, but not @intf's lock. |
994 | * and not @intf->dev.sem. | ||
995 | */ | 1015 | */ |
996 | void usb_forced_unbind_intf(struct usb_interface *intf) | 1016 | void usb_forced_unbind_intf(struct usb_interface *intf) |
997 | { | 1017 | { |
@@ -1004,16 +1024,37 @@ void usb_forced_unbind_intf(struct usb_interface *intf) | |||
1004 | intf->needs_binding = 1; | 1024 | intf->needs_binding = 1; |
1005 | } | 1025 | } |
1006 | 1026 | ||
1027 | /* | ||
1028 | * Unbind drivers for @udev's marked interfaces. These interfaces have | ||
1029 | * the needs_binding flag set, for example by usb_resume_interface(). | ||
1030 | * | ||
1031 | * The caller must hold @udev's device lock. | ||
1032 | */ | ||
1033 | static void unbind_marked_interfaces(struct usb_device *udev) | ||
1034 | { | ||
1035 | struct usb_host_config *config; | ||
1036 | int i; | ||
1037 | struct usb_interface *intf; | ||
1038 | |||
1039 | config = udev->actconfig; | ||
1040 | if (config) { | ||
1041 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | ||
1042 | intf = config->interface[i]; | ||
1043 | if (intf->dev.driver && intf->needs_binding) | ||
1044 | usb_forced_unbind_intf(intf); | ||
1045 | } | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1007 | /* Delayed forced unbinding of a USB interface driver and scan | 1049 | /* Delayed forced unbinding of a USB interface driver and scan |
1008 | * for rebinding. | 1050 | * for rebinding. |
1009 | * | 1051 | * |
1010 | * The caller must hold @intf's device's lock, but not its pm_mutex | 1052 | * The caller must hold @intf's device's lock, but not @intf's lock. |
1011 | * and not @intf->dev.sem. | ||
1012 | * | 1053 | * |
1013 | * Note: Rebinds will be skipped if a system sleep transition is in | 1054 | * Note: Rebinds will be skipped if a system sleep transition is in |
1014 | * progress and the PM "complete" callback hasn't occurred yet. | 1055 | * progress and the PM "complete" callback hasn't occurred yet. |
1015 | */ | 1056 | */ |
1016 | void usb_rebind_intf(struct usb_interface *intf) | 1057 | static void usb_rebind_intf(struct usb_interface *intf) |
1017 | { | 1058 | { |
1018 | int rc; | 1059 | int rc; |
1019 | 1060 | ||
@@ -1030,68 +1071,66 @@ void usb_rebind_intf(struct usb_interface *intf) | |||
1030 | } | 1071 | } |
1031 | } | 1072 | } |
1032 | 1073 | ||
1033 | #ifdef CONFIG_PM | 1074 | /* |
1034 | 1075 | * Rebind drivers to @udev's marked interfaces. These interfaces have | |
1035 | /* Unbind drivers for @udev's interfaces that don't support suspend/resume | 1076 | * the needs_binding flag set. |
1036 | * There is no check for reset_resume here because it can be determined | ||
1037 | * only during resume whether reset_resume is needed. | ||
1038 | * | 1077 | * |
1039 | * The caller must hold @udev's device lock. | 1078 | * The caller must hold @udev's device lock. |
1040 | */ | 1079 | */ |
1041 | static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) | 1080 | static void rebind_marked_interfaces(struct usb_device *udev) |
1042 | { | 1081 | { |
1043 | struct usb_host_config *config; | 1082 | struct usb_host_config *config; |
1044 | int i; | 1083 | int i; |
1045 | struct usb_interface *intf; | 1084 | struct usb_interface *intf; |
1046 | struct usb_driver *drv; | ||
1047 | 1085 | ||
1048 | config = udev->actconfig; | 1086 | config = udev->actconfig; |
1049 | if (config) { | 1087 | if (config) { |
1050 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | 1088 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { |
1051 | intf = config->interface[i]; | 1089 | intf = config->interface[i]; |
1052 | 1090 | if (intf->needs_binding) | |
1053 | if (intf->dev.driver) { | 1091 | usb_rebind_intf(intf); |
1054 | drv = to_usb_driver(intf->dev.driver); | ||
1055 | if (!drv->suspend || !drv->resume) | ||
1056 | usb_forced_unbind_intf(intf); | ||
1057 | } | ||
1058 | } | 1092 | } |
1059 | } | 1093 | } |
1060 | } | 1094 | } |
1061 | 1095 | ||
1062 | /* Unbind drivers for @udev's interfaces that failed to support reset-resume. | 1096 | /* |
1063 | * These interfaces have the needs_binding flag set by usb_resume_interface(). | 1097 | * Unbind all of @udev's marked interfaces and then rebind all of them. |
1098 | * This ordering is necessary because some drivers claim several interfaces | ||
1099 | * when they are first probed. | ||
1064 | * | 1100 | * |
1065 | * The caller must hold @udev's device lock. | 1101 | * The caller must hold @udev's device lock. |
1066 | */ | 1102 | */ |
1067 | static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) | 1103 | void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev) |
1068 | { | 1104 | { |
1069 | struct usb_host_config *config; | 1105 | unbind_marked_interfaces(udev); |
1070 | int i; | 1106 | rebind_marked_interfaces(udev); |
1071 | struct usb_interface *intf; | ||
1072 | |||
1073 | config = udev->actconfig; | ||
1074 | if (config) { | ||
1075 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | ||
1076 | intf = config->interface[i]; | ||
1077 | if (intf->dev.driver && intf->needs_binding) | ||
1078 | usb_forced_unbind_intf(intf); | ||
1079 | } | ||
1080 | } | ||
1081 | } | 1107 | } |
1082 | 1108 | ||
1083 | static void do_rebind_interfaces(struct usb_device *udev) | 1109 | #ifdef CONFIG_PM |
1110 | |||
1111 | /* Unbind drivers for @udev's interfaces that don't support suspend/resume | ||
1112 | * There is no check for reset_resume here because it can be determined | ||
1113 | * only during resume whether reset_resume is needed. | ||
1114 | * | ||
1115 | * The caller must hold @udev's device lock. | ||
1116 | */ | ||
1117 | static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) | ||
1084 | { | 1118 | { |
1085 | struct usb_host_config *config; | 1119 | struct usb_host_config *config; |
1086 | int i; | 1120 | int i; |
1087 | struct usb_interface *intf; | 1121 | struct usb_interface *intf; |
1122 | struct usb_driver *drv; | ||
1088 | 1123 | ||
1089 | config = udev->actconfig; | 1124 | config = udev->actconfig; |
1090 | if (config) { | 1125 | if (config) { |
1091 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { | 1126 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { |
1092 | intf = config->interface[i]; | 1127 | intf = config->interface[i]; |
1093 | if (intf->needs_binding) | 1128 | |
1094 | usb_rebind_intf(intf); | 1129 | if (intf->dev.driver) { |
1130 | drv = to_usb_driver(intf->dev.driver); | ||
1131 | if (!drv->suspend || !drv->resume) | ||
1132 | usb_forced_unbind_intf(intf); | ||
1133 | } | ||
1095 | } | 1134 | } |
1096 | } | 1135 | } |
1097 | } | 1136 | } |
@@ -1420,7 +1459,7 @@ int usb_resume_complete(struct device *dev) | |||
1420 | * whose needs_binding flag is set | 1459 | * whose needs_binding flag is set |
1421 | */ | 1460 | */ |
1422 | if (udev->state != USB_STATE_NOTATTACHED) | 1461 | if (udev->state != USB_STATE_NOTATTACHED) |
1423 | do_rebind_interfaces(udev); | 1462 | rebind_marked_interfaces(udev); |
1424 | return 0; | 1463 | return 0; |
1425 | } | 1464 | } |
1426 | 1465 | ||
@@ -1442,7 +1481,7 @@ int usb_resume(struct device *dev, pm_message_t msg) | |||
1442 | pm_runtime_disable(dev); | 1481 | pm_runtime_disable(dev); |
1443 | pm_runtime_set_active(dev); | 1482 | pm_runtime_set_active(dev); |
1444 | pm_runtime_enable(dev); | 1483 | pm_runtime_enable(dev); |
1445 | unbind_no_reset_resume_drivers_interfaces(udev); | 1484 | unbind_marked_interfaces(udev); |
1446 | } | 1485 | } |
1447 | 1486 | ||
1448 | /* Avoid PM error messages for devices disconnected while suspended | 1487 | /* Avoid PM error messages for devices disconnected while suspended |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 2518c3250750..9c4e2922b04d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -2049,7 +2049,7 @@ int usb_alloc_streams(struct usb_interface *interface, | |||
2049 | { | 2049 | { |
2050 | struct usb_hcd *hcd; | 2050 | struct usb_hcd *hcd; |
2051 | struct usb_device *dev; | 2051 | struct usb_device *dev; |
2052 | int i; | 2052 | int i, ret; |
2053 | 2053 | ||
2054 | dev = interface_to_usbdev(interface); | 2054 | dev = interface_to_usbdev(interface); |
2055 | hcd = bus_to_hcd(dev->bus); | 2055 | hcd = bus_to_hcd(dev->bus); |
@@ -2058,13 +2058,24 @@ int usb_alloc_streams(struct usb_interface *interface, | |||
2058 | if (dev->speed != USB_SPEED_SUPER) | 2058 | if (dev->speed != USB_SPEED_SUPER) |
2059 | return -EINVAL; | 2059 | return -EINVAL; |
2060 | 2060 | ||
2061 | /* Streams only apply to bulk endpoints. */ | 2061 | for (i = 0; i < num_eps; i++) { |
2062 | for (i = 0; i < num_eps; i++) | 2062 | /* Streams only apply to bulk endpoints. */ |
2063 | if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) | 2063 | if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) |
2064 | return -EINVAL; | 2064 | return -EINVAL; |
2065 | /* Re-alloc is not allowed */ | ||
2066 | if (eps[i]->streams) | ||
2067 | return -EINVAL; | ||
2068 | } | ||
2065 | 2069 | ||
2066 | return hcd->driver->alloc_streams(hcd, dev, eps, num_eps, | 2070 | ret = hcd->driver->alloc_streams(hcd, dev, eps, num_eps, |
2067 | num_streams, mem_flags); | 2071 | num_streams, mem_flags); |
2072 | if (ret < 0) | ||
2073 | return ret; | ||
2074 | |||
2075 | for (i = 0; i < num_eps; i++) | ||
2076 | eps[i]->streams = ret; | ||
2077 | |||
2078 | return ret; | ||
2068 | } | 2079 | } |
2069 | EXPORT_SYMBOL_GPL(usb_alloc_streams); | 2080 | EXPORT_SYMBOL_GPL(usb_alloc_streams); |
2070 | 2081 | ||
@@ -2078,8 +2089,7 @@ EXPORT_SYMBOL_GPL(usb_alloc_streams); | |||
2078 | * Reverts a group of bulk endpoints back to not using stream IDs. | 2089 | * Reverts a group of bulk endpoints back to not using stream IDs. |
2079 | * Can fail if we are given bad arguments, or HCD is broken. | 2090 | * Can fail if we are given bad arguments, or HCD is broken. |
2080 | * | 2091 | * |
2081 | * Return: On success, the number of allocated streams. On failure, a negative | 2092 | * Return: 0 on success. On failure, a negative error code. |
2082 | * error code. | ||
2083 | */ | 2093 | */ |
2084 | int usb_free_streams(struct usb_interface *interface, | 2094 | int usb_free_streams(struct usb_interface *interface, |
2085 | struct usb_host_endpoint **eps, unsigned int num_eps, | 2095 | struct usb_host_endpoint **eps, unsigned int num_eps, |
@@ -2087,19 +2097,26 @@ int usb_free_streams(struct usb_interface *interface, | |||
2087 | { | 2097 | { |
2088 | struct usb_hcd *hcd; | 2098 | struct usb_hcd *hcd; |
2089 | struct usb_device *dev; | 2099 | struct usb_device *dev; |
2090 | int i; | 2100 | int i, ret; |
2091 | 2101 | ||
2092 | dev = interface_to_usbdev(interface); | 2102 | dev = interface_to_usbdev(interface); |
2093 | hcd = bus_to_hcd(dev->bus); | 2103 | hcd = bus_to_hcd(dev->bus); |
2094 | if (dev->speed != USB_SPEED_SUPER) | 2104 | if (dev->speed != USB_SPEED_SUPER) |
2095 | return -EINVAL; | 2105 | return -EINVAL; |
2096 | 2106 | ||
2097 | /* Streams only apply to bulk endpoints. */ | 2107 | /* Double-free is not allowed */ |
2098 | for (i = 0; i < num_eps; i++) | 2108 | for (i = 0; i < num_eps; i++) |
2099 | if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc)) | 2109 | if (!eps[i] || !eps[i]->streams) |
2100 | return -EINVAL; | 2110 | return -EINVAL; |
2101 | 2111 | ||
2102 | return hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); | 2112 | ret = hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); |
2113 | if (ret < 0) | ||
2114 | return ret; | ||
2115 | |||
2116 | for (i = 0; i < num_eps; i++) | ||
2117 | eps[i]->streams = 0; | ||
2118 | |||
2119 | return ret; | ||
2103 | } | 2120 | } |
2104 | EXPORT_SYMBOL_GPL(usb_free_streams); | 2121 | EXPORT_SYMBOL_GPL(usb_free_streams); |
2105 | 2122 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 610735823d93..090469ebfcff 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -141,19 +141,27 @@ static int usb_device_supports_lpm(struct usb_device *udev) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* All USB 3.0 must support LPM, but we need their max exit latency | 144 | /* |
145 | * information from the SuperSpeed Extended Capabilities BOS descriptor. | 145 | * According to the USB 3.0 spec, all USB 3.0 devices must support LPM. |
146 | * However, there are some that don't, and they set the U1/U2 exit | ||
147 | * latencies to zero. | ||
146 | */ | 148 | */ |
147 | if (!udev->bos->ss_cap) { | 149 | if (!udev->bos->ss_cap) { |
148 | dev_warn(&udev->dev, "No LPM exit latency info found. " | 150 | dev_info(&udev->dev, "No LPM exit latency info found, disabling LPM.\n"); |
149 | "Power management will be impacted.\n"); | 151 | return 0; |
152 | } | ||
153 | |||
154 | if (udev->bos->ss_cap->bU1devExitLat == 0 && | ||
155 | udev->bos->ss_cap->bU2DevExitLat == 0) { | ||
156 | if (udev->parent) | ||
157 | dev_info(&udev->dev, "LPM exit latency is zeroed, disabling LPM.\n"); | ||
158 | else | ||
159 | dev_info(&udev->dev, "We don't know the algorithms for LPM for this host, disabling LPM.\n"); | ||
150 | return 0; | 160 | return 0; |
151 | } | 161 | } |
152 | if (udev->parent->lpm_capable) | ||
153 | return 1; | ||
154 | 162 | ||
155 | dev_warn(&udev->dev, "Parent hub missing LPM exit latency info. " | 163 | if (!udev->parent || udev->parent->lpm_capable) |
156 | "Power management will be impacted.\n"); | 164 | return 1; |
157 | return 0; | 165 | return 0; |
158 | } | 166 | } |
159 | 167 | ||
@@ -499,7 +507,8 @@ static void led_work (struct work_struct *work) | |||
499 | changed++; | 507 | changed++; |
500 | } | 508 | } |
501 | if (changed) | 509 | if (changed) |
502 | schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); | 510 | queue_delayed_work(system_power_efficient_wq, |
511 | &hub->leds, LED_CYCLE_PERIOD); | ||
503 | } | 512 | } |
504 | 513 | ||
505 | /* use a short timeout for hub/port status fetches */ | 514 | /* use a short timeout for hub/port status fetches */ |
@@ -1041,7 +1050,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1041 | if (type == HUB_INIT) { | 1050 | if (type == HUB_INIT) { |
1042 | delay = hub_power_on(hub, false); | 1051 | delay = hub_power_on(hub, false); |
1043 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func2); | 1052 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func2); |
1044 | schedule_delayed_work(&hub->init_work, | 1053 | queue_delayed_work(system_power_efficient_wq, |
1054 | &hub->init_work, | ||
1045 | msecs_to_jiffies(delay)); | 1055 | msecs_to_jiffies(delay)); |
1046 | 1056 | ||
1047 | /* Suppress autosuspend until init is done */ | 1057 | /* Suppress autosuspend until init is done */ |
@@ -1195,7 +1205,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1195 | /* Don't do a long sleep inside a workqueue routine */ | 1205 | /* Don't do a long sleep inside a workqueue routine */ |
1196 | if (type == HUB_INIT2) { | 1206 | if (type == HUB_INIT2) { |
1197 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func3); | 1207 | INIT_DELAYED_WORK(&hub->init_work, hub_init_func3); |
1198 | schedule_delayed_work(&hub->init_work, | 1208 | queue_delayed_work(system_power_efficient_wq, |
1209 | &hub->init_work, | ||
1199 | msecs_to_jiffies(delay)); | 1210 | msecs_to_jiffies(delay)); |
1200 | return; /* Continues at init3: below */ | 1211 | return; /* Continues at init3: below */ |
1201 | } else { | 1212 | } else { |
@@ -1209,7 +1220,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
1209 | if (status < 0) | 1220 | if (status < 0) |
1210 | dev_err(hub->intfdev, "activate --> %d\n", status); | 1221 | dev_err(hub->intfdev, "activate --> %d\n", status); |
1211 | if (hub->has_indicators && blinkenlights) | 1222 | if (hub->has_indicators && blinkenlights) |
1212 | schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); | 1223 | queue_delayed_work(system_power_efficient_wq, |
1224 | &hub->leds, LED_CYCLE_PERIOD); | ||
1213 | 1225 | ||
1214 | /* Scan all ports that need attention */ | 1226 | /* Scan all ports that need attention */ |
1215 | kick_khubd(hub); | 1227 | kick_khubd(hub); |
@@ -3095,9 +3107,19 @@ static int finish_port_resume(struct usb_device *udev) | |||
3095 | * operation is carried out here, after the port has been | 3107 | * operation is carried out here, after the port has been |
3096 | * resumed. | 3108 | * resumed. |
3097 | */ | 3109 | */ |
3098 | if (udev->reset_resume) | 3110 | if (udev->reset_resume) { |
3111 | /* | ||
3112 | * If the device morphs or switches modes when it is reset, | ||
3113 | * we don't want to perform a reset-resume. We'll fail the | ||
3114 | * resume, which will cause a logical disconnect, and then | ||
3115 | * the device will be rediscovered. | ||
3116 | */ | ||
3099 | retry_reset_resume: | 3117 | retry_reset_resume: |
3100 | status = usb_reset_and_verify_device(udev); | 3118 | if (udev->quirks & USB_QUIRK_RESET) |
3119 | status = -ENODEV; | ||
3120 | else | ||
3121 | status = usb_reset_and_verify_device(udev); | ||
3122 | } | ||
3101 | 3123 | ||
3102 | /* 10.5.4.5 says be sure devices in the tree are still there. | 3124 | /* 10.5.4.5 says be sure devices in the tree are still there. |
3103 | * For now let's assume the device didn't go crazy on resume, | 3125 | * For now let's assume the device didn't go crazy on resume, |
@@ -3960,7 +3982,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) | |||
3960 | connect_type = usb_get_hub_port_connect_type(udev->parent, | 3982 | connect_type = usb_get_hub_port_connect_type(udev->parent, |
3961 | udev->portnum); | 3983 | udev->portnum); |
3962 | 3984 | ||
3963 | if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) || | 3985 | if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || |
3964 | connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { | 3986 | connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { |
3965 | udev->usb2_hw_lpm_allowed = 1; | 3987 | udev->usb2_hw_lpm_allowed = 1; |
3966 | usb_set_usb2_hardware_lpm(udev, 1); | 3988 | usb_set_usb2_hardware_lpm(udev, 1); |
@@ -4109,8 +4131,12 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
4109 | 4131 | ||
4110 | did_new_scheme = true; | 4132 | did_new_scheme = true; |
4111 | retval = hub_enable_device(udev); | 4133 | retval = hub_enable_device(udev); |
4112 | if (retval < 0) | 4134 | if (retval < 0) { |
4135 | dev_err(&udev->dev, | ||
4136 | "hub failed to enable device, error %d\n", | ||
4137 | retval); | ||
4113 | goto fail; | 4138 | goto fail; |
4139 | } | ||
4114 | 4140 | ||
4115 | #define GET_DESCRIPTOR_BUFSIZE 64 | 4141 | #define GET_DESCRIPTOR_BUFSIZE 64 |
4116 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); | 4142 | buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); |
@@ -4313,7 +4339,8 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) | |||
4313 | /* hub LEDs are probably harder to miss than syslog */ | 4339 | /* hub LEDs are probably harder to miss than syslog */ |
4314 | if (hub->has_indicators) { | 4340 | if (hub->has_indicators) { |
4315 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; | 4341 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; |
4316 | schedule_delayed_work (&hub->leds, 0); | 4342 | queue_delayed_work(system_power_efficient_wq, |
4343 | &hub->leds, 0); | ||
4317 | } | 4344 | } |
4318 | } | 4345 | } |
4319 | kfree(qual); | 4346 | kfree(qual); |
@@ -4542,7 +4569,9 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
4542 | if (hub->has_indicators) { | 4569 | if (hub->has_indicators) { |
4543 | hub->indicator[port1-1] = | 4570 | hub->indicator[port1-1] = |
4544 | INDICATOR_AMBER_BLINK; | 4571 | INDICATOR_AMBER_BLINK; |
4545 | schedule_delayed_work (&hub->leds, 0); | 4572 | queue_delayed_work( |
4573 | system_power_efficient_wq, | ||
4574 | &hub->leds, 0); | ||
4546 | } | 4575 | } |
4547 | status = -ENOTCONN; /* Don't retry */ | 4576 | status = -ENOTCONN; /* Don't retry */ |
4548 | goto loop_disable; | 4577 | goto loop_disable; |
@@ -4741,6 +4770,8 @@ static void hub_events(void) | |||
4741 | 4770 | ||
4742 | /* deal with port status changes */ | 4771 | /* deal with port status changes */ |
4743 | for (i = 1; i <= hdev->maxchild; i++) { | 4772 | for (i = 1; i <= hdev->maxchild; i++) { |
4773 | struct usb_device *udev = hub->ports[i - 1]->child; | ||
4774 | |||
4744 | if (test_bit(i, hub->busy_bits)) | 4775 | if (test_bit(i, hub->busy_bits)) |
4745 | continue; | 4776 | continue; |
4746 | connect_change = test_bit(i, hub->change_bits); | 4777 | connect_change = test_bit(i, hub->change_bits); |
@@ -4839,8 +4870,6 @@ static void hub_events(void) | |||
4839 | */ | 4870 | */ |
4840 | if (hub_port_warm_reset_required(hub, portstatus)) { | 4871 | if (hub_port_warm_reset_required(hub, portstatus)) { |
4841 | int status; | 4872 | int status; |
4842 | struct usb_device *udev = | ||
4843 | hub->ports[i - 1]->child; | ||
4844 | 4873 | ||
4845 | dev_dbg(hub_dev, "warm reset port %d\n", i); | 4874 | dev_dbg(hub_dev, "warm reset port %d\n", i); |
4846 | if (!udev || | 4875 | if (!udev || |
@@ -4857,6 +4886,24 @@ static void hub_events(void) | |||
4857 | usb_unlock_device(udev); | 4886 | usb_unlock_device(udev); |
4858 | connect_change = 0; | 4887 | connect_change = 0; |
4859 | } | 4888 | } |
4889 | /* | ||
4890 | * On disconnect USB3 protocol ports transit from U0 to | ||
4891 | * SS.Inactive to Rx.Detect. If this happens a warm- | ||
4892 | * reset is not needed, but a (re)connect may happen | ||
4893 | * before khubd runs and sees the disconnect, and the | ||
4894 | * device may be an unknown state. | ||
4895 | * | ||
4896 | * If the port went through SS.Inactive without khubd | ||
4897 | * seeing it the C_LINK_STATE change flag will be set, | ||
4898 | * and we reset the dev to put it in a known state. | ||
4899 | */ | ||
4900 | } else if (udev && hub_is_superspeed(hub->hdev) && | ||
4901 | (portchange & USB_PORT_STAT_C_LINK_STATE) && | ||
4902 | (portstatus & USB_PORT_STAT_CONNECTION)) { | ||
4903 | usb_lock_device(udev); | ||
4904 | usb_reset_device(udev); | ||
4905 | usb_unlock_device(udev); | ||
4906 | connect_change = 0; | ||
4860 | } | 4907 | } |
4861 | 4908 | ||
4862 | if (connect_change) | 4909 | if (connect_change) |
@@ -5114,7 +5161,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
5114 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | 5161 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); |
5115 | struct usb_device_descriptor descriptor = udev->descriptor; | 5162 | struct usb_device_descriptor descriptor = udev->descriptor; |
5116 | struct usb_host_bos *bos; | 5163 | struct usb_host_bos *bos; |
5117 | int i, ret = 0; | 5164 | int i, j, ret = 0; |
5118 | int port1 = udev->portnum; | 5165 | int port1 = udev->portnum; |
5119 | 5166 | ||
5120 | if (udev->state == USB_STATE_NOTATTACHED || | 5167 | if (udev->state == USB_STATE_NOTATTACHED || |
@@ -5240,6 +5287,9 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
5240 | ret); | 5287 | ret); |
5241 | goto re_enumerate; | 5288 | goto re_enumerate; |
5242 | } | 5289 | } |
5290 | /* Resetting also frees any allocated streams */ | ||
5291 | for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) | ||
5292 | intf->cur_altsetting->endpoint[j].streams = 0; | ||
5243 | } | 5293 | } |
5244 | 5294 | ||
5245 | done: | 5295 | done: |
@@ -5342,10 +5392,11 @@ int usb_reset_device(struct usb_device *udev) | |||
5342 | else if (cintf->condition == | 5392 | else if (cintf->condition == |
5343 | USB_INTERFACE_BOUND) | 5393 | USB_INTERFACE_BOUND) |
5344 | rebind = 1; | 5394 | rebind = 1; |
5395 | if (rebind) | ||
5396 | cintf->needs_binding = 1; | ||
5345 | } | 5397 | } |
5346 | if (ret == 0 && rebind) | ||
5347 | usb_rebind_intf(cintf); | ||
5348 | } | 5398 | } |
5399 | usb_unbind_and_rebind_marked_interfaces(udev); | ||
5349 | } | 5400 | } |
5350 | 5401 | ||
5351 | usb_autosuspend_device(udev); | 5402 | usb_autosuspend_device(udev); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 08d95e9d56c2..3cdcd0a2c0b7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1293,8 +1293,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1293 | struct usb_interface *iface; | 1293 | struct usb_interface *iface; |
1294 | struct usb_host_interface *alt; | 1294 | struct usb_host_interface *alt; |
1295 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); | 1295 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); |
1296 | int ret; | 1296 | int i, ret, manual = 0; |
1297 | int manual = 0; | ||
1298 | unsigned int epaddr; | 1297 | unsigned int epaddr; |
1299 | unsigned int pipe; | 1298 | unsigned int pipe; |
1300 | 1299 | ||
@@ -1329,6 +1328,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1329 | mutex_unlock(hcd->bandwidth_mutex); | 1328 | mutex_unlock(hcd->bandwidth_mutex); |
1330 | return -ENOMEM; | 1329 | return -ENOMEM; |
1331 | } | 1330 | } |
1331 | /* Changing alt-setting also frees any allocated streams */ | ||
1332 | for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++) | ||
1333 | iface->cur_altsetting->endpoint[i].streams = 0; | ||
1334 | |||
1332 | ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); | 1335 | ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); |
1333 | if (ret < 0) { | 1336 | if (ret < 0) { |
1334 | dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", | 1337 | dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index a87532845bf9..75bf649da82d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -55,7 +55,7 @@ extern int usb_match_one_id_intf(struct usb_device *dev, | |||
55 | extern int usb_match_device(struct usb_device *dev, | 55 | extern int usb_match_device(struct usb_device *dev, |
56 | const struct usb_device_id *id); | 56 | const struct usb_device_id *id); |
57 | extern void usb_forced_unbind_intf(struct usb_interface *intf); | 57 | extern void usb_forced_unbind_intf(struct usb_interface *intf); |
58 | extern void usb_rebind_intf(struct usb_interface *intf); | 58 | extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev); |
59 | 59 | ||
60 | extern void usb_hub_release_all_ports(struct usb_device *hdev, | 60 | extern void usb_hub_release_all_ports(struct usb_device *hdev, |
61 | struct usb_dev_state *owner); | 61 | struct usb_dev_state *owner); |
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 8205799e6db3..c93918b70d03 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c | |||
@@ -72,6 +72,26 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * dwc2_handle_usb_port_intr - handles OTG PRTINT interrupts. | ||
76 | * When the PRTINT interrupt fires, there are certain status bits in the Host | ||
77 | * Port that needs to get cleared. | ||
78 | * | ||
79 | * @hsotg: Programming view of DWC_otg controller | ||
80 | */ | ||
81 | static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) | ||
82 | { | ||
83 | u32 hprt0 = readl(hsotg->regs + HPRT0); | ||
84 | |||
85 | if (hprt0 & HPRT0_ENACHG) { | ||
86 | hprt0 &= ~HPRT0_ENA; | ||
87 | writel(hprt0, hsotg->regs + HPRT0); | ||
88 | } | ||
89 | |||
90 | /* Clear interrupt */ | ||
91 | writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); | ||
92 | } | ||
93 | |||
94 | /** | ||
75 | * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message | 95 | * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message |
76 | * | 96 | * |
77 | * @hsotg: Programming view of DWC_otg controller | 97 | * @hsotg: Programming view of DWC_otg controller |
@@ -479,9 +499,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |||
479 | if (dwc2_is_device_mode(hsotg)) { | 499 | if (dwc2_is_device_mode(hsotg)) { |
480 | dev_dbg(hsotg->dev, | 500 | dev_dbg(hsotg->dev, |
481 | " --Port interrupt received in Device mode--\n"); | 501 | " --Port interrupt received in Device mode--\n"); |
482 | gintsts = GINTSTS_PRTINT; | 502 | dwc2_handle_usb_port_intr(hsotg); |
483 | writel(gintsts, hsotg->regs + GINTSTS); | 503 | retval = IRQ_HANDLED; |
484 | retval = 1; | ||
485 | } | 504 | } |
486 | } | 505 | } |
487 | 506 | ||
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 012f17ec1a37..47b9eb5389b4 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c | |||
@@ -975,8 +975,8 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, | |||
975 | struct dwc2_qtd *qtd) | 975 | struct dwc2_qtd *qtd) |
976 | { | 976 | { |
977 | struct dwc2_hcd_urb *urb = qtd->urb; | 977 | struct dwc2_hcd_urb *urb = qtd->urb; |
978 | int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); | ||
979 | enum dwc2_halt_status halt_status = DWC2_HC_XFER_COMPLETE; | 978 | enum dwc2_halt_status halt_status = DWC2_HC_XFER_COMPLETE; |
979 | int pipe_type; | ||
980 | int urb_xfer_done; | 980 | int urb_xfer_done; |
981 | 981 | ||
982 | if (dbg_hc(chan)) | 982 | if (dbg_hc(chan)) |
@@ -984,6 +984,11 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, | |||
984 | "--Host Channel %d Interrupt: Transfer Complete--\n", | 984 | "--Host Channel %d Interrupt: Transfer Complete--\n", |
985 | chnum); | 985 | chnum); |
986 | 986 | ||
987 | if (!urb) | ||
988 | goto handle_xfercomp_done; | ||
989 | |||
990 | pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); | ||
991 | |||
987 | if (hsotg->core_params->dma_desc_enable > 0) { | 992 | if (hsotg->core_params->dma_desc_enable > 0) { |
988 | dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status); | 993 | dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status); |
989 | if (pipe_type == USB_ENDPOINT_XFER_ISOC) | 994 | if (pipe_type == USB_ENDPOINT_XFER_ISOC) |
@@ -1005,9 +1010,6 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, | |||
1005 | } | 1010 | } |
1006 | } | 1011 | } |
1007 | 1012 | ||
1008 | if (!urb) | ||
1009 | goto handle_xfercomp_done; | ||
1010 | |||
1011 | /* Update the QTD and URB states */ | 1013 | /* Update the QTD and URB states */ |
1012 | switch (pipe_type) { | 1014 | switch (pipe_type) { |
1013 | case USB_ENDPOINT_XFER_CONTROL: | 1015 | case USB_ENDPOINT_XFER_CONTROL: |
@@ -1105,7 +1107,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, | |||
1105 | struct dwc2_qtd *qtd) | 1107 | struct dwc2_qtd *qtd) |
1106 | { | 1108 | { |
1107 | struct dwc2_hcd_urb *urb = qtd->urb; | 1109 | struct dwc2_hcd_urb *urb = qtd->urb; |
1108 | int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); | 1110 | int pipe_type; |
1109 | 1111 | ||
1110 | dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n", | 1112 | dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n", |
1111 | chnum); | 1113 | chnum); |
@@ -1119,6 +1121,8 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, | |||
1119 | if (!urb) | 1121 | if (!urb) |
1120 | goto handle_stall_halt; | 1122 | goto handle_stall_halt; |
1121 | 1123 | ||
1124 | pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); | ||
1125 | |||
1122 | if (pipe_type == USB_ENDPOINT_XFER_CONTROL) | 1126 | if (pipe_type == USB_ENDPOINT_XFER_CONTROL) |
1123 | dwc2_host_complete(hsotg, qtd, -EPIPE); | 1127 | dwc2_host_complete(hsotg, qtd, -EPIPE); |
1124 | 1128 | ||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a49217ae3533..d001417e8e37 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -61,9 +61,10 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode) | |||
61 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset | 61 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset |
62 | * @dwc: pointer to our context structure | 62 | * @dwc: pointer to our context structure |
63 | */ | 63 | */ |
64 | static void dwc3_core_soft_reset(struct dwc3 *dwc) | 64 | static int dwc3_core_soft_reset(struct dwc3 *dwc) |
65 | { | 65 | { |
66 | u32 reg; | 66 | u32 reg; |
67 | int ret; | ||
67 | 68 | ||
68 | /* Before Resetting PHY, put Core in Reset */ | 69 | /* Before Resetting PHY, put Core in Reset */ |
69 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | 70 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
@@ -82,6 +83,15 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc) | |||
82 | 83 | ||
83 | usb_phy_init(dwc->usb2_phy); | 84 | usb_phy_init(dwc->usb2_phy); |
84 | usb_phy_init(dwc->usb3_phy); | 85 | usb_phy_init(dwc->usb3_phy); |
86 | ret = phy_init(dwc->usb2_generic_phy); | ||
87 | if (ret < 0) | ||
88 | return ret; | ||
89 | |||
90 | ret = phy_init(dwc->usb3_generic_phy); | ||
91 | if (ret < 0) { | ||
92 | phy_exit(dwc->usb2_generic_phy); | ||
93 | return ret; | ||
94 | } | ||
85 | mdelay(100); | 95 | mdelay(100); |
86 | 96 | ||
87 | /* Clear USB3 PHY reset */ | 97 | /* Clear USB3 PHY reset */ |
@@ -100,6 +110,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc) | |||
100 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | 110 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
101 | reg &= ~DWC3_GCTL_CORESOFTRESET; | 111 | reg &= ~DWC3_GCTL_CORESOFTRESET; |
102 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 112 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
113 | |||
114 | return 0; | ||
103 | } | 115 | } |
104 | 116 | ||
105 | /** | 117 | /** |
@@ -242,6 +254,90 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) | |||
242 | } | 254 | } |
243 | } | 255 | } |
244 | 256 | ||
257 | static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc) | ||
258 | { | ||
259 | if (!dwc->has_hibernation) | ||
260 | return 0; | ||
261 | |||
262 | if (!dwc->nr_scratch) | ||
263 | return 0; | ||
264 | |||
265 | dwc->scratchbuf = kmalloc_array(dwc->nr_scratch, | ||
266 | DWC3_SCRATCHBUF_SIZE, GFP_KERNEL); | ||
267 | if (!dwc->scratchbuf) | ||
268 | return -ENOMEM; | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int dwc3_setup_scratch_buffers(struct dwc3 *dwc) | ||
274 | { | ||
275 | dma_addr_t scratch_addr; | ||
276 | u32 param; | ||
277 | int ret; | ||
278 | |||
279 | if (!dwc->has_hibernation) | ||
280 | return 0; | ||
281 | |||
282 | if (!dwc->nr_scratch) | ||
283 | return 0; | ||
284 | |||
285 | /* should never fall here */ | ||
286 | if (!WARN_ON(dwc->scratchbuf)) | ||
287 | return 0; | ||
288 | |||
289 | scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf, | ||
290 | dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE, | ||
291 | DMA_BIDIRECTIONAL); | ||
292 | if (dma_mapping_error(dwc->dev, scratch_addr)) { | ||
293 | dev_err(dwc->dev, "failed to map scratch buffer\n"); | ||
294 | ret = -EFAULT; | ||
295 | goto err0; | ||
296 | } | ||
297 | |||
298 | dwc->scratch_addr = scratch_addr; | ||
299 | |||
300 | param = lower_32_bits(scratch_addr); | ||
301 | |||
302 | ret = dwc3_send_gadget_generic_command(dwc, | ||
303 | DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO, param); | ||
304 | if (ret < 0) | ||
305 | goto err1; | ||
306 | |||
307 | param = upper_32_bits(scratch_addr); | ||
308 | |||
309 | ret = dwc3_send_gadget_generic_command(dwc, | ||
310 | DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI, param); | ||
311 | if (ret < 0) | ||
312 | goto err1; | ||
313 | |||
314 | return 0; | ||
315 | |||
316 | err1: | ||
317 | dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch * | ||
318 | DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL); | ||
319 | |||
320 | err0: | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | static void dwc3_free_scratch_buffers(struct dwc3 *dwc) | ||
325 | { | ||
326 | if (!dwc->has_hibernation) | ||
327 | return; | ||
328 | |||
329 | if (!dwc->nr_scratch) | ||
330 | return; | ||
331 | |||
332 | /* should never fall here */ | ||
333 | if (!WARN_ON(dwc->scratchbuf)) | ||
334 | return; | ||
335 | |||
336 | dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch * | ||
337 | DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL); | ||
338 | kfree(dwc->scratchbuf); | ||
339 | } | ||
340 | |||
245 | static void dwc3_core_num_eps(struct dwc3 *dwc) | 341 | static void dwc3_core_num_eps(struct dwc3 *dwc) |
246 | { | 342 | { |
247 | struct dwc3_hwparams *parms = &dwc->hwparams; | 343 | struct dwc3_hwparams *parms = &dwc->hwparams; |
@@ -277,6 +373,7 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) | |||
277 | static int dwc3_core_init(struct dwc3 *dwc) | 373 | static int dwc3_core_init(struct dwc3 *dwc) |
278 | { | 374 | { |
279 | unsigned long timeout; | 375 | unsigned long timeout; |
376 | u32 hwparams4 = dwc->hwparams.hwparams4; | ||
280 | u32 reg; | 377 | u32 reg; |
281 | int ret; | 378 | int ret; |
282 | 379 | ||
@@ -306,7 +403,9 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
306 | cpu_relax(); | 403 | cpu_relax(); |
307 | } while (true); | 404 | } while (true); |
308 | 405 | ||
309 | dwc3_core_soft_reset(dwc); | 406 | ret = dwc3_core_soft_reset(dwc); |
407 | if (ret) | ||
408 | goto err0; | ||
310 | 409 | ||
311 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | 410 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
312 | reg &= ~DWC3_GCTL_SCALEDOWN_MASK; | 411 | reg &= ~DWC3_GCTL_SCALEDOWN_MASK; |
@@ -314,7 +413,29 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
314 | 413 | ||
315 | switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { | 414 | switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { |
316 | case DWC3_GHWPARAMS1_EN_PWROPT_CLK: | 415 | case DWC3_GHWPARAMS1_EN_PWROPT_CLK: |
317 | reg &= ~DWC3_GCTL_DSBLCLKGTNG; | 416 | /** |
417 | * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an | ||
418 | * issue which would cause xHCI compliance tests to fail. | ||
419 | * | ||
420 | * Because of that we cannot enable clock gating on such | ||
421 | * configurations. | ||
422 | * | ||
423 | * Refers to: | ||
424 | * | ||
425 | * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based | ||
426 | * SOF/ITP Mode Used | ||
427 | */ | ||
428 | if ((dwc->dr_mode == USB_DR_MODE_HOST || | ||
429 | dwc->dr_mode == USB_DR_MODE_OTG) && | ||
430 | (dwc->revision >= DWC3_REVISION_210A && | ||
431 | dwc->revision <= DWC3_REVISION_250A)) | ||
432 | reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; | ||
433 | else | ||
434 | reg &= ~DWC3_GCTL_DSBLCLKGTNG; | ||
435 | break; | ||
436 | case DWC3_GHWPARAMS1_EN_PWROPT_HIB: | ||
437 | /* enable hibernation here */ | ||
438 | dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); | ||
318 | break; | 439 | break; |
319 | default: | 440 | default: |
320 | dev_dbg(dwc->dev, "No power optimization available\n"); | 441 | dev_dbg(dwc->dev, "No power optimization available\n"); |
@@ -333,16 +454,36 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
333 | 454 | ||
334 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 455 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
335 | 456 | ||
457 | ret = dwc3_alloc_scratch_buffers(dwc); | ||
458 | if (ret) | ||
459 | goto err1; | ||
460 | |||
461 | ret = dwc3_setup_scratch_buffers(dwc); | ||
462 | if (ret) | ||
463 | goto err2; | ||
464 | |||
336 | return 0; | 465 | return 0; |
337 | 466 | ||
467 | err2: | ||
468 | dwc3_free_scratch_buffers(dwc); | ||
469 | |||
470 | err1: | ||
471 | usb_phy_shutdown(dwc->usb2_phy); | ||
472 | usb_phy_shutdown(dwc->usb3_phy); | ||
473 | phy_exit(dwc->usb2_generic_phy); | ||
474 | phy_exit(dwc->usb3_generic_phy); | ||
475 | |||
338 | err0: | 476 | err0: |
339 | return ret; | 477 | return ret; |
340 | } | 478 | } |
341 | 479 | ||
342 | static void dwc3_core_exit(struct dwc3 *dwc) | 480 | static void dwc3_core_exit(struct dwc3 *dwc) |
343 | { | 481 | { |
482 | dwc3_free_scratch_buffers(dwc); | ||
344 | usb_phy_shutdown(dwc->usb2_phy); | 483 | usb_phy_shutdown(dwc->usb2_phy); |
345 | usb_phy_shutdown(dwc->usb3_phy); | 484 | usb_phy_shutdown(dwc->usb3_phy); |
485 | phy_exit(dwc->usb2_generic_phy); | ||
486 | phy_exit(dwc->usb3_generic_phy); | ||
346 | } | 487 | } |
347 | 488 | ||
348 | #define DWC3_ALIGN_MASK (16 - 1) | 489 | #define DWC3_ALIGN_MASK (16 - 1) |
@@ -411,32 +552,52 @@ static int dwc3_probe(struct platform_device *pdev) | |||
411 | 552 | ||
412 | if (IS_ERR(dwc->usb2_phy)) { | 553 | if (IS_ERR(dwc->usb2_phy)) { |
413 | ret = PTR_ERR(dwc->usb2_phy); | 554 | ret = PTR_ERR(dwc->usb2_phy); |
414 | 555 | if (ret == -ENXIO || ret == -ENODEV) { | |
415 | /* | 556 | dwc->usb2_phy = NULL; |
416 | * if -ENXIO is returned, it means PHY layer wasn't | 557 | } else if (ret == -EPROBE_DEFER) { |
417 | * enabled, so it makes no sense to return -EPROBE_DEFER | ||
418 | * in that case, since no PHY driver will ever probe. | ||
419 | */ | ||
420 | if (ret == -ENXIO) | ||
421 | return ret; | 558 | return ret; |
422 | 559 | } else { | |
423 | dev_err(dev, "no usb2 phy configured\n"); | 560 | dev_err(dev, "no usb2 phy configured\n"); |
424 | return -EPROBE_DEFER; | 561 | return ret; |
562 | } | ||
425 | } | 563 | } |
426 | 564 | ||
427 | if (IS_ERR(dwc->usb3_phy)) { | 565 | if (IS_ERR(dwc->usb3_phy)) { |
428 | ret = PTR_ERR(dwc->usb3_phy); | 566 | ret = PTR_ERR(dwc->usb3_phy); |
567 | if (ret == -ENXIO || ret == -ENODEV) { | ||
568 | dwc->usb3_phy = NULL; | ||
569 | } else if (ret == -EPROBE_DEFER) { | ||
570 | return ret; | ||
571 | } else { | ||
572 | dev_err(dev, "no usb3 phy configured\n"); | ||
573 | return ret; | ||
574 | } | ||
575 | } | ||
429 | 576 | ||
430 | /* | 577 | dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); |
431 | * if -ENXIO is returned, it means PHY layer wasn't | 578 | if (IS_ERR(dwc->usb2_generic_phy)) { |
432 | * enabled, so it makes no sense to return -EPROBE_DEFER | 579 | ret = PTR_ERR(dwc->usb2_generic_phy); |
433 | * in that case, since no PHY driver will ever probe. | 580 | if (ret == -ENOSYS || ret == -ENODEV) { |
434 | */ | 581 | dwc->usb2_generic_phy = NULL; |
435 | if (ret == -ENXIO) | 582 | } else if (ret == -EPROBE_DEFER) { |
583 | return ret; | ||
584 | } else { | ||
585 | dev_err(dev, "no usb2 phy configured\n"); | ||
436 | return ret; | 586 | return ret; |
587 | } | ||
588 | } | ||
437 | 589 | ||
438 | dev_err(dev, "no usb3 phy configured\n"); | 590 | dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); |
439 | return -EPROBE_DEFER; | 591 | if (IS_ERR(dwc->usb3_generic_phy)) { |
592 | ret = PTR_ERR(dwc->usb3_generic_phy); | ||
593 | if (ret == -ENOSYS || ret == -ENODEV) { | ||
594 | dwc->usb3_generic_phy = NULL; | ||
595 | } else if (ret == -EPROBE_DEFER) { | ||
596 | return ret; | ||
597 | } else { | ||
598 | dev_err(dev, "no usb3 phy configured\n"); | ||
599 | return ret; | ||
600 | } | ||
440 | } | 601 | } |
441 | 602 | ||
442 | dwc->xhci_resources[0].start = res->start; | 603 | dwc->xhci_resources[0].start = res->start; |
@@ -479,6 +640,14 @@ static int dwc3_probe(struct platform_device *pdev) | |||
479 | goto err0; | 640 | goto err0; |
480 | } | 641 | } |
481 | 642 | ||
643 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) | ||
644 | dwc->dr_mode = USB_DR_MODE_HOST; | ||
645 | else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) | ||
646 | dwc->dr_mode = USB_DR_MODE_PERIPHERAL; | ||
647 | |||
648 | if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) | ||
649 | dwc->dr_mode = USB_DR_MODE_OTG; | ||
650 | |||
482 | ret = dwc3_core_init(dwc); | 651 | ret = dwc3_core_init(dwc); |
483 | if (ret) { | 652 | if (ret) { |
484 | dev_err(dev, "failed to initialize core\n"); | 653 | dev_err(dev, "failed to initialize core\n"); |
@@ -487,21 +656,20 @@ static int dwc3_probe(struct platform_device *pdev) | |||
487 | 656 | ||
488 | usb_phy_set_suspend(dwc->usb2_phy, 0); | 657 | usb_phy_set_suspend(dwc->usb2_phy, 0); |
489 | usb_phy_set_suspend(dwc->usb3_phy, 0); | 658 | usb_phy_set_suspend(dwc->usb3_phy, 0); |
659 | ret = phy_power_on(dwc->usb2_generic_phy); | ||
660 | if (ret < 0) | ||
661 | goto err1; | ||
662 | |||
663 | ret = phy_power_on(dwc->usb3_generic_phy); | ||
664 | if (ret < 0) | ||
665 | goto err_usb2phy_power; | ||
490 | 666 | ||
491 | ret = dwc3_event_buffers_setup(dwc); | 667 | ret = dwc3_event_buffers_setup(dwc); |
492 | if (ret) { | 668 | if (ret) { |
493 | dev_err(dwc->dev, "failed to setup event buffers\n"); | 669 | dev_err(dwc->dev, "failed to setup event buffers\n"); |
494 | goto err1; | 670 | goto err_usb3phy_power; |
495 | } | 671 | } |
496 | 672 | ||
497 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) | ||
498 | dwc->dr_mode = USB_DR_MODE_HOST; | ||
499 | else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) | ||
500 | dwc->dr_mode = USB_DR_MODE_PERIPHERAL; | ||
501 | |||
502 | if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) | ||
503 | dwc->dr_mode = USB_DR_MODE_OTG; | ||
504 | |||
505 | switch (dwc->dr_mode) { | 673 | switch (dwc->dr_mode) { |
506 | case USB_DR_MODE_PERIPHERAL: | 674 | case USB_DR_MODE_PERIPHERAL: |
507 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); | 675 | dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); |
@@ -568,6 +736,12 @@ err3: | |||
568 | err2: | 736 | err2: |
569 | dwc3_event_buffers_cleanup(dwc); | 737 | dwc3_event_buffers_cleanup(dwc); |
570 | 738 | ||
739 | err_usb3phy_power: | ||
740 | phy_power_off(dwc->usb3_generic_phy); | ||
741 | |||
742 | err_usb2phy_power: | ||
743 | phy_power_off(dwc->usb2_generic_phy); | ||
744 | |||
571 | err1: | 745 | err1: |
572 | usb_phy_set_suspend(dwc->usb2_phy, 1); | 746 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
573 | usb_phy_set_suspend(dwc->usb3_phy, 1); | 747 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
@@ -585,6 +759,8 @@ static int dwc3_remove(struct platform_device *pdev) | |||
585 | 759 | ||
586 | usb_phy_set_suspend(dwc->usb2_phy, 1); | 760 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
587 | usb_phy_set_suspend(dwc->usb3_phy, 1); | 761 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
762 | phy_power_off(dwc->usb2_generic_phy); | ||
763 | phy_power_off(dwc->usb3_generic_phy); | ||
588 | 764 | ||
589 | pm_runtime_put_sync(&pdev->dev); | 765 | pm_runtime_put_sync(&pdev->dev); |
590 | pm_runtime_disable(&pdev->dev); | 766 | pm_runtime_disable(&pdev->dev); |
@@ -682,6 +858,8 @@ static int dwc3_suspend(struct device *dev) | |||
682 | 858 | ||
683 | usb_phy_shutdown(dwc->usb3_phy); | 859 | usb_phy_shutdown(dwc->usb3_phy); |
684 | usb_phy_shutdown(dwc->usb2_phy); | 860 | usb_phy_shutdown(dwc->usb2_phy); |
861 | phy_exit(dwc->usb2_generic_phy); | ||
862 | phy_exit(dwc->usb3_generic_phy); | ||
685 | 863 | ||
686 | return 0; | 864 | return 0; |
687 | } | 865 | } |
@@ -690,9 +868,17 @@ static int dwc3_resume(struct device *dev) | |||
690 | { | 868 | { |
691 | struct dwc3 *dwc = dev_get_drvdata(dev); | 869 | struct dwc3 *dwc = dev_get_drvdata(dev); |
692 | unsigned long flags; | 870 | unsigned long flags; |
871 | int ret; | ||
693 | 872 | ||
694 | usb_phy_init(dwc->usb3_phy); | 873 | usb_phy_init(dwc->usb3_phy); |
695 | usb_phy_init(dwc->usb2_phy); | 874 | usb_phy_init(dwc->usb2_phy); |
875 | ret = phy_init(dwc->usb2_generic_phy); | ||
876 | if (ret < 0) | ||
877 | return ret; | ||
878 | |||
879 | ret = phy_init(dwc->usb3_generic_phy); | ||
880 | if (ret < 0) | ||
881 | goto err_usb2phy_init; | ||
696 | 882 | ||
697 | spin_lock_irqsave(&dwc->lock, flags); | 883 | spin_lock_irqsave(&dwc->lock, flags); |
698 | 884 | ||
@@ -716,6 +902,11 @@ static int dwc3_resume(struct device *dev) | |||
716 | pm_runtime_enable(dev); | 902 | pm_runtime_enable(dev); |
717 | 903 | ||
718 | return 0; | 904 | return 0; |
905 | |||
906 | err_usb2phy_init: | ||
907 | phy_exit(dwc->usb2_generic_phy); | ||
908 | |||
909 | return ret; | ||
719 | } | 910 | } |
720 | 911 | ||
721 | static const struct dev_pm_ops dwc3_dev_pm_ops = { | 912 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f8af8d44af85..57332e3768e4 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -31,11 +31,14 @@ | |||
31 | #include <linux/usb/gadget.h> | 31 | #include <linux/usb/gadget.h> |
32 | #include <linux/usb/otg.h> | 32 | #include <linux/usb/otg.h> |
33 | 33 | ||
34 | #include <linux/phy/phy.h> | ||
35 | |||
34 | /* Global constants */ | 36 | /* Global constants */ |
35 | #define DWC3_EP0_BOUNCE_SIZE 512 | 37 | #define DWC3_EP0_BOUNCE_SIZE 512 |
36 | #define DWC3_ENDPOINTS_NUM 32 | 38 | #define DWC3_ENDPOINTS_NUM 32 |
37 | #define DWC3_XHCI_RESOURCES_NUM 2 | 39 | #define DWC3_XHCI_RESOURCES_NUM 2 |
38 | 40 | ||
41 | #define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */ | ||
39 | #define DWC3_EVENT_SIZE 4 /* bytes */ | 42 | #define DWC3_EVENT_SIZE 4 /* bytes */ |
40 | #define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ | 43 | #define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */ |
41 | #define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) | 44 | #define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM) |
@@ -157,6 +160,7 @@ | |||
157 | #define DWC3_GCTL_PRTCAP_OTG 3 | 160 | #define DWC3_GCTL_PRTCAP_OTG 3 |
158 | 161 | ||
159 | #define DWC3_GCTL_CORESOFTRESET (1 << 11) | 162 | #define DWC3_GCTL_CORESOFTRESET (1 << 11) |
163 | #define DWC3_GCTL_SOFITPSYNC (1 << 10) | ||
160 | #define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) | 164 | #define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) |
161 | #define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) | 165 | #define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) |
162 | #define DWC3_GCTL_DISSCRAMBLE (1 << 3) | 166 | #define DWC3_GCTL_DISSCRAMBLE (1 << 3) |
@@ -318,7 +322,7 @@ | |||
318 | /* Device Endpoint Command Register */ | 322 | /* Device Endpoint Command Register */ |
319 | #define DWC3_DEPCMD_PARAM_SHIFT 16 | 323 | #define DWC3_DEPCMD_PARAM_SHIFT 16 |
320 | #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) | 324 | #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) |
321 | #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) | 325 | #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) |
322 | #define DWC3_DEPCMD_STATUS(x) (((x) >> 15) & 1) | 326 | #define DWC3_DEPCMD_STATUS(x) (((x) >> 15) & 1) |
323 | #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) | 327 | #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) |
324 | #define DWC3_DEPCMD_CMDACT (1 << 10) | 328 | #define DWC3_DEPCMD_CMDACT (1 << 10) |
@@ -393,6 +397,7 @@ struct dwc3_event_buffer { | |||
393 | * @busy_slot: first slot which is owned by HW | 397 | * @busy_slot: first slot which is owned by HW |
394 | * @desc: usb_endpoint_descriptor pointer | 398 | * @desc: usb_endpoint_descriptor pointer |
395 | * @dwc: pointer to DWC controller | 399 | * @dwc: pointer to DWC controller |
400 | * @saved_state: ep state saved during hibernation | ||
396 | * @flags: endpoint flags (wedged, stalled, ...) | 401 | * @flags: endpoint flags (wedged, stalled, ...) |
397 | * @current_trb: index of current used trb | 402 | * @current_trb: index of current used trb |
398 | * @number: endpoint number (1 - 15) | 403 | * @number: endpoint number (1 - 15) |
@@ -415,6 +420,7 @@ struct dwc3_ep { | |||
415 | const struct usb_ss_ep_comp_descriptor *comp_desc; | 420 | const struct usb_ss_ep_comp_descriptor *comp_desc; |
416 | struct dwc3 *dwc; | 421 | struct dwc3 *dwc; |
417 | 422 | ||
423 | u32 saved_state; | ||
418 | unsigned flags; | 424 | unsigned flags; |
419 | #define DWC3_EP_ENABLED (1 << 0) | 425 | #define DWC3_EP_ENABLED (1 << 0) |
420 | #define DWC3_EP_STALL (1 << 1) | 426 | #define DWC3_EP_STALL (1 << 1) |
@@ -598,6 +604,7 @@ struct dwc3_scratchpad_array { | |||
598 | * @ep0_trb: dma address of ep0_trb | 604 | * @ep0_trb: dma address of ep0_trb |
599 | * @ep0_usb_req: dummy req used while handling STD USB requests | 605 | * @ep0_usb_req: dummy req used while handling STD USB requests |
600 | * @ep0_bounce_addr: dma address of ep0_bounce | 606 | * @ep0_bounce_addr: dma address of ep0_bounce |
607 | * @scratch_addr: dma address of scratchbuf | ||
601 | * @lock: for synchronizing | 608 | * @lock: for synchronizing |
602 | * @dev: pointer to our struct device | 609 | * @dev: pointer to our struct device |
603 | * @xhci: pointer to our xHCI child | 610 | * @xhci: pointer to our xHCI child |
@@ -606,6 +613,7 @@ struct dwc3_scratchpad_array { | |||
606 | * @gadget_driver: pointer to the gadget driver | 613 | * @gadget_driver: pointer to the gadget driver |
607 | * @regs: base address for our registers | 614 | * @regs: base address for our registers |
608 | * @regs_size: address space size | 615 | * @regs_size: address space size |
616 | * @nr_scratch: number of scratch buffers | ||
609 | * @num_event_buffers: calculated number of event buffers | 617 | * @num_event_buffers: calculated number of event buffers |
610 | * @u1u2: only used on revisions <1.83a for workaround | 618 | * @u1u2: only used on revisions <1.83a for workaround |
611 | * @maximum_speed: maximum speed requested (mainly for testing purposes) | 619 | * @maximum_speed: maximum speed requested (mainly for testing purposes) |
@@ -613,16 +621,10 @@ struct dwc3_scratchpad_array { | |||
613 | * @dr_mode: requested mode of operation | 621 | * @dr_mode: requested mode of operation |
614 | * @usb2_phy: pointer to USB2 PHY | 622 | * @usb2_phy: pointer to USB2 PHY |
615 | * @usb3_phy: pointer to USB3 PHY | 623 | * @usb3_phy: pointer to USB3 PHY |
624 | * @usb2_generic_phy: pointer to USB2 PHY | ||
625 | * @usb3_generic_phy: pointer to USB3 PHY | ||
616 | * @dcfg: saved contents of DCFG register | 626 | * @dcfg: saved contents of DCFG register |
617 | * @gctl: saved contents of GCTL register | 627 | * @gctl: saved contents of GCTL register |
618 | * @is_selfpowered: true when we are selfpowered | ||
619 | * @three_stage_setup: set if we perform a three phase setup | ||
620 | * @ep0_bounced: true when we used bounce buffer | ||
621 | * @ep0_expect_in: true when we expect a DATA IN transfer | ||
622 | * @start_config_issued: true when StartConfig command has been issued | ||
623 | * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround | ||
624 | * @needs_fifo_resize: not all users might want fifo resizing, flag it | ||
625 | * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. | ||
626 | * @isoch_delay: wValue from Set Isochronous Delay request; | 628 | * @isoch_delay: wValue from Set Isochronous Delay request; |
627 | * @u2sel: parameter from Set SEL request. | 629 | * @u2sel: parameter from Set SEL request. |
628 | * @u2pel: parameter from Set SEL request. | 630 | * @u2pel: parameter from Set SEL request. |
@@ -637,15 +639,31 @@ struct dwc3_scratchpad_array { | |||
637 | * @mem: points to start of memory which is used for this struct. | 639 | * @mem: points to start of memory which is used for this struct. |
638 | * @hwparams: copy of hwparams registers | 640 | * @hwparams: copy of hwparams registers |
639 | * @root: debugfs root folder pointer | 641 | * @root: debugfs root folder pointer |
642 | * @regset: debugfs pointer to regdump file | ||
643 | * @test_mode: true when we're entering a USB test mode | ||
644 | * @test_mode_nr: test feature selector | ||
645 | * @delayed_status: true when gadget driver asks for delayed status | ||
646 | * @ep0_bounced: true when we used bounce buffer | ||
647 | * @ep0_expect_in: true when we expect a DATA IN transfer | ||
648 | * @has_hibernation: true when dwc3 was configured with Hibernation | ||
649 | * @is_selfpowered: true when we are selfpowered | ||
650 | * @needs_fifo_resize: not all users might want fifo resizing, flag it | ||
651 | * @pullups_connected: true when Run/Stop bit is set | ||
652 | * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. | ||
653 | * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround | ||
654 | * @start_config_issued: true when StartConfig command has been issued | ||
655 | * @three_stage_setup: set if we perform a three phase setup | ||
640 | */ | 656 | */ |
641 | struct dwc3 { | 657 | struct dwc3 { |
642 | struct usb_ctrlrequest *ctrl_req; | 658 | struct usb_ctrlrequest *ctrl_req; |
643 | struct dwc3_trb *ep0_trb; | 659 | struct dwc3_trb *ep0_trb; |
644 | void *ep0_bounce; | 660 | void *ep0_bounce; |
661 | void *scratchbuf; | ||
645 | u8 *setup_buf; | 662 | u8 *setup_buf; |
646 | dma_addr_t ctrl_req_addr; | 663 | dma_addr_t ctrl_req_addr; |
647 | dma_addr_t ep0_trb_addr; | 664 | dma_addr_t ep0_trb_addr; |
648 | dma_addr_t ep0_bounce_addr; | 665 | dma_addr_t ep0_bounce_addr; |
666 | dma_addr_t scratch_addr; | ||
649 | struct dwc3_request ep0_usb_req; | 667 | struct dwc3_request ep0_usb_req; |
650 | 668 | ||
651 | /* device lock */ | 669 | /* device lock */ |
@@ -665,6 +683,9 @@ struct dwc3 { | |||
665 | struct usb_phy *usb2_phy; | 683 | struct usb_phy *usb2_phy; |
666 | struct usb_phy *usb3_phy; | 684 | struct usb_phy *usb3_phy; |
667 | 685 | ||
686 | struct phy *usb2_generic_phy; | ||
687 | struct phy *usb3_generic_phy; | ||
688 | |||
668 | void __iomem *regs; | 689 | void __iomem *regs; |
669 | size_t regs_size; | 690 | size_t regs_size; |
670 | 691 | ||
@@ -674,6 +695,7 @@ struct dwc3 { | |||
674 | u32 dcfg; | 695 | u32 dcfg; |
675 | u32 gctl; | 696 | u32 gctl; |
676 | 697 | ||
698 | u32 nr_scratch; | ||
677 | u32 num_event_buffers; | 699 | u32 num_event_buffers; |
678 | u32 u1u2; | 700 | u32 u1u2; |
679 | u32 maximum_speed; | 701 | u32 maximum_speed; |
@@ -695,17 +717,9 @@ struct dwc3 { | |||
695 | #define DWC3_REVISION_230A 0x5533230a | 717 | #define DWC3_REVISION_230A 0x5533230a |
696 | #define DWC3_REVISION_240A 0x5533240a | 718 | #define DWC3_REVISION_240A 0x5533240a |
697 | #define DWC3_REVISION_250A 0x5533250a | 719 | #define DWC3_REVISION_250A 0x5533250a |
698 | 720 | #define DWC3_REVISION_260A 0x5533260a | |
699 | unsigned is_selfpowered:1; | 721 | #define DWC3_REVISION_270A 0x5533270a |
700 | unsigned three_stage_setup:1; | 722 | #define DWC3_REVISION_280A 0x5533280a |
701 | unsigned ep0_bounced:1; | ||
702 | unsigned ep0_expect_in:1; | ||
703 | unsigned start_config_issued:1; | ||
704 | unsigned setup_packet_pending:1; | ||
705 | unsigned delayed_status:1; | ||
706 | unsigned needs_fifo_resize:1; | ||
707 | unsigned resize_fifos:1; | ||
708 | unsigned pullups_connected:1; | ||
709 | 723 | ||
710 | enum dwc3_ep0_next ep0_next_event; | 724 | enum dwc3_ep0_next ep0_next_event; |
711 | enum dwc3_ep0_state ep0state; | 725 | enum dwc3_ep0_state ep0state; |
@@ -730,6 +744,18 @@ struct dwc3 { | |||
730 | 744 | ||
731 | u8 test_mode; | 745 | u8 test_mode; |
732 | u8 test_mode_nr; | 746 | u8 test_mode_nr; |
747 | |||
748 | unsigned delayed_status:1; | ||
749 | unsigned ep0_bounced:1; | ||
750 | unsigned ep0_expect_in:1; | ||
751 | unsigned has_hibernation:1; | ||
752 | unsigned is_selfpowered:1; | ||
753 | unsigned needs_fifo_resize:1; | ||
754 | unsigned pullups_connected:1; | ||
755 | unsigned resize_fifos:1; | ||
756 | unsigned setup_packet_pending:1; | ||
757 | unsigned start_config_issued:1; | ||
758 | unsigned three_stage_setup:1; | ||
733 | }; | 759 | }; |
734 | 760 | ||
735 | /* -------------------------------------------------------------------------- */ | 761 | /* -------------------------------------------------------------------------- */ |
@@ -815,15 +841,15 @@ struct dwc3_event_depevt { | |||
815 | * 12 - VndrDevTstRcved | 841 | * 12 - VndrDevTstRcved |
816 | * @reserved15_12: Reserved, not used | 842 | * @reserved15_12: Reserved, not used |
817 | * @event_info: Information about this event | 843 | * @event_info: Information about this event |
818 | * @reserved31_24: Reserved, not used | 844 | * @reserved31_25: Reserved, not used |
819 | */ | 845 | */ |
820 | struct dwc3_event_devt { | 846 | struct dwc3_event_devt { |
821 | u32 one_bit:1; | 847 | u32 one_bit:1; |
822 | u32 device_event:7; | 848 | u32 device_event:7; |
823 | u32 type:4; | 849 | u32 type:4; |
824 | u32 reserved15_12:4; | 850 | u32 reserved15_12:4; |
825 | u32 event_info:8; | 851 | u32 event_info:9; |
826 | u32 reserved31_24:8; | 852 | u32 reserved31_25:7; |
827 | } __packed; | 853 | } __packed; |
828 | 854 | ||
829 | /** | 855 | /** |
@@ -856,6 +882,19 @@ union dwc3_event { | |||
856 | struct dwc3_event_gevt gevt; | 882 | struct dwc3_event_gevt gevt; |
857 | }; | 883 | }; |
858 | 884 | ||
885 | /** | ||
886 | * struct dwc3_gadget_ep_cmd_params - representation of endpoint command | ||
887 | * parameters | ||
888 | * @param2: third parameter | ||
889 | * @param1: second parameter | ||
890 | * @param0: first parameter | ||
891 | */ | ||
892 | struct dwc3_gadget_ep_cmd_params { | ||
893 | u32 param2; | ||
894 | u32 param1; | ||
895 | u32 param0; | ||
896 | }; | ||
897 | |||
859 | /* | 898 | /* |
860 | * DWC3 Features to be used as Driver Data | 899 | * DWC3 Features to be used as Driver Data |
861 | */ | 900 | */ |
@@ -881,11 +920,31 @@ static inline void dwc3_host_exit(struct dwc3 *dwc) | |||
881 | #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) | 920 | #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) |
882 | int dwc3_gadget_init(struct dwc3 *dwc); | 921 | int dwc3_gadget_init(struct dwc3 *dwc); |
883 | void dwc3_gadget_exit(struct dwc3 *dwc); | 922 | void dwc3_gadget_exit(struct dwc3 *dwc); |
923 | int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); | ||
924 | int dwc3_gadget_get_link_state(struct dwc3 *dwc); | ||
925 | int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); | ||
926 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
927 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); | ||
928 | int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param); | ||
884 | #else | 929 | #else |
885 | static inline int dwc3_gadget_init(struct dwc3 *dwc) | 930 | static inline int dwc3_gadget_init(struct dwc3 *dwc) |
886 | { return 0; } | 931 | { return 0; } |
887 | static inline void dwc3_gadget_exit(struct dwc3 *dwc) | 932 | static inline void dwc3_gadget_exit(struct dwc3 *dwc) |
888 | { } | 933 | { } |
934 | static inline int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) | ||
935 | { return 0; } | ||
936 | static inline int dwc3_gadget_get_link_state(struct dwc3 *dwc) | ||
937 | { return 0; } | ||
938 | static inline int dwc3_gadget_set_link_state(struct dwc3 *dwc, | ||
939 | enum dwc3_link_state state) | ||
940 | { return 0; } | ||
941 | |||
942 | static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
943 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) | ||
944 | { return 0; } | ||
945 | static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc, | ||
946 | int cmd, u32 param) | ||
947 | { return 0; } | ||
889 | #endif | 948 | #endif |
890 | 949 | ||
891 | /* power management interface */ | 950 | /* power management interface */ |
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index b1d7ee6e40b7..1160ff41bed4 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c | |||
@@ -423,11 +423,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 425 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
426 | if (!res) { | ||
427 | dev_err(dev, "missing memory base resource\n"); | ||
428 | return -EINVAL; | ||
429 | } | ||
430 | |||
431 | base = devm_ioremap_resource(dev, res); | 426 | base = devm_ioremap_resource(dev, res); |
432 | if (IS_ERR(base)) | 427 | if (IS_ERR(base)) |
433 | return PTR_ERR(base); | 428 | return PTR_ERR(base); |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2da0a5a2803a..a740eac74d56 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -68,6 +68,22 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * dwc3_gadget_get_link_state - Gets current state of USB Link | ||
72 | * @dwc: pointer to our context structure | ||
73 | * | ||
74 | * Caller should take care of locking. This function will | ||
75 | * return the link state on success (>= 0) or -ETIMEDOUT. | ||
76 | */ | ||
77 | int dwc3_gadget_get_link_state(struct dwc3 *dwc) | ||
78 | { | ||
79 | u32 reg; | ||
80 | |||
81 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
82 | |||
83 | return DWC3_DSTS_USBLNKST(reg); | ||
84 | } | ||
85 | |||
86 | /** | ||
71 | * dwc3_gadget_set_link_state - Sets USB Link to a particular State | 87 | * dwc3_gadget_set_link_state - Sets USB Link to a particular State |
72 | * @dwc: pointer to our context structure | 88 | * @dwc: pointer to our context structure |
73 | * @state: the state to put link into | 89 | * @state: the state to put link into |
@@ -417,7 +433,7 @@ static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep) | |||
417 | static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | 433 | static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, |
418 | const struct usb_endpoint_descriptor *desc, | 434 | const struct usb_endpoint_descriptor *desc, |
419 | const struct usb_ss_ep_comp_descriptor *comp_desc, | 435 | const struct usb_ss_ep_comp_descriptor *comp_desc, |
420 | bool ignore) | 436 | bool ignore, bool restore) |
421 | { | 437 | { |
422 | struct dwc3_gadget_ep_cmd_params params; | 438 | struct dwc3_gadget_ep_cmd_params params; |
423 | 439 | ||
@@ -436,6 +452,11 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
436 | if (ignore) | 452 | if (ignore) |
437 | params.param0 |= DWC3_DEPCFG_IGN_SEQ_NUM; | 453 | params.param0 |= DWC3_DEPCFG_IGN_SEQ_NUM; |
438 | 454 | ||
455 | if (restore) { | ||
456 | params.param0 |= DWC3_DEPCFG_ACTION_RESTORE; | ||
457 | params.param2 |= dep->saved_state; | ||
458 | } | ||
459 | |||
439 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | 460 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN |
440 | | DWC3_DEPCFG_XFER_NOT_READY_EN; | 461 | | DWC3_DEPCFG_XFER_NOT_READY_EN; |
441 | 462 | ||
@@ -494,7 +515,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep) | |||
494 | static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | 515 | static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, |
495 | const struct usb_endpoint_descriptor *desc, | 516 | const struct usb_endpoint_descriptor *desc, |
496 | const struct usb_ss_ep_comp_descriptor *comp_desc, | 517 | const struct usb_ss_ep_comp_descriptor *comp_desc, |
497 | bool ignore) | 518 | bool ignore, bool restore) |
498 | { | 519 | { |
499 | struct dwc3 *dwc = dep->dwc; | 520 | struct dwc3 *dwc = dep->dwc; |
500 | u32 reg; | 521 | u32 reg; |
@@ -508,7 +529,8 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | |||
508 | return ret; | 529 | return ret; |
509 | } | 530 | } |
510 | 531 | ||
511 | ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc, ignore); | 532 | ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc, ignore, |
533 | restore); | ||
512 | if (ret) | 534 | if (ret) |
513 | return ret; | 535 | return ret; |
514 | 536 | ||
@@ -548,13 +570,13 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | |||
548 | return 0; | 570 | return 0; |
549 | } | 571 | } |
550 | 572 | ||
551 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum); | 573 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force); |
552 | static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) | 574 | static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) |
553 | { | 575 | { |
554 | struct dwc3_request *req; | 576 | struct dwc3_request *req; |
555 | 577 | ||
556 | if (!list_empty(&dep->req_queued)) { | 578 | if (!list_empty(&dep->req_queued)) { |
557 | dwc3_stop_active_transfer(dwc, dep->number); | 579 | dwc3_stop_active_transfer(dwc, dep->number, true); |
558 | 580 | ||
559 | /* - giveback all requests to gadget driver */ | 581 | /* - giveback all requests to gadget driver */ |
560 | while (!list_empty(&dep->req_queued)) { | 582 | while (!list_empty(&dep->req_queued)) { |
@@ -659,7 +681,7 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep, | |||
659 | } | 681 | } |
660 | 682 | ||
661 | spin_lock_irqsave(&dwc->lock, flags); | 683 | spin_lock_irqsave(&dwc->lock, flags); |
662 | ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false); | 684 | ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false); |
663 | spin_unlock_irqrestore(&dwc->lock, flags); | 685 | spin_unlock_irqrestore(&dwc->lock, flags); |
664 | 686 | ||
665 | return ret; | 687 | return ret; |
@@ -771,9 +793,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
771 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | 793 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; |
772 | else | 794 | else |
773 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; | 795 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; |
774 | |||
775 | if (!req->request.no_interrupt && !chain) | ||
776 | trb->ctrl |= DWC3_TRB_CTRL_IOC; | ||
777 | break; | 796 | break; |
778 | 797 | ||
779 | case USB_ENDPOINT_XFER_BULK: | 798 | case USB_ENDPOINT_XFER_BULK: |
@@ -788,6 +807,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
788 | BUG(); | 807 | BUG(); |
789 | } | 808 | } |
790 | 809 | ||
810 | if (!req->request.no_interrupt && !chain) | ||
811 | trb->ctrl |= DWC3_TRB_CTRL_IOC; | ||
812 | |||
791 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 813 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
792 | trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; | 814 | trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; |
793 | trb->ctrl |= DWC3_TRB_CTRL_CSP; | 815 | trb->ctrl |= DWC3_TRB_CTRL_CSP; |
@@ -1077,7 +1099,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1077 | */ | 1099 | */ |
1078 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 1100 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
1079 | if (list_empty(&dep->req_queued)) { | 1101 | if (list_empty(&dep->req_queued)) { |
1080 | dwc3_stop_active_transfer(dwc, dep->number); | 1102 | dwc3_stop_active_transfer(dwc, dep->number, true); |
1081 | dep->flags = DWC3_EP_ENABLED; | 1103 | dep->flags = DWC3_EP_ENABLED; |
1082 | } | 1104 | } |
1083 | return 0; | 1105 | return 0; |
@@ -1107,6 +1129,23 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1107 | return ret; | 1129 | return ret; |
1108 | } | 1130 | } |
1109 | 1131 | ||
1132 | /* | ||
1133 | * 4. Stream Capable Bulk Endpoints. We need to start the transfer | ||
1134 | * right away, otherwise host will not know we have streams to be | ||
1135 | * handled. | ||
1136 | */ | ||
1137 | if (dep->stream_capable) { | ||
1138 | int ret; | ||
1139 | |||
1140 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | ||
1141 | if (ret && ret != -EBUSY) { | ||
1142 | struct dwc3 *dwc = dep->dwc; | ||
1143 | |||
1144 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | ||
1145 | dep->name); | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1110 | return 0; | 1149 | return 0; |
1111 | } | 1150 | } |
1112 | 1151 | ||
@@ -1163,7 +1202,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, | |||
1163 | } | 1202 | } |
1164 | if (r == req) { | 1203 | if (r == req) { |
1165 | /* wait until it is processed */ | 1204 | /* wait until it is processed */ |
1166 | dwc3_stop_active_transfer(dwc, dep->number); | 1205 | dwc3_stop_active_transfer(dwc, dep->number, true); |
1167 | goto out1; | 1206 | goto out1; |
1168 | } | 1207 | } |
1169 | dev_err(dwc->dev, "request %p was not queued to %s\n", | 1208 | dev_err(dwc->dev, "request %p was not queued to %s\n", |
@@ -1194,8 +1233,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | |||
1194 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 1233 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, |
1195 | DWC3_DEPCMD_SETSTALL, ¶ms); | 1234 | DWC3_DEPCMD_SETSTALL, ¶ms); |
1196 | if (ret) | 1235 | if (ret) |
1197 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | 1236 | dev_err(dwc->dev, "failed to set STALL on %s\n", |
1198 | value ? "set" : "clear", | ||
1199 | dep->name); | 1237 | dep->name); |
1200 | else | 1238 | else |
1201 | dep->flags |= DWC3_EP_STALL; | 1239 | dep->flags |= DWC3_EP_STALL; |
@@ -1203,8 +1241,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | |||
1203 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 1241 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, |
1204 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | 1242 | DWC3_DEPCMD_CLEARSTALL, ¶ms); |
1205 | if (ret) | 1243 | if (ret) |
1206 | dev_err(dwc->dev, "failed to %s STALL on %s\n", | 1244 | dev_err(dwc->dev, "failed to clear STALL on %s\n", |
1207 | value ? "set" : "clear", | ||
1208 | dep->name); | 1245 | dep->name); |
1209 | else | 1246 | else |
1210 | dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); | 1247 | dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); |
@@ -1387,7 +1424,7 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, | |||
1387 | return 0; | 1424 | return 0; |
1388 | } | 1425 | } |
1389 | 1426 | ||
1390 | static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | 1427 | static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) |
1391 | { | 1428 | { |
1392 | u32 reg; | 1429 | u32 reg; |
1393 | u32 timeout = 500; | 1430 | u32 timeout = 500; |
@@ -1402,9 +1439,17 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | |||
1402 | if (dwc->revision >= DWC3_REVISION_194A) | 1439 | if (dwc->revision >= DWC3_REVISION_194A) |
1403 | reg &= ~DWC3_DCTL_KEEP_CONNECT; | 1440 | reg &= ~DWC3_DCTL_KEEP_CONNECT; |
1404 | reg |= DWC3_DCTL_RUN_STOP; | 1441 | reg |= DWC3_DCTL_RUN_STOP; |
1442 | |||
1443 | if (dwc->has_hibernation) | ||
1444 | reg |= DWC3_DCTL_KEEP_CONNECT; | ||
1445 | |||
1405 | dwc->pullups_connected = true; | 1446 | dwc->pullups_connected = true; |
1406 | } else { | 1447 | } else { |
1407 | reg &= ~DWC3_DCTL_RUN_STOP; | 1448 | reg &= ~DWC3_DCTL_RUN_STOP; |
1449 | |||
1450 | if (dwc->has_hibernation && !suspend) | ||
1451 | reg &= ~DWC3_DCTL_KEEP_CONNECT; | ||
1452 | |||
1408 | dwc->pullups_connected = false; | 1453 | dwc->pullups_connected = false; |
1409 | } | 1454 | } |
1410 | 1455 | ||
@@ -1442,7 +1487,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | |||
1442 | is_on = !!is_on; | 1487 | is_on = !!is_on; |
1443 | 1488 | ||
1444 | spin_lock_irqsave(&dwc->lock, flags); | 1489 | spin_lock_irqsave(&dwc->lock, flags); |
1445 | ret = dwc3_gadget_run_stop(dwc, is_on); | 1490 | ret = dwc3_gadget_run_stop(dwc, is_on, false); |
1446 | spin_unlock_irqrestore(&dwc->lock, flags); | 1491 | spin_unlock_irqrestore(&dwc->lock, flags); |
1447 | 1492 | ||
1448 | return ret; | 1493 | return ret; |
@@ -1549,14 +1594,16 @@ static int dwc3_gadget_start(struct usb_gadget *g, | |||
1549 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | 1594 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); |
1550 | 1595 | ||
1551 | dep = dwc->eps[0]; | 1596 | dep = dwc->eps[0]; |
1552 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); | 1597 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, |
1598 | false); | ||
1553 | if (ret) { | 1599 | if (ret) { |
1554 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 1600 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); |
1555 | goto err2; | 1601 | goto err2; |
1556 | } | 1602 | } |
1557 | 1603 | ||
1558 | dep = dwc->eps[1]; | 1604 | dep = dwc->eps[1]; |
1559 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); | 1605 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, |
1606 | false); | ||
1560 | if (ret) { | 1607 | if (ret) { |
1561 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 1608 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); |
1562 | goto err3; | 1609 | goto err3; |
@@ -1849,15 +1896,12 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1849 | */ | 1896 | */ |
1850 | dep->flags = DWC3_EP_PENDING_REQUEST; | 1897 | dep->flags = DWC3_EP_PENDING_REQUEST; |
1851 | } else { | 1898 | } else { |
1852 | dwc3_stop_active_transfer(dwc, dep->number); | 1899 | dwc3_stop_active_transfer(dwc, dep->number, true); |
1853 | dep->flags = DWC3_EP_ENABLED; | 1900 | dep->flags = DWC3_EP_ENABLED; |
1854 | } | 1901 | } |
1855 | return 1; | 1902 | return 1; |
1856 | } | 1903 | } |
1857 | 1904 | ||
1858 | if ((event->status & DEPEVT_STATUS_IOC) && | ||
1859 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | ||
1860 | return 0; | ||
1861 | return 1; | 1905 | return 1; |
1862 | } | 1906 | } |
1863 | 1907 | ||
@@ -1999,7 +2043,25 @@ static void dwc3_disconnect_gadget(struct dwc3 *dwc) | |||
1999 | } | 2043 | } |
2000 | } | 2044 | } |
2001 | 2045 | ||
2002 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | 2046 | static void dwc3_suspend_gadget(struct dwc3 *dwc) |
2047 | { | ||
2048 | if (dwc->gadget_driver && dwc->gadget_driver->suspend) { | ||
2049 | spin_unlock(&dwc->lock); | ||
2050 | dwc->gadget_driver->suspend(&dwc->gadget); | ||
2051 | spin_lock(&dwc->lock); | ||
2052 | } | ||
2053 | } | ||
2054 | |||
2055 | static void dwc3_resume_gadget(struct dwc3 *dwc) | ||
2056 | { | ||
2057 | if (dwc->gadget_driver && dwc->gadget_driver->resume) { | ||
2058 | spin_unlock(&dwc->lock); | ||
2059 | dwc->gadget_driver->resume(&dwc->gadget); | ||
2060 | spin_lock(&dwc->lock); | ||
2061 | } | ||
2062 | } | ||
2063 | |||
2064 | static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) | ||
2003 | { | 2065 | { |
2004 | struct dwc3_ep *dep; | 2066 | struct dwc3_ep *dep; |
2005 | struct dwc3_gadget_ep_cmd_params params; | 2067 | struct dwc3_gadget_ep_cmd_params params; |
@@ -2031,7 +2093,8 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | |||
2031 | */ | 2093 | */ |
2032 | 2094 | ||
2033 | cmd = DWC3_DEPCMD_ENDTRANSFER; | 2095 | cmd = DWC3_DEPCMD_ENDTRANSFER; |
2034 | cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; | 2096 | cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0; |
2097 | cmd |= DWC3_DEPCMD_CMDIOC; | ||
2035 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); | 2098 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); |
2036 | memset(¶ms, 0, sizeof(params)); | 2099 | memset(¶ms, 0, sizeof(params)); |
2037 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 2100 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); |
@@ -2260,17 +2323,23 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | |||
2260 | reg |= DWC3_DCTL_HIRD_THRES(12); | 2323 | reg |= DWC3_DCTL_HIRD_THRES(12); |
2261 | 2324 | ||
2262 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 2325 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
2326 | } else { | ||
2327 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
2328 | reg &= ~DWC3_DCTL_HIRD_THRES_MASK; | ||
2329 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
2263 | } | 2330 | } |
2264 | 2331 | ||
2265 | dep = dwc->eps[0]; | 2332 | dep = dwc->eps[0]; |
2266 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, true); | 2333 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, true, |
2334 | false); | ||
2267 | if (ret) { | 2335 | if (ret) { |
2268 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 2336 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); |
2269 | return; | 2337 | return; |
2270 | } | 2338 | } |
2271 | 2339 | ||
2272 | dep = dwc->eps[1]; | 2340 | dep = dwc->eps[1]; |
2273 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, true); | 2341 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, true, |
2342 | false); | ||
2274 | if (ret) { | 2343 | if (ret) { |
2275 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); | 2344 | dev_err(dwc->dev, "failed to enable %s\n", dep->name); |
2276 | return; | 2345 | return; |
@@ -2378,9 +2447,50 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, | |||
2378 | 2447 | ||
2379 | dwc->link_state = next; | 2448 | dwc->link_state = next; |
2380 | 2449 | ||
2450 | switch (next) { | ||
2451 | case DWC3_LINK_STATE_U1: | ||
2452 | if (dwc->speed == USB_SPEED_SUPER) | ||
2453 | dwc3_suspend_gadget(dwc); | ||
2454 | break; | ||
2455 | case DWC3_LINK_STATE_U2: | ||
2456 | case DWC3_LINK_STATE_U3: | ||
2457 | dwc3_suspend_gadget(dwc); | ||
2458 | break; | ||
2459 | case DWC3_LINK_STATE_RESUME: | ||
2460 | dwc3_resume_gadget(dwc); | ||
2461 | break; | ||
2462 | default: | ||
2463 | /* do nothing */ | ||
2464 | break; | ||
2465 | } | ||
2466 | |||
2381 | dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); | 2467 | dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); |
2382 | } | 2468 | } |
2383 | 2469 | ||
2470 | static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, | ||
2471 | unsigned int evtinfo) | ||
2472 | { | ||
2473 | unsigned int is_ss = evtinfo & BIT(4); | ||
2474 | |||
2475 | /** | ||
2476 | * WORKAROUND: DWC3 revison 2.20a with hibernation support | ||
2477 | * have a known issue which can cause USB CV TD.9.23 to fail | ||
2478 | * randomly. | ||
2479 | * | ||
2480 | * Because of this issue, core could generate bogus hibernation | ||
2481 | * events which SW needs to ignore. | ||
2482 | * | ||
2483 | * Refers to: | ||
2484 | * | ||
2485 | * STAR#9000546576: Device Mode Hibernation: Issue in USB 2.0 | ||
2486 | * Device Fallback from SuperSpeed | ||
2487 | */ | ||
2488 | if (is_ss ^ (dwc->speed == USB_SPEED_SUPER)) | ||
2489 | return; | ||
2490 | |||
2491 | /* enter hibernation here */ | ||
2492 | } | ||
2493 | |||
2384 | static void dwc3_gadget_interrupt(struct dwc3 *dwc, | 2494 | static void dwc3_gadget_interrupt(struct dwc3 *dwc, |
2385 | const struct dwc3_event_devt *event) | 2495 | const struct dwc3_event_devt *event) |
2386 | { | 2496 | { |
@@ -2397,6 +2507,13 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, | |||
2397 | case DWC3_DEVICE_EVENT_WAKEUP: | 2507 | case DWC3_DEVICE_EVENT_WAKEUP: |
2398 | dwc3_gadget_wakeup_interrupt(dwc); | 2508 | dwc3_gadget_wakeup_interrupt(dwc); |
2399 | break; | 2509 | break; |
2510 | case DWC3_DEVICE_EVENT_HIBER_REQ: | ||
2511 | if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation, | ||
2512 | "unexpected hibernation event\n")) | ||
2513 | break; | ||
2514 | |||
2515 | dwc3_gadget_hibernation_interrupt(dwc, event->event_info); | ||
2516 | break; | ||
2400 | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | 2517 | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: |
2401 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); | 2518 | dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); |
2402 | break; | 2519 | break; |
@@ -2661,8 +2778,10 @@ void dwc3_gadget_exit(struct dwc3 *dwc) | |||
2661 | 2778 | ||
2662 | int dwc3_gadget_prepare(struct dwc3 *dwc) | 2779 | int dwc3_gadget_prepare(struct dwc3 *dwc) |
2663 | { | 2780 | { |
2664 | if (dwc->pullups_connected) | 2781 | if (dwc->pullups_connected) { |
2665 | dwc3_gadget_disable_irq(dwc); | 2782 | dwc3_gadget_disable_irq(dwc); |
2783 | dwc3_gadget_run_stop(dwc, true, true); | ||
2784 | } | ||
2666 | 2785 | ||
2667 | return 0; | 2786 | return 0; |
2668 | } | 2787 | } |
@@ -2671,7 +2790,7 @@ void dwc3_gadget_complete(struct dwc3 *dwc) | |||
2671 | { | 2790 | { |
2672 | if (dwc->pullups_connected) { | 2791 | if (dwc->pullups_connected) { |
2673 | dwc3_gadget_enable_irq(dwc); | 2792 | dwc3_gadget_enable_irq(dwc); |
2674 | dwc3_gadget_run_stop(dwc, true); | 2793 | dwc3_gadget_run_stop(dwc, true, false); |
2675 | } | 2794 | } |
2676 | } | 2795 | } |
2677 | 2796 | ||
@@ -2694,12 +2813,14 @@ int dwc3_gadget_resume(struct dwc3 *dwc) | |||
2694 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); | 2813 | dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512); |
2695 | 2814 | ||
2696 | dep = dwc->eps[0]; | 2815 | dep = dwc->eps[0]; |
2697 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); | 2816 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, |
2817 | false); | ||
2698 | if (ret) | 2818 | if (ret) |
2699 | goto err0; | 2819 | goto err0; |
2700 | 2820 | ||
2701 | dep = dwc->eps[1]; | 2821 | dep = dwc->eps[1]; |
2702 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); | 2822 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false, |
2823 | false); | ||
2703 | if (ret) | 2824 | if (ret) |
2704 | goto err1; | 2825 | goto err1; |
2705 | 2826 | ||
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index febe1aa7b714..a0ee75b68a80 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h | |||
@@ -56,12 +56,6 @@ struct dwc3; | |||
56 | /* DEPXFERCFG parameter 0 */ | 56 | /* DEPXFERCFG parameter 0 */ |
57 | #define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff) | 57 | #define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff) |
58 | 58 | ||
59 | struct dwc3_gadget_ep_cmd_params { | ||
60 | u32 param2; | ||
61 | u32 param1; | ||
62 | u32 param0; | ||
63 | }; | ||
64 | |||
65 | /* -------------------------------------------------------------------------- */ | 59 | /* -------------------------------------------------------------------------- */ |
66 | 60 | ||
67 | #define to_dwc3_request(r) (container_of(r, struct dwc3_request, request)) | 61 | #define to_dwc3_request(r) (container_of(r, struct dwc3_request, request)) |
@@ -85,9 +79,6 @@ static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req) | |||
85 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | 79 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
86 | int status); | 80 | int status); |
87 | 81 | ||
88 | int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); | ||
89 | int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); | ||
90 | |||
91 | void dwc3_ep0_interrupt(struct dwc3 *dwc, | 82 | void dwc3_ep0_interrupt(struct dwc3 *dwc, |
92 | const struct dwc3_event_depevt *event); | 83 | const struct dwc3_event_depevt *event); |
93 | void dwc3_ep0_out_start(struct dwc3 *dwc); | 84 | void dwc3_ep0_out_start(struct dwc3 *dwc); |
@@ -95,9 +86,6 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); | |||
95 | int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | 86 | int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, |
96 | gfp_t gfp_flags); | 87 | gfp_t gfp_flags); |
97 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); | 88 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); |
98 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | ||
99 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); | ||
100 | int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param); | ||
101 | 89 | ||
102 | /** | 90 | /** |
103 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW | 91 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 8154165aa601..3557c7e5040d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -226,7 +226,7 @@ config USB_GR_UDC | |||
226 | config USB_OMAP | 226 | config USB_OMAP |
227 | tristate "OMAP USB Device Controller" | 227 | tristate "OMAP USB Device Controller" |
228 | depends on ARCH_OMAP1 | 228 | depends on ARCH_OMAP1 |
229 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG | 229 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 |
230 | help | 230 | help |
231 | Many Texas Instruments OMAP processors have flexible full | 231 | Many Texas Instruments OMAP processors have flexible full |
232 | speed USB device controllers, with support for up to 30 | 232 | speed USB device controllers, with support for up to 30 |
@@ -301,7 +301,6 @@ config USB_PXA27X | |||
301 | gadget drivers to also be dynamically linked. | 301 | gadget drivers to also be dynamically linked. |
302 | 302 | ||
303 | config USB_S3C_HSOTG | 303 | config USB_S3C_HSOTG |
304 | depends on ARM | ||
305 | tristate "Designware/S3C HS/OtG USB Device controller" | 304 | tristate "Designware/S3C HS/OtG USB Device controller" |
306 | help | 305 | help |
307 | The Designware USB2.0 high-speed gadget controller | 306 | The Designware USB2.0 high-speed gadget controller |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index cea8c20a1425..f605ad8c1902 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1758,15 +1758,15 @@ static int at91udc_probe(struct platform_device *pdev) | |||
1758 | 1758 | ||
1759 | /* newer chips have more FIFO memory than rm9200 */ | 1759 | /* newer chips have more FIFO memory than rm9200 */ |
1760 | if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) { | 1760 | if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) { |
1761 | usb_ep_set_maxpacket_limit(&udc->ep[0].ep, 64); | 1761 | udc->ep[0].maxpacket = 64; |
1762 | usb_ep_set_maxpacket_limit(&udc->ep[3].ep, 64); | 1762 | udc->ep[3].maxpacket = 64; |
1763 | usb_ep_set_maxpacket_limit(&udc->ep[4].ep, 512); | 1763 | udc->ep[4].maxpacket = 512; |
1764 | usb_ep_set_maxpacket_limit(&udc->ep[5].ep, 512); | 1764 | udc->ep[5].maxpacket = 512; |
1765 | } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { | 1765 | } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { |
1766 | usb_ep_set_maxpacket_limit(&udc->ep[3].ep, 64); | 1766 | udc->ep[3].maxpacket = 64; |
1767 | } else if (cpu_is_at91sam9263()) { | 1767 | } else if (cpu_is_at91sam9263()) { |
1768 | usb_ep_set_maxpacket_limit(&udc->ep[0].ep, 64); | 1768 | udc->ep[0].maxpacket = 64; |
1769 | usb_ep_set_maxpacket_limit(&udc->ep[3].ep, 64); | 1769 | udc->ep[3].maxpacket = 64; |
1770 | } | 1770 | } |
1771 | 1771 | ||
1772 | udc->udp_baseaddr = ioremap(res->start, resource_size(res)); | 1772 | udc->udp_baseaddr = ioremap(res->start, resource_size(res)); |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 52771d4c44bc..9f65324f9ae0 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1661,7 +1661,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1661 | if (dma_status) { | 1661 | if (dma_status) { |
1662 | int i; | 1662 | int i; |
1663 | 1663 | ||
1664 | for (i = 1; i < USBA_NR_ENDPOINTS; i++) | 1664 | for (i = 1; i < USBA_NR_DMAS; i++) |
1665 | if (dma_status & (1 << i)) | 1665 | if (dma_status & (1 << i)) |
1666 | usba_dma_irq(udc, &udc->usba_ep[i]); | 1666 | usba_dma_irq(udc, &udc->usba_ep[i]); |
1667 | } | 1667 | } |
@@ -1670,7 +1670,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1670 | if (ep_status) { | 1670 | if (ep_status) { |
1671 | int i; | 1671 | int i; |
1672 | 1672 | ||
1673 | for (i = 0; i < USBA_NR_ENDPOINTS; i++) | 1673 | for (i = 0; i < udc->num_ep; i++) |
1674 | if (ep_status & (1 << i)) { | 1674 | if (ep_status & (1 << i)) { |
1675 | if (ep_is_control(&udc->usba_ep[i])) | 1675 | if (ep_is_control(&udc->usba_ep[i])) |
1676 | usba_control_irq(udc, &udc->usba_ep[i]); | 1676 | usba_control_irq(udc, &udc->usba_ep[i]); |
@@ -1827,12 +1827,12 @@ static int atmel_usba_stop(struct usb_gadget *gadget, | |||
1827 | toggle_bias(0); | 1827 | toggle_bias(0); |
1828 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1828 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1829 | 1829 | ||
1830 | udc->driver = NULL; | ||
1831 | |||
1832 | clk_disable_unprepare(udc->hclk); | 1830 | clk_disable_unprepare(udc->hclk); |
1833 | clk_disable_unprepare(udc->pclk); | 1831 | clk_disable_unprepare(udc->pclk); |
1834 | 1832 | ||
1835 | DBG(DBG_GADGET, "unregistered driver `%s'\n", driver->driver.name); | 1833 | DBG(DBG_GADGET, "unregistered driver `%s'\n", udc->driver->driver.name); |
1834 | |||
1835 | udc->driver = NULL; | ||
1836 | 1836 | ||
1837 | return 0; | 1837 | return 0; |
1838 | } | 1838 | } |
@@ -1914,6 +1914,12 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev, | |||
1914 | i++; | 1914 | i++; |
1915 | } | 1915 | } |
1916 | 1916 | ||
1917 | if (i == 0) { | ||
1918 | dev_err(&pdev->dev, "of_probe: no endpoint specified\n"); | ||
1919 | ret = -EINVAL; | ||
1920 | goto err; | ||
1921 | } | ||
1922 | |||
1917 | return eps; | 1923 | return eps; |
1918 | err: | 1924 | err: |
1919 | return ERR_PTR(ret); | 1925 | return ERR_PTR(ret); |
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h index 2922db50befe..a70706e8cb02 100644 --- a/drivers/usb/gadget/atmel_usba_udc.h +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -210,7 +210,7 @@ | |||
210 | #define USBA_FIFO_BASE(x) ((x) << 16) | 210 | #define USBA_FIFO_BASE(x) ((x) << 16) |
211 | 211 | ||
212 | /* Synth parameters */ | 212 | /* Synth parameters */ |
213 | #define USBA_NR_ENDPOINTS 7 | 213 | #define USBA_NR_DMAS 7 |
214 | 214 | ||
215 | #define EP0_FIFO_SIZE 64 | 215 | #define EP0_FIFO_SIZE 64 |
216 | #define EP0_EPT_SIZE USBA_EPT_SIZE_64 | 216 | #define EP0_EPT_SIZE USBA_EPT_SIZE_64 |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d742bed7a5fa..fab906429b80 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1139,7 +1139,7 @@ struct usb_string *usb_gstrings_attach(struct usb_composite_dev *cdev, | |||
1139 | 1139 | ||
1140 | uc = copy_gadget_strings(sp, n_gstrings, n_strings); | 1140 | uc = copy_gadget_strings(sp, n_gstrings, n_strings); |
1141 | if (IS_ERR(uc)) | 1141 | if (IS_ERR(uc)) |
1142 | return ERR_PTR(PTR_ERR(uc)); | 1142 | return ERR_CAST(uc); |
1143 | 1143 | ||
1144 | n_gs = get_containers_gs(uc); | 1144 | n_gs = get_containers_gs(uc); |
1145 | ret = usb_string_ids_tab(cdev, n_gs[0]->strings); | 1145 | ret = usb_string_ids_tab(cdev, n_gs[0]->strings); |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 2b4334394076..2e164dca08e8 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -28,6 +28,10 @@ | |||
28 | #include <linux/usb/composite.h> | 28 | #include <linux/usb/composite.h> |
29 | #include <linux/usb/functionfs.h> | 29 | #include <linux/usb/functionfs.h> |
30 | 30 | ||
31 | #include <linux/aio.h> | ||
32 | #include <linux/mmu_context.h> | ||
33 | #include <linux/poll.h> | ||
34 | |||
31 | #include "u_fs.h" | 35 | #include "u_fs.h" |
32 | #include "configfs.h" | 36 | #include "configfs.h" |
33 | 37 | ||
@@ -99,6 +103,14 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f) | |||
99 | } | 103 | } |
100 | 104 | ||
101 | 105 | ||
106 | static inline enum ffs_setup_state | ||
107 | ffs_setup_state_clear_cancelled(struct ffs_data *ffs) | ||
108 | { | ||
109 | return (enum ffs_setup_state) | ||
110 | cmpxchg(&ffs->setup_state, FFS_SETUP_CANCELLED, FFS_NO_SETUP); | ||
111 | } | ||
112 | |||
113 | |||
102 | static void ffs_func_eps_disable(struct ffs_function *func); | 114 | static void ffs_func_eps_disable(struct ffs_function *func); |
103 | static int __must_check ffs_func_eps_enable(struct ffs_function *func); | 115 | static int __must_check ffs_func_eps_enable(struct ffs_function *func); |
104 | 116 | ||
@@ -122,8 +134,8 @@ struct ffs_ep { | |||
122 | struct usb_ep *ep; /* P: ffs->eps_lock */ | 134 | struct usb_ep *ep; /* P: ffs->eps_lock */ |
123 | struct usb_request *req; /* P: epfile->mutex */ | 135 | struct usb_request *req; /* P: epfile->mutex */ |
124 | 136 | ||
125 | /* [0]: full speed, [1]: high speed */ | 137 | /* [0]: full speed, [1]: high speed, [2]: super speed */ |
126 | struct usb_endpoint_descriptor *descs[2]; | 138 | struct usb_endpoint_descriptor *descs[3]; |
127 | 139 | ||
128 | u8 num; | 140 | u8 num; |
129 | 141 | ||
@@ -148,6 +160,25 @@ struct ffs_epfile { | |||
148 | unsigned char _pad; | 160 | unsigned char _pad; |
149 | }; | 161 | }; |
150 | 162 | ||
163 | /* ffs_io_data structure ***************************************************/ | ||
164 | |||
165 | struct ffs_io_data { | ||
166 | bool aio; | ||
167 | bool read; | ||
168 | |||
169 | struct kiocb *kiocb; | ||
170 | const struct iovec *iovec; | ||
171 | unsigned long nr_segs; | ||
172 | char __user *buf; | ||
173 | size_t len; | ||
174 | |||
175 | struct mm_struct *mm; | ||
176 | struct work_struct work; | ||
177 | |||
178 | struct usb_ep *ep; | ||
179 | struct usb_request *req; | ||
180 | }; | ||
181 | |||
151 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); | 182 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); |
152 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); | 183 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); |
153 | 184 | ||
@@ -161,8 +192,10 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data, | |||
161 | DEFINE_MUTEX(ffs_lock); | 192 | DEFINE_MUTEX(ffs_lock); |
162 | EXPORT_SYMBOL(ffs_lock); | 193 | EXPORT_SYMBOL(ffs_lock); |
163 | 194 | ||
164 | static struct ffs_dev *ffs_find_dev(const char *name); | 195 | static struct ffs_dev *_ffs_find_dev(const char *name); |
196 | static struct ffs_dev *_ffs_alloc_dev(void); | ||
165 | static int _ffs_name_dev(struct ffs_dev *dev, const char *name); | 197 | static int _ffs_name_dev(struct ffs_dev *dev, const char *name); |
198 | static void _ffs_free_dev(struct ffs_dev *dev); | ||
166 | static void *ffs_acquire_dev(const char *dev_name); | 199 | static void *ffs_acquire_dev(const char *dev_name); |
167 | static void ffs_release_dev(struct ffs_data *ffs_data); | 200 | static void ffs_release_dev(struct ffs_data *ffs_data); |
168 | static int ffs_ready(struct ffs_data *ffs); | 201 | static int ffs_ready(struct ffs_data *ffs); |
@@ -218,7 +251,7 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) | |||
218 | } | 251 | } |
219 | 252 | ||
220 | ffs->setup_state = FFS_NO_SETUP; | 253 | ffs->setup_state = FFS_NO_SETUP; |
221 | return ffs->ep0req_status; | 254 | return req->status ? req->status : req->actual; |
222 | } | 255 | } |
223 | 256 | ||
224 | static int __ffs_ep0_stall(struct ffs_data *ffs) | 257 | static int __ffs_ep0_stall(struct ffs_data *ffs) |
@@ -244,7 +277,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
244 | ENTER(); | 277 | ENTER(); |
245 | 278 | ||
246 | /* Fast check if setup was canceled */ | 279 | /* Fast check if setup was canceled */ |
247 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) | 280 | if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED) |
248 | return -EIDRM; | 281 | return -EIDRM; |
249 | 282 | ||
250 | /* Acquire mutex */ | 283 | /* Acquire mutex */ |
@@ -310,8 +343,8 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
310 | * rather then _irqsave | 343 | * rather then _irqsave |
311 | */ | 344 | */ |
312 | spin_lock_irq(&ffs->ev.waitq.lock); | 345 | spin_lock_irq(&ffs->ev.waitq.lock); |
313 | switch (FFS_SETUP_STATE(ffs)) { | 346 | switch (ffs_setup_state_clear_cancelled(ffs)) { |
314 | case FFS_SETUP_CANCELED: | 347 | case FFS_SETUP_CANCELLED: |
315 | ret = -EIDRM; | 348 | ret = -EIDRM; |
316 | goto done_spin; | 349 | goto done_spin; |
317 | 350 | ||
@@ -346,7 +379,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
346 | /* | 379 | /* |
347 | * We are guaranteed to be still in FFS_ACTIVE state | 380 | * We are guaranteed to be still in FFS_ACTIVE state |
348 | * but the state of setup could have changed from | 381 | * but the state of setup could have changed from |
349 | * FFS_SETUP_PENDING to FFS_SETUP_CANCELED so we need | 382 | * FFS_SETUP_PENDING to FFS_SETUP_CANCELLED so we need |
350 | * to check for that. If that happened we copied data | 383 | * to check for that. If that happened we copied data |
351 | * from user space in vain but it's unlikely. | 384 | * from user space in vain but it's unlikely. |
352 | * | 385 | * |
@@ -355,7 +388,8 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
355 | * transition can be performed and it's protected by | 388 | * transition can be performed and it's protected by |
356 | * mutex. | 389 | * mutex. |
357 | */ | 390 | */ |
358 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { | 391 | if (ffs_setup_state_clear_cancelled(ffs) == |
392 | FFS_SETUP_CANCELLED) { | ||
359 | ret = -EIDRM; | 393 | ret = -EIDRM; |
360 | done_spin: | 394 | done_spin: |
361 | spin_unlock_irq(&ffs->ev.waitq.lock); | 395 | spin_unlock_irq(&ffs->ev.waitq.lock); |
@@ -421,7 +455,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
421 | ENTER(); | 455 | ENTER(); |
422 | 456 | ||
423 | /* Fast check if setup was canceled */ | 457 | /* Fast check if setup was canceled */ |
424 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) | 458 | if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED) |
425 | return -EIDRM; | 459 | return -EIDRM; |
426 | 460 | ||
427 | /* Acquire mutex */ | 461 | /* Acquire mutex */ |
@@ -441,8 +475,8 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
441 | */ | 475 | */ |
442 | spin_lock_irq(&ffs->ev.waitq.lock); | 476 | spin_lock_irq(&ffs->ev.waitq.lock); |
443 | 477 | ||
444 | switch (FFS_SETUP_STATE(ffs)) { | 478 | switch (ffs_setup_state_clear_cancelled(ffs)) { |
445 | case FFS_SETUP_CANCELED: | 479 | case FFS_SETUP_CANCELLED: |
446 | ret = -EIDRM; | 480 | ret = -EIDRM; |
447 | break; | 481 | break; |
448 | 482 | ||
@@ -489,7 +523,8 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
489 | spin_lock_irq(&ffs->ev.waitq.lock); | 523 | spin_lock_irq(&ffs->ev.waitq.lock); |
490 | 524 | ||
491 | /* See ffs_ep0_write() */ | 525 | /* See ffs_ep0_write() */ |
492 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { | 526 | if (ffs_setup_state_clear_cancelled(ffs) == |
527 | FFS_SETUP_CANCELLED) { | ||
493 | ret = -EIDRM; | 528 | ret = -EIDRM; |
494 | break; | 529 | break; |
495 | } | 530 | } |
@@ -558,6 +593,45 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) | |||
558 | return ret; | 593 | return ret; |
559 | } | 594 | } |
560 | 595 | ||
596 | static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait) | ||
597 | { | ||
598 | struct ffs_data *ffs = file->private_data; | ||
599 | unsigned int mask = POLLWRNORM; | ||
600 | int ret; | ||
601 | |||
602 | poll_wait(file, &ffs->ev.waitq, wait); | ||
603 | |||
604 | ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK); | ||
605 | if (unlikely(ret < 0)) | ||
606 | return mask; | ||
607 | |||
608 | switch (ffs->state) { | ||
609 | case FFS_READ_DESCRIPTORS: | ||
610 | case FFS_READ_STRINGS: | ||
611 | mask |= POLLOUT; | ||
612 | break; | ||
613 | |||
614 | case FFS_ACTIVE: | ||
615 | switch (ffs->setup_state) { | ||
616 | case FFS_NO_SETUP: | ||
617 | if (ffs->ev.count) | ||
618 | mask |= POLLIN; | ||
619 | break; | ||
620 | |||
621 | case FFS_SETUP_PENDING: | ||
622 | case FFS_SETUP_CANCELLED: | ||
623 | mask |= (POLLIN | POLLOUT); | ||
624 | break; | ||
625 | } | ||
626 | case FFS_CLOSING: | ||
627 | break; | ||
628 | } | ||
629 | |||
630 | mutex_unlock(&ffs->mutex); | ||
631 | |||
632 | return mask; | ||
633 | } | ||
634 | |||
561 | static const struct file_operations ffs_ep0_operations = { | 635 | static const struct file_operations ffs_ep0_operations = { |
562 | .llseek = no_llseek, | 636 | .llseek = no_llseek, |
563 | 637 | ||
@@ -566,6 +640,7 @@ static const struct file_operations ffs_ep0_operations = { | |||
566 | .read = ffs_ep0_read, | 640 | .read = ffs_ep0_read, |
567 | .release = ffs_ep0_release, | 641 | .release = ffs_ep0_release, |
568 | .unlocked_ioctl = ffs_ep0_ioctl, | 642 | .unlocked_ioctl = ffs_ep0_ioctl, |
643 | .poll = ffs_ep0_poll, | ||
569 | }; | 644 | }; |
570 | 645 | ||
571 | 646 | ||
@@ -581,8 +656,52 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) | |||
581 | } | 656 | } |
582 | } | 657 | } |
583 | 658 | ||
584 | static ssize_t ffs_epfile_io(struct file *file, | 659 | static void ffs_user_copy_worker(struct work_struct *work) |
585 | char __user *buf, size_t len, int read) | 660 | { |
661 | struct ffs_io_data *io_data = container_of(work, struct ffs_io_data, | ||
662 | work); | ||
663 | int ret = io_data->req->status ? io_data->req->status : | ||
664 | io_data->req->actual; | ||
665 | |||
666 | if (io_data->read && ret > 0) { | ||
667 | int i; | ||
668 | size_t pos = 0; | ||
669 | use_mm(io_data->mm); | ||
670 | for (i = 0; i < io_data->nr_segs; i++) { | ||
671 | if (unlikely(copy_to_user(io_data->iovec[i].iov_base, | ||
672 | &io_data->buf[pos], | ||
673 | io_data->iovec[i].iov_len))) { | ||
674 | ret = -EFAULT; | ||
675 | break; | ||
676 | } | ||
677 | pos += io_data->iovec[i].iov_len; | ||
678 | } | ||
679 | unuse_mm(io_data->mm); | ||
680 | } | ||
681 | |||
682 | aio_complete(io_data->kiocb, ret, ret); | ||
683 | |||
684 | usb_ep_free_request(io_data->ep, io_data->req); | ||
685 | |||
686 | io_data->kiocb->private = NULL; | ||
687 | if (io_data->read) | ||
688 | kfree(io_data->iovec); | ||
689 | kfree(io_data->buf); | ||
690 | kfree(io_data); | ||
691 | } | ||
692 | |||
693 | static void ffs_epfile_async_io_complete(struct usb_ep *_ep, | ||
694 | struct usb_request *req) | ||
695 | { | ||
696 | struct ffs_io_data *io_data = req->context; | ||
697 | |||
698 | ENTER(); | ||
699 | |||
700 | INIT_WORK(&io_data->work, ffs_user_copy_worker); | ||
701 | schedule_work(&io_data->work); | ||
702 | } | ||
703 | |||
704 | static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) | ||
586 | { | 705 | { |
587 | struct ffs_epfile *epfile = file->private_data; | 706 | struct ffs_epfile *epfile = file->private_data; |
588 | struct ffs_ep *ep; | 707 | struct ffs_ep *ep; |
@@ -612,7 +731,7 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
612 | } | 731 | } |
613 | 732 | ||
614 | /* Do we halt? */ | 733 | /* Do we halt? */ |
615 | halt = !read == !epfile->in; | 734 | halt = (!io_data->read == !epfile->in); |
616 | if (halt && epfile->isoc) { | 735 | if (halt && epfile->isoc) { |
617 | ret = -EINVAL; | 736 | ret = -EINVAL; |
618 | goto error; | 737 | goto error; |
@@ -630,15 +749,32 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
630 | * Controller may require buffer size to be aligned to | 749 | * Controller may require buffer size to be aligned to |
631 | * maxpacketsize of an out endpoint. | 750 | * maxpacketsize of an out endpoint. |
632 | */ | 751 | */ |
633 | data_len = read ? usb_ep_align_maybe(gadget, ep->ep, len) : len; | 752 | data_len = io_data->read ? |
753 | usb_ep_align_maybe(gadget, ep->ep, io_data->len) : | ||
754 | io_data->len; | ||
634 | 755 | ||
635 | data = kmalloc(data_len, GFP_KERNEL); | 756 | data = kmalloc(data_len, GFP_KERNEL); |
636 | if (unlikely(!data)) | 757 | if (unlikely(!data)) |
637 | return -ENOMEM; | 758 | return -ENOMEM; |
638 | 759 | if (io_data->aio && !io_data->read) { | |
639 | if (!read && unlikely(copy_from_user(data, buf, len))) { | 760 | int i; |
640 | ret = -EFAULT; | 761 | size_t pos = 0; |
641 | goto error; | 762 | for (i = 0; i < io_data->nr_segs; i++) { |
763 | if (unlikely(copy_from_user(&data[pos], | ||
764 | io_data->iovec[i].iov_base, | ||
765 | io_data->iovec[i].iov_len))) { | ||
766 | ret = -EFAULT; | ||
767 | goto error; | ||
768 | } | ||
769 | pos += io_data->iovec[i].iov_len; | ||
770 | } | ||
771 | } else { | ||
772 | if (!io_data->read && | ||
773 | unlikely(__copy_from_user(data, io_data->buf, | ||
774 | io_data->len))) { | ||
775 | ret = -EFAULT; | ||
776 | goto error; | ||
777 | } | ||
642 | } | 778 | } |
643 | } | 779 | } |
644 | 780 | ||
@@ -661,40 +797,78 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
661 | ret = -EBADMSG; | 797 | ret = -EBADMSG; |
662 | } else { | 798 | } else { |
663 | /* Fire the request */ | 799 | /* Fire the request */ |
664 | DECLARE_COMPLETION_ONSTACK(done); | 800 | struct usb_request *req; |
665 | 801 | ||
666 | struct usb_request *req = ep->req; | 802 | if (io_data->aio) { |
667 | req->context = &done; | 803 | req = usb_ep_alloc_request(ep->ep, GFP_KERNEL); |
668 | req->complete = ffs_epfile_io_complete; | 804 | if (unlikely(!req)) |
669 | req->buf = data; | 805 | goto error_lock; |
670 | req->length = data_len; | ||
671 | 806 | ||
672 | ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); | 807 | req->buf = data; |
808 | req->length = io_data->len; | ||
673 | 809 | ||
674 | spin_unlock_irq(&epfile->ffs->eps_lock); | 810 | io_data->buf = data; |
811 | io_data->ep = ep->ep; | ||
812 | io_data->req = req; | ||
675 | 813 | ||
676 | if (unlikely(ret < 0)) { | 814 | req->context = io_data; |
677 | /* nop */ | 815 | req->complete = ffs_epfile_async_io_complete; |
678 | } else if (unlikely(wait_for_completion_interruptible(&done))) { | 816 | |
679 | ret = -EINTR; | 817 | ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); |
680 | usb_ep_dequeue(ep->ep, req); | 818 | if (unlikely(ret)) { |
819 | usb_ep_free_request(ep->ep, req); | ||
820 | goto error_lock; | ||
821 | } | ||
822 | ret = -EIOCBQUEUED; | ||
823 | |||
824 | spin_unlock_irq(&epfile->ffs->eps_lock); | ||
681 | } else { | 825 | } else { |
682 | /* | 826 | DECLARE_COMPLETION_ONSTACK(done); |
683 | * XXX We may end up silently droping data here. | 827 | |
684 | * Since data_len (i.e. req->length) may be bigger | 828 | req = ep->req; |
685 | * than len (after being rounded up to maxpacketsize), | 829 | req->buf = data; |
686 | * we may end up with more data then user space has | 830 | req->length = io_data->len; |
687 | * space for. | 831 | |
688 | */ | 832 | req->context = &done; |
689 | ret = ep->status; | 833 | req->complete = ffs_epfile_io_complete; |
690 | if (read && ret > 0 && | 834 | |
691 | unlikely(copy_to_user(buf, data, | 835 | ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); |
692 | min_t(size_t, ret, len)))) | 836 | |
693 | ret = -EFAULT; | 837 | spin_unlock_irq(&epfile->ffs->eps_lock); |
838 | |||
839 | if (unlikely(ret < 0)) { | ||
840 | /* nop */ | ||
841 | } else if (unlikely( | ||
842 | wait_for_completion_interruptible(&done))) { | ||
843 | ret = -EINTR; | ||
844 | usb_ep_dequeue(ep->ep, req); | ||
845 | } else { | ||
846 | /* | ||
847 | * XXX We may end up silently droping data | ||
848 | * here. Since data_len (i.e. req->length) may | ||
849 | * be bigger than len (after being rounded up | ||
850 | * to maxpacketsize), we may end up with more | ||
851 | * data then user space has space for. | ||
852 | */ | ||
853 | ret = ep->status; | ||
854 | if (io_data->read && ret > 0) { | ||
855 | ret = min_t(size_t, ret, io_data->len); | ||
856 | |||
857 | if (unlikely(copy_to_user(io_data->buf, | ||
858 | data, ret))) | ||
859 | ret = -EFAULT; | ||
860 | } | ||
861 | } | ||
862 | kfree(data); | ||
694 | } | 863 | } |
695 | } | 864 | } |
696 | 865 | ||
697 | mutex_unlock(&epfile->mutex); | 866 | mutex_unlock(&epfile->mutex); |
867 | return ret; | ||
868 | |||
869 | error_lock: | ||
870 | spin_unlock_irq(&epfile->ffs->eps_lock); | ||
871 | mutex_unlock(&epfile->mutex); | ||
698 | error: | 872 | error: |
699 | kfree(data); | 873 | kfree(data); |
700 | return ret; | 874 | return ret; |
@@ -704,17 +878,31 @@ static ssize_t | |||
704 | ffs_epfile_write(struct file *file, const char __user *buf, size_t len, | 878 | ffs_epfile_write(struct file *file, const char __user *buf, size_t len, |
705 | loff_t *ptr) | 879 | loff_t *ptr) |
706 | { | 880 | { |
881 | struct ffs_io_data io_data; | ||
882 | |||
707 | ENTER(); | 883 | ENTER(); |
708 | 884 | ||
709 | return ffs_epfile_io(file, (char __user *)buf, len, 0); | 885 | io_data.aio = false; |
886 | io_data.read = false; | ||
887 | io_data.buf = (char * __user)buf; | ||
888 | io_data.len = len; | ||
889 | |||
890 | return ffs_epfile_io(file, &io_data); | ||
710 | } | 891 | } |
711 | 892 | ||
712 | static ssize_t | 893 | static ssize_t |
713 | ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) | 894 | ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) |
714 | { | 895 | { |
896 | struct ffs_io_data io_data; | ||
897 | |||
715 | ENTER(); | 898 | ENTER(); |
716 | 899 | ||
717 | return ffs_epfile_io(file, buf, len, 1); | 900 | io_data.aio = false; |
901 | io_data.read = true; | ||
902 | io_data.buf = buf; | ||
903 | io_data.len = len; | ||
904 | |||
905 | return ffs_epfile_io(file, &io_data); | ||
718 | } | 906 | } |
719 | 907 | ||
720 | static int | 908 | static int |
@@ -733,6 +921,89 @@ ffs_epfile_open(struct inode *inode, struct file *file) | |||
733 | return 0; | 921 | return 0; |
734 | } | 922 | } |
735 | 923 | ||
924 | static int ffs_aio_cancel(struct kiocb *kiocb) | ||
925 | { | ||
926 | struct ffs_io_data *io_data = kiocb->private; | ||
927 | struct ffs_epfile *epfile = kiocb->ki_filp->private_data; | ||
928 | int value; | ||
929 | |||
930 | ENTER(); | ||
931 | |||
932 | spin_lock_irq(&epfile->ffs->eps_lock); | ||
933 | |||
934 | if (likely(io_data && io_data->ep && io_data->req)) | ||
935 | value = usb_ep_dequeue(io_data->ep, io_data->req); | ||
936 | else | ||
937 | value = -EINVAL; | ||
938 | |||
939 | spin_unlock_irq(&epfile->ffs->eps_lock); | ||
940 | |||
941 | return value; | ||
942 | } | ||
943 | |||
944 | static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, | ||
945 | const struct iovec *iovec, | ||
946 | unsigned long nr_segs, loff_t loff) | ||
947 | { | ||
948 | struct ffs_io_data *io_data; | ||
949 | |||
950 | ENTER(); | ||
951 | |||
952 | io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); | ||
953 | if (unlikely(!io_data)) | ||
954 | return -ENOMEM; | ||
955 | |||
956 | io_data->aio = true; | ||
957 | io_data->read = false; | ||
958 | io_data->kiocb = kiocb; | ||
959 | io_data->iovec = iovec; | ||
960 | io_data->nr_segs = nr_segs; | ||
961 | io_data->len = kiocb->ki_nbytes; | ||
962 | io_data->mm = current->mm; | ||
963 | |||
964 | kiocb->private = io_data; | ||
965 | |||
966 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | ||
967 | |||
968 | return ffs_epfile_io(kiocb->ki_filp, io_data); | ||
969 | } | ||
970 | |||
971 | static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, | ||
972 | const struct iovec *iovec, | ||
973 | unsigned long nr_segs, loff_t loff) | ||
974 | { | ||
975 | struct ffs_io_data *io_data; | ||
976 | struct iovec *iovec_copy; | ||
977 | |||
978 | ENTER(); | ||
979 | |||
980 | iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL); | ||
981 | if (unlikely(!iovec_copy)) | ||
982 | return -ENOMEM; | ||
983 | |||
984 | memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs); | ||
985 | |||
986 | io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); | ||
987 | if (unlikely(!io_data)) { | ||
988 | kfree(iovec_copy); | ||
989 | return -ENOMEM; | ||
990 | } | ||
991 | |||
992 | io_data->aio = true; | ||
993 | io_data->read = true; | ||
994 | io_data->kiocb = kiocb; | ||
995 | io_data->iovec = iovec_copy; | ||
996 | io_data->nr_segs = nr_segs; | ||
997 | io_data->len = kiocb->ki_nbytes; | ||
998 | io_data->mm = current->mm; | ||
999 | |||
1000 | kiocb->private = io_data; | ||
1001 | |||
1002 | kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); | ||
1003 | |||
1004 | return ffs_epfile_io(kiocb->ki_filp, io_data); | ||
1005 | } | ||
1006 | |||
736 | static int | 1007 | static int |
737 | ffs_epfile_release(struct inode *inode, struct file *file) | 1008 | ffs_epfile_release(struct inode *inode, struct file *file) |
738 | { | 1009 | { |
@@ -789,6 +1060,8 @@ static const struct file_operations ffs_epfile_operations = { | |||
789 | .open = ffs_epfile_open, | 1060 | .open = ffs_epfile_open, |
790 | .write = ffs_epfile_write, | 1061 | .write = ffs_epfile_write, |
791 | .read = ffs_epfile_read, | 1062 | .read = ffs_epfile_read, |
1063 | .aio_write = ffs_epfile_aio_write, | ||
1064 | .aio_read = ffs_epfile_aio_read, | ||
792 | .release = ffs_epfile_release, | 1065 | .release = ffs_epfile_release, |
793 | .unlocked_ioctl = ffs_epfile_ioctl, | 1066 | .unlocked_ioctl = ffs_epfile_ioctl, |
794 | }; | 1067 | }; |
@@ -1172,7 +1445,7 @@ static void ffs_data_clear(struct ffs_data *ffs) | |||
1172 | if (ffs->epfiles) | 1445 | if (ffs->epfiles) |
1173 | ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); | 1446 | ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); |
1174 | 1447 | ||
1175 | kfree(ffs->raw_descs); | 1448 | kfree(ffs->raw_descs_data); |
1176 | kfree(ffs->raw_strings); | 1449 | kfree(ffs->raw_strings); |
1177 | kfree(ffs->stringtabs); | 1450 | kfree(ffs->stringtabs); |
1178 | } | 1451 | } |
@@ -1184,14 +1457,15 @@ static void ffs_data_reset(struct ffs_data *ffs) | |||
1184 | ffs_data_clear(ffs); | 1457 | ffs_data_clear(ffs); |
1185 | 1458 | ||
1186 | ffs->epfiles = NULL; | 1459 | ffs->epfiles = NULL; |
1460 | ffs->raw_descs_data = NULL; | ||
1187 | ffs->raw_descs = NULL; | 1461 | ffs->raw_descs = NULL; |
1188 | ffs->raw_strings = NULL; | 1462 | ffs->raw_strings = NULL; |
1189 | ffs->stringtabs = NULL; | 1463 | ffs->stringtabs = NULL; |
1190 | 1464 | ||
1191 | ffs->raw_descs_length = 0; | 1465 | ffs->raw_descs_length = 0; |
1192 | ffs->raw_fs_descs_length = 0; | ||
1193 | ffs->fs_descs_count = 0; | 1466 | ffs->fs_descs_count = 0; |
1194 | ffs->hs_descs_count = 0; | 1467 | ffs->hs_descs_count = 0; |
1468 | ffs->ss_descs_count = 0; | ||
1195 | 1469 | ||
1196 | ffs->strings_count = 0; | 1470 | ffs->strings_count = 0; |
1197 | ffs->interfaces_count = 0; | 1471 | ffs->interfaces_count = 0; |
@@ -1334,7 +1608,24 @@ static int ffs_func_eps_enable(struct ffs_function *func) | |||
1334 | spin_lock_irqsave(&func->ffs->eps_lock, flags); | 1608 | spin_lock_irqsave(&func->ffs->eps_lock, flags); |
1335 | do { | 1609 | do { |
1336 | struct usb_endpoint_descriptor *ds; | 1610 | struct usb_endpoint_descriptor *ds; |
1337 | ds = ep->descs[ep->descs[1] ? 1 : 0]; | 1611 | int desc_idx; |
1612 | |||
1613 | if (ffs->gadget->speed == USB_SPEED_SUPER) | ||
1614 | desc_idx = 2; | ||
1615 | else if (ffs->gadget->speed == USB_SPEED_HIGH) | ||
1616 | desc_idx = 1; | ||
1617 | else | ||
1618 | desc_idx = 0; | ||
1619 | |||
1620 | /* fall-back to lower speed if desc missing for current speed */ | ||
1621 | do { | ||
1622 | ds = ep->descs[desc_idx]; | ||
1623 | } while (!ds && --desc_idx >= 0); | ||
1624 | |||
1625 | if (!ds) { | ||
1626 | ret = -EINVAL; | ||
1627 | break; | ||
1628 | } | ||
1338 | 1629 | ||
1339 | ep->ep->driver_data = ep; | 1630 | ep->ep->driver_data = ep; |
1340 | ep->ep->desc = ds; | 1631 | ep->ep->desc = ds; |
@@ -1469,6 +1760,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
1469 | } | 1760 | } |
1470 | break; | 1761 | break; |
1471 | 1762 | ||
1763 | case USB_DT_SS_ENDPOINT_COMP: | ||
1764 | pr_vdebug("EP SS companion descriptor\n"); | ||
1765 | if (length != sizeof(struct usb_ss_ep_comp_descriptor)) | ||
1766 | goto inv_length; | ||
1767 | break; | ||
1768 | |||
1472 | case USB_DT_OTHER_SPEED_CONFIG: | 1769 | case USB_DT_OTHER_SPEED_CONFIG: |
1473 | case USB_DT_INTERFACE_POWER: | 1770 | case USB_DT_INTERFACE_POWER: |
1474 | case USB_DT_DEBUG: | 1771 | case USB_DT_DEBUG: |
@@ -1579,60 +1876,76 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
1579 | static int __ffs_data_got_descs(struct ffs_data *ffs, | 1876 | static int __ffs_data_got_descs(struct ffs_data *ffs, |
1580 | char *const _data, size_t len) | 1877 | char *const _data, size_t len) |
1581 | { | 1878 | { |
1582 | unsigned fs_count, hs_count; | 1879 | char *data = _data, *raw_descs; |
1583 | int fs_len, ret = -EINVAL; | 1880 | unsigned counts[3], flags; |
1584 | char *data = _data; | 1881 | int ret = -EINVAL, i; |
1585 | 1882 | ||
1586 | ENTER(); | 1883 | ENTER(); |
1587 | 1884 | ||
1588 | if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_DESCRIPTORS_MAGIC || | 1885 | if (get_unaligned_le32(data + 4) != len) |
1589 | get_unaligned_le32(data + 4) != len)) | ||
1590 | goto error; | 1886 | goto error; |
1591 | fs_count = get_unaligned_le32(data + 8); | ||
1592 | hs_count = get_unaligned_le32(data + 12); | ||
1593 | 1887 | ||
1594 | if (!fs_count && !hs_count) | 1888 | switch (get_unaligned_le32(data)) { |
1595 | goto einval; | 1889 | case FUNCTIONFS_DESCRIPTORS_MAGIC: |
1596 | 1890 | flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC; | |
1597 | data += 16; | 1891 | data += 8; |
1598 | len -= 16; | 1892 | len -= 8; |
1599 | 1893 | break; | |
1600 | if (likely(fs_count)) { | 1894 | case FUNCTIONFS_DESCRIPTORS_MAGIC_V2: |
1601 | fs_len = ffs_do_descs(fs_count, data, len, | 1895 | flags = get_unaligned_le32(data + 8); |
1602 | __ffs_data_do_entity, ffs); | 1896 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | |
1603 | if (unlikely(fs_len < 0)) { | 1897 | FUNCTIONFS_HAS_HS_DESC | |
1604 | ret = fs_len; | 1898 | FUNCTIONFS_HAS_SS_DESC)) { |
1899 | ret = -ENOSYS; | ||
1605 | goto error; | 1900 | goto error; |
1606 | } | 1901 | } |
1902 | data += 12; | ||
1903 | len -= 12; | ||
1904 | break; | ||
1905 | default: | ||
1906 | goto error; | ||
1907 | } | ||
1607 | 1908 | ||
1608 | data += fs_len; | 1909 | /* Read fs_count, hs_count and ss_count (if present) */ |
1609 | len -= fs_len; | 1910 | for (i = 0; i < 3; ++i) { |
1610 | } else { | 1911 | if (!(flags & (1 << i))) { |
1611 | fs_len = 0; | 1912 | counts[i] = 0; |
1913 | } else if (len < 4) { | ||
1914 | goto error; | ||
1915 | } else { | ||
1916 | counts[i] = get_unaligned_le32(data); | ||
1917 | data += 4; | ||
1918 | len -= 4; | ||
1919 | } | ||
1612 | } | 1920 | } |
1613 | 1921 | ||
1614 | if (likely(hs_count)) { | 1922 | /* Read descriptors */ |
1615 | ret = ffs_do_descs(hs_count, data, len, | 1923 | raw_descs = data; |
1924 | for (i = 0; i < 3; ++i) { | ||
1925 | if (!counts[i]) | ||
1926 | continue; | ||
1927 | ret = ffs_do_descs(counts[i], data, len, | ||
1616 | __ffs_data_do_entity, ffs); | 1928 | __ffs_data_do_entity, ffs); |
1617 | if (unlikely(ret < 0)) | 1929 | if (ret < 0) |
1618 | goto error; | 1930 | goto error; |
1619 | } else { | 1931 | data += ret; |
1620 | ret = 0; | 1932 | len -= ret; |
1621 | } | 1933 | } |
1622 | 1934 | ||
1623 | if (unlikely(len != ret)) | 1935 | if (raw_descs == data || len) { |
1624 | goto einval; | 1936 | ret = -EINVAL; |
1937 | goto error; | ||
1938 | } | ||
1625 | 1939 | ||
1626 | ffs->raw_fs_descs_length = fs_len; | 1940 | ffs->raw_descs_data = _data; |
1627 | ffs->raw_descs_length = fs_len + ret; | 1941 | ffs->raw_descs = raw_descs; |
1628 | ffs->raw_descs = _data; | 1942 | ffs->raw_descs_length = data - raw_descs; |
1629 | ffs->fs_descs_count = fs_count; | 1943 | ffs->fs_descs_count = counts[0]; |
1630 | ffs->hs_descs_count = hs_count; | 1944 | ffs->hs_descs_count = counts[1]; |
1945 | ffs->ss_descs_count = counts[2]; | ||
1631 | 1946 | ||
1632 | return 0; | 1947 | return 0; |
1633 | 1948 | ||
1634 | einval: | ||
1635 | ret = -EINVAL; | ||
1636 | error: | 1949 | error: |
1637 | kfree(_data); | 1950 | kfree(_data); |
1638 | return ret; | 1951 | return ret; |
@@ -1789,7 +2102,7 @@ static void __ffs_event_add(struct ffs_data *ffs, | |||
1789 | * the source does nothing. | 2102 | * the source does nothing. |
1790 | */ | 2103 | */ |
1791 | if (ffs->setup_state == FFS_SETUP_PENDING) | 2104 | if (ffs->setup_state == FFS_SETUP_PENDING) |
1792 | ffs->setup_state = FFS_SETUP_CANCELED; | 2105 | ffs->setup_state = FFS_SETUP_CANCELLED; |
1793 | 2106 | ||
1794 | switch (type) { | 2107 | switch (type) { |
1795 | case FUNCTIONFS_RESUME: | 2108 | case FUNCTIONFS_RESUME: |
@@ -1850,21 +2163,28 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
1850 | struct usb_endpoint_descriptor *ds = (void *)desc; | 2163 | struct usb_endpoint_descriptor *ds = (void *)desc; |
1851 | struct ffs_function *func = priv; | 2164 | struct ffs_function *func = priv; |
1852 | struct ffs_ep *ffs_ep; | 2165 | struct ffs_ep *ffs_ep; |
1853 | 2166 | unsigned ep_desc_id, idx; | |
1854 | /* | 2167 | static const char *speed_names[] = { "full", "high", "super" }; |
1855 | * If hs_descriptors is not NULL then we are reading hs | ||
1856 | * descriptors now | ||
1857 | */ | ||
1858 | const int isHS = func->function.hs_descriptors != NULL; | ||
1859 | unsigned idx; | ||
1860 | 2168 | ||
1861 | if (type != FFS_DESCRIPTOR) | 2169 | if (type != FFS_DESCRIPTOR) |
1862 | return 0; | 2170 | return 0; |
1863 | 2171 | ||
1864 | if (isHS) | 2172 | /* |
2173 | * If ss_descriptors is not NULL, we are reading super speed | ||
2174 | * descriptors; if hs_descriptors is not NULL, we are reading high | ||
2175 | * speed descriptors; otherwise, we are reading full speed | ||
2176 | * descriptors. | ||
2177 | */ | ||
2178 | if (func->function.ss_descriptors) { | ||
2179 | ep_desc_id = 2; | ||
2180 | func->function.ss_descriptors[(long)valuep] = desc; | ||
2181 | } else if (func->function.hs_descriptors) { | ||
2182 | ep_desc_id = 1; | ||
1865 | func->function.hs_descriptors[(long)valuep] = desc; | 2183 | func->function.hs_descriptors[(long)valuep] = desc; |
1866 | else | 2184 | } else { |
2185 | ep_desc_id = 0; | ||
1867 | func->function.fs_descriptors[(long)valuep] = desc; | 2186 | func->function.fs_descriptors[(long)valuep] = desc; |
2187 | } | ||
1868 | 2188 | ||
1869 | if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) | 2189 | if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) |
1870 | return 0; | 2190 | return 0; |
@@ -1872,13 +2192,13 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
1872 | idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; | 2192 | idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; |
1873 | ffs_ep = func->eps + idx; | 2193 | ffs_ep = func->eps + idx; |
1874 | 2194 | ||
1875 | if (unlikely(ffs_ep->descs[isHS])) { | 2195 | if (unlikely(ffs_ep->descs[ep_desc_id])) { |
1876 | pr_vdebug("two %sspeed descriptors for EP %d\n", | 2196 | pr_err("two %sspeed descriptors for EP %d\n", |
1877 | isHS ? "high" : "full", | 2197 | speed_names[ep_desc_id], |
1878 | ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 2198 | ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
1879 | return -EINVAL; | 2199 | return -EINVAL; |
1880 | } | 2200 | } |
1881 | ffs_ep->descs[isHS] = ds; | 2201 | ffs_ep->descs[ep_desc_id] = ds; |
1882 | 2202 | ||
1883 | ffs_dump_mem(": Original ep desc", ds, ds->bLength); | 2203 | ffs_dump_mem(": Original ep desc", ds, ds->bLength); |
1884 | if (ffs_ep->ep) { | 2204 | if (ffs_ep->ep) { |
@@ -2022,8 +2342,10 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
2022 | const int full = !!func->ffs->fs_descs_count; | 2342 | const int full = !!func->ffs->fs_descs_count; |
2023 | const int high = gadget_is_dualspeed(func->gadget) && | 2343 | const int high = gadget_is_dualspeed(func->gadget) && |
2024 | func->ffs->hs_descs_count; | 2344 | func->ffs->hs_descs_count; |
2345 | const int super = gadget_is_superspeed(func->gadget) && | ||
2346 | func->ffs->ss_descs_count; | ||
2025 | 2347 | ||
2026 | int ret; | 2348 | int fs_len, hs_len, ret; |
2027 | 2349 | ||
2028 | /* Make it a single chunk, less management later on */ | 2350 | /* Make it a single chunk, less management later on */ |
2029 | vla_group(d); | 2351 | vla_group(d); |
@@ -2032,15 +2354,16 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
2032 | full ? ffs->fs_descs_count + 1 : 0); | 2354 | full ? ffs->fs_descs_count + 1 : 0); |
2033 | vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs, | 2355 | vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs, |
2034 | high ? ffs->hs_descs_count + 1 : 0); | 2356 | high ? ffs->hs_descs_count + 1 : 0); |
2357 | vla_item_with_sz(d, struct usb_descriptor_header *, ss_descs, | ||
2358 | super ? ffs->ss_descs_count + 1 : 0); | ||
2035 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); | 2359 | vla_item_with_sz(d, short, inums, ffs->interfaces_count); |
2036 | vla_item_with_sz(d, char, raw_descs, | 2360 | vla_item_with_sz(d, char, raw_descs, ffs->raw_descs_length); |
2037 | high ? ffs->raw_descs_length : ffs->raw_fs_descs_length); | ||
2038 | char *vlabuf; | 2361 | char *vlabuf; |
2039 | 2362 | ||
2040 | ENTER(); | 2363 | ENTER(); |
2041 | 2364 | ||
2042 | /* Only high speed but not supported by gadget? */ | 2365 | /* Has descriptors only for speeds gadget does not support */ |
2043 | if (unlikely(!(full | high))) | 2366 | if (unlikely(!(full | high | super))) |
2044 | return -ENOTSUPP; | 2367 | return -ENOTSUPP; |
2045 | 2368 | ||
2046 | /* Allocate a single chunk, less management later on */ | 2369 | /* Allocate a single chunk, less management later on */ |
@@ -2050,8 +2373,10 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
2050 | 2373 | ||
2051 | /* Zero */ | 2374 | /* Zero */ |
2052 | memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); | 2375 | memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz); |
2053 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16, | 2376 | /* Copy descriptors */ |
2054 | d_raw_descs__sz); | 2377 | memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs, |
2378 | ffs->raw_descs_length); | ||
2379 | |||
2055 | memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); | 2380 | memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz); |
2056 | for (ret = ffs->eps_count; ret; --ret) { | 2381 | for (ret = ffs->eps_count; ret; --ret) { |
2057 | struct ffs_ep *ptr; | 2382 | struct ffs_ep *ptr; |
@@ -2073,22 +2398,38 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
2073 | */ | 2398 | */ |
2074 | if (likely(full)) { | 2399 | if (likely(full)) { |
2075 | func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs); | 2400 | func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs); |
2076 | ret = ffs_do_descs(ffs->fs_descs_count, | 2401 | fs_len = ffs_do_descs(ffs->fs_descs_count, |
2077 | vla_ptr(vlabuf, d, raw_descs), | 2402 | vla_ptr(vlabuf, d, raw_descs), |
2078 | d_raw_descs__sz, | 2403 | d_raw_descs__sz, |
2079 | __ffs_func_bind_do_descs, func); | 2404 | __ffs_func_bind_do_descs, func); |
2080 | if (unlikely(ret < 0)) | 2405 | if (unlikely(fs_len < 0)) { |
2406 | ret = fs_len; | ||
2081 | goto error; | 2407 | goto error; |
2408 | } | ||
2082 | } else { | 2409 | } else { |
2083 | ret = 0; | 2410 | fs_len = 0; |
2084 | } | 2411 | } |
2085 | 2412 | ||
2086 | if (likely(high)) { | 2413 | if (likely(high)) { |
2087 | func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs); | 2414 | func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs); |
2088 | ret = ffs_do_descs(ffs->hs_descs_count, | 2415 | hs_len = ffs_do_descs(ffs->hs_descs_count, |
2089 | vla_ptr(vlabuf, d, raw_descs) + ret, | 2416 | vla_ptr(vlabuf, d, raw_descs) + fs_len, |
2090 | d_raw_descs__sz - ret, | 2417 | d_raw_descs__sz - fs_len, |
2091 | __ffs_func_bind_do_descs, func); | 2418 | __ffs_func_bind_do_descs, func); |
2419 | if (unlikely(hs_len < 0)) { | ||
2420 | ret = hs_len; | ||
2421 | goto error; | ||
2422 | } | ||
2423 | } else { | ||
2424 | hs_len = 0; | ||
2425 | } | ||
2426 | |||
2427 | if (likely(super)) { | ||
2428 | func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs); | ||
2429 | ret = ffs_do_descs(ffs->ss_descs_count, | ||
2430 | vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, | ||
2431 | d_raw_descs__sz - fs_len - hs_len, | ||
2432 | __ffs_func_bind_do_descs, func); | ||
2092 | if (unlikely(ret < 0)) | 2433 | if (unlikely(ret < 0)) |
2093 | goto error; | 2434 | goto error; |
2094 | } | 2435 | } |
@@ -2099,7 +2440,8 @@ static int _ffs_func_bind(struct usb_configuration *c, | |||
2099 | * now. | 2440 | * now. |
2100 | */ | 2441 | */ |
2101 | ret = ffs_do_descs(ffs->fs_descs_count + | 2442 | ret = ffs_do_descs(ffs->fs_descs_count + |
2102 | (high ? ffs->hs_descs_count : 0), | 2443 | (high ? ffs->hs_descs_count : 0) + |
2444 | (super ? ffs->ss_descs_count : 0), | ||
2103 | vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz, | 2445 | vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz, |
2104 | __ffs_func_bind_do_nums, func); | 2446 | __ffs_func_bind_do_nums, func); |
2105 | if (unlikely(ret < 0)) | 2447 | if (unlikely(ret < 0)) |
@@ -2258,7 +2600,7 @@ static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf) | |||
2258 | 2600 | ||
2259 | static LIST_HEAD(ffs_devices); | 2601 | static LIST_HEAD(ffs_devices); |
2260 | 2602 | ||
2261 | static struct ffs_dev *_ffs_find_dev(const char *name) | 2603 | static struct ffs_dev *_ffs_do_find_dev(const char *name) |
2262 | { | 2604 | { |
2263 | struct ffs_dev *dev; | 2605 | struct ffs_dev *dev; |
2264 | 2606 | ||
@@ -2275,7 +2617,7 @@ static struct ffs_dev *_ffs_find_dev(const char *name) | |||
2275 | /* | 2617 | /* |
2276 | * ffs_lock must be taken by the caller of this function | 2618 | * ffs_lock must be taken by the caller of this function |
2277 | */ | 2619 | */ |
2278 | static struct ffs_dev *ffs_get_single_dev(void) | 2620 | static struct ffs_dev *_ffs_get_single_dev(void) |
2279 | { | 2621 | { |
2280 | struct ffs_dev *dev; | 2622 | struct ffs_dev *dev; |
2281 | 2623 | ||
@@ -2291,15 +2633,15 @@ static struct ffs_dev *ffs_get_single_dev(void) | |||
2291 | /* | 2633 | /* |
2292 | * ffs_lock must be taken by the caller of this function | 2634 | * ffs_lock must be taken by the caller of this function |
2293 | */ | 2635 | */ |
2294 | static struct ffs_dev *ffs_find_dev(const char *name) | 2636 | static struct ffs_dev *_ffs_find_dev(const char *name) |
2295 | { | 2637 | { |
2296 | struct ffs_dev *dev; | 2638 | struct ffs_dev *dev; |
2297 | 2639 | ||
2298 | dev = ffs_get_single_dev(); | 2640 | dev = _ffs_get_single_dev(); |
2299 | if (dev) | 2641 | if (dev) |
2300 | return dev; | 2642 | return dev; |
2301 | 2643 | ||
2302 | return _ffs_find_dev(name); | 2644 | return _ffs_do_find_dev(name); |
2303 | } | 2645 | } |
2304 | 2646 | ||
2305 | /* Configfs support *********************************************************/ | 2647 | /* Configfs support *********************************************************/ |
@@ -2335,7 +2677,7 @@ static void ffs_free_inst(struct usb_function_instance *f) | |||
2335 | 2677 | ||
2336 | opts = to_f_fs_opts(f); | 2678 | opts = to_f_fs_opts(f); |
2337 | ffs_dev_lock(); | 2679 | ffs_dev_lock(); |
2338 | ffs_free_dev(opts->dev); | 2680 | _ffs_free_dev(opts->dev); |
2339 | ffs_dev_unlock(); | 2681 | ffs_dev_unlock(); |
2340 | kfree(opts); | 2682 | kfree(opts); |
2341 | } | 2683 | } |
@@ -2390,7 +2732,7 @@ static struct usb_function_instance *ffs_alloc_inst(void) | |||
2390 | opts->func_inst.set_inst_name = ffs_set_inst_name; | 2732 | opts->func_inst.set_inst_name = ffs_set_inst_name; |
2391 | opts->func_inst.free_func_inst = ffs_free_inst; | 2733 | opts->func_inst.free_func_inst = ffs_free_inst; |
2392 | ffs_dev_lock(); | 2734 | ffs_dev_lock(); |
2393 | dev = ffs_alloc_dev(); | 2735 | dev = _ffs_alloc_dev(); |
2394 | ffs_dev_unlock(); | 2736 | ffs_dev_unlock(); |
2395 | if (IS_ERR(dev)) { | 2737 | if (IS_ERR(dev)) { |
2396 | kfree(opts); | 2738 | kfree(opts); |
@@ -2446,6 +2788,7 @@ static void ffs_func_unbind(struct usb_configuration *c, | |||
2446 | */ | 2788 | */ |
2447 | func->function.fs_descriptors = NULL; | 2789 | func->function.fs_descriptors = NULL; |
2448 | func->function.hs_descriptors = NULL; | 2790 | func->function.hs_descriptors = NULL; |
2791 | func->function.ss_descriptors = NULL; | ||
2449 | func->interfaces_nums = NULL; | 2792 | func->interfaces_nums = NULL; |
2450 | 2793 | ||
2451 | ffs_event_add(ffs, FUNCTIONFS_UNBIND); | 2794 | ffs_event_add(ffs, FUNCTIONFS_UNBIND); |
@@ -2478,12 +2821,12 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi) | |||
2478 | /* | 2821 | /* |
2479 | * ffs_lock must be taken by the caller of this function | 2822 | * ffs_lock must be taken by the caller of this function |
2480 | */ | 2823 | */ |
2481 | struct ffs_dev *ffs_alloc_dev(void) | 2824 | static struct ffs_dev *_ffs_alloc_dev(void) |
2482 | { | 2825 | { |
2483 | struct ffs_dev *dev; | 2826 | struct ffs_dev *dev; |
2484 | int ret; | 2827 | int ret; |
2485 | 2828 | ||
2486 | if (ffs_get_single_dev()) | 2829 | if (_ffs_get_single_dev()) |
2487 | return ERR_PTR(-EBUSY); | 2830 | return ERR_PTR(-EBUSY); |
2488 | 2831 | ||
2489 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 2832 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
@@ -2511,10 +2854,10 @@ static int _ffs_name_dev(struct ffs_dev *dev, const char *name) | |||
2511 | { | 2854 | { |
2512 | struct ffs_dev *existing; | 2855 | struct ffs_dev *existing; |
2513 | 2856 | ||
2514 | existing = _ffs_find_dev(name); | 2857 | existing = _ffs_do_find_dev(name); |
2515 | if (existing) | 2858 | if (existing) |
2516 | return -EBUSY; | 2859 | return -EBUSY; |
2517 | 2860 | ||
2518 | dev->name = name; | 2861 | dev->name = name; |
2519 | 2862 | ||
2520 | return 0; | 2863 | return 0; |
@@ -2555,7 +2898,7 @@ EXPORT_SYMBOL(ffs_single_dev); | |||
2555 | /* | 2898 | /* |
2556 | * ffs_lock must be taken by the caller of this function | 2899 | * ffs_lock must be taken by the caller of this function |
2557 | */ | 2900 | */ |
2558 | void ffs_free_dev(struct ffs_dev *dev) | 2901 | static void _ffs_free_dev(struct ffs_dev *dev) |
2559 | { | 2902 | { |
2560 | list_del(&dev->entry); | 2903 | list_del(&dev->entry); |
2561 | if (dev->name_allocated) | 2904 | if (dev->name_allocated) |
@@ -2572,7 +2915,7 @@ static void *ffs_acquire_dev(const char *dev_name) | |||
2572 | ENTER(); | 2915 | ENTER(); |
2573 | ffs_dev_lock(); | 2916 | ffs_dev_lock(); |
2574 | 2917 | ||
2575 | ffs_dev = ffs_find_dev(dev_name); | 2918 | ffs_dev = _ffs_find_dev(dev_name); |
2576 | if (!ffs_dev) | 2919 | if (!ffs_dev) |
2577 | ffs_dev = ERR_PTR(-ENODEV); | 2920 | ffs_dev = ERR_PTR(-ENODEV); |
2578 | else if (ffs_dev->mounted) | 2921 | else if (ffs_dev->mounted) |
@@ -2595,11 +2938,12 @@ static void ffs_release_dev(struct ffs_data *ffs_data) | |||
2595 | ffs_dev_lock(); | 2938 | ffs_dev_lock(); |
2596 | 2939 | ||
2597 | ffs_dev = ffs_data->private_data; | 2940 | ffs_dev = ffs_data->private_data; |
2598 | if (ffs_dev) | 2941 | if (ffs_dev) { |
2599 | ffs_dev->mounted = false; | 2942 | ffs_dev->mounted = false; |
2600 | 2943 | ||
2601 | if (ffs_dev->ffs_release_dev_callback) | 2944 | if (ffs_dev->ffs_release_dev_callback) |
2602 | ffs_dev->ffs_release_dev_callback(ffs_dev); | 2945 | ffs_dev->ffs_release_dev_callback(ffs_dev); |
2946 | } | ||
2603 | 2947 | ||
2604 | ffs_dev_unlock(); | 2948 | ffs_dev_unlock(); |
2605 | } | 2949 | } |
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index f1a59190ac9a..df4a0dcbc993 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c | |||
@@ -276,7 +276,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
276 | } | 276 | } |
277 | 277 | ||
278 | net = gether_connect(&geth->port); | 278 | net = gether_connect(&geth->port); |
279 | return IS_ERR(net) ? PTR_ERR(net) : 0; | 279 | return PTR_RET(net); |
280 | } | 280 | } |
281 | 281 | ||
282 | static void geth_disable(struct usb_function *f) | 282 | static void geth_disable(struct usb_function *f) |
diff --git a/drivers/usb/gadget/gr_udc.c b/drivers/usb/gadget/gr_udc.c index 914cbd84ee40..f984ee75324d 100644 --- a/drivers/usb/gadget/gr_udc.c +++ b/drivers/usb/gadget/gr_udc.c | |||
@@ -225,14 +225,8 @@ static void gr_dfs_create(struct gr_udc *dev) | |||
225 | const char *name = "gr_udc_state"; | 225 | const char *name = "gr_udc_state"; |
226 | 226 | ||
227 | dev->dfs_root = debugfs_create_dir(dev_name(dev->dev), NULL); | 227 | dev->dfs_root = debugfs_create_dir(dev_name(dev->dev), NULL); |
228 | if (IS_ERR(dev->dfs_root)) { | 228 | dev->dfs_state = debugfs_create_file(name, 0444, dev->dfs_root, dev, |
229 | dev_err(dev->dev, "Failed to create debugfs directory\n"); | 229 | &gr_dfs_fops); |
230 | return; | ||
231 | } | ||
232 | dev->dfs_state = debugfs_create_file(name, 0444, dev->dfs_root, | ||
233 | dev, &gr_dfs_fops); | ||
234 | if (IS_ERR(dev->dfs_state)) | ||
235 | dev_err(dev->dev, "Failed to create debugfs file %s\n", name); | ||
236 | } | 230 | } |
237 | 231 | ||
238 | static void gr_dfs_delete(struct gr_udc *dev) | 232 | static void gr_dfs_delete(struct gr_udc *dev) |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index b94c049ab0d0..b5be6f0308c2 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -439,11 +439,9 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
439 | /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ | 439 | /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ |
440 | 440 | ||
441 | value = -ENOMEM; | 441 | value = -ENOMEM; |
442 | kbuf = kmalloc (len, GFP_KERNEL); | 442 | kbuf = memdup_user(buf, len); |
443 | if (!kbuf) | 443 | if (!kbuf) { |
444 | goto free1; | 444 | value = PTR_ERR(kbuf); |
445 | if (copy_from_user (kbuf, buf, len)) { | ||
446 | value = -EFAULT; | ||
447 | goto free1; | 445 | goto free1; |
448 | } | 446 | } |
449 | 447 | ||
@@ -452,7 +450,6 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
452 | data->name, len, (int) value); | 450 | data->name, len, (int) value); |
453 | free1: | 451 | free1: |
454 | mutex_unlock(&data->lock); | 452 | mutex_unlock(&data->lock); |
455 | kfree (kbuf); | ||
456 | return value; | 453 | return value; |
457 | } | 454 | } |
458 | 455 | ||
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 049ebab0d360..a139894c600f 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c | |||
@@ -3295,9 +3295,9 @@ usb_clk_enable_fail: | |||
3295 | pll_set_fail: | 3295 | pll_set_fail: |
3296 | clk_disable(udc->usb_pll_clk); | 3296 | clk_disable(udc->usb_pll_clk); |
3297 | pll_enable_fail: | 3297 | pll_enable_fail: |
3298 | clk_put(udc->usb_slv_clk); | ||
3299 | usb_otg_clk_get_fail: | ||
3300 | clk_put(udc->usb_otg_clk); | 3298 | clk_put(udc->usb_otg_clk); |
3299 | usb_otg_clk_get_fail: | ||
3300 | clk_put(udc->usb_slv_clk); | ||
3301 | usb_clk_get_fail: | 3301 | usb_clk_get_fail: |
3302 | clk_put(udc->usb_pll_clk); | 3302 | clk_put(udc->usb_pll_clk); |
3303 | pll_get_fail: | 3303 | pll_get_fail: |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 69b76efd11e9..6474081dcbaf 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -427,12 +427,17 @@ setup_rx_reqs(struct printer_dev *dev) | |||
427 | req->length = USB_BUFSIZE; | 427 | req->length = USB_BUFSIZE; |
428 | req->complete = rx_complete; | 428 | req->complete = rx_complete; |
429 | 429 | ||
430 | /* here, we unlock, and only unlock, to avoid deadlock. */ | ||
431 | spin_unlock(&dev->lock); | ||
430 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); | 432 | error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); |
433 | spin_lock(&dev->lock); | ||
431 | if (error) { | 434 | if (error) { |
432 | DBG(dev, "rx submit --> %d\n", error); | 435 | DBG(dev, "rx submit --> %d\n", error); |
433 | list_add(&req->list, &dev->rx_reqs); | 436 | list_add(&req->list, &dev->rx_reqs); |
434 | break; | 437 | break; |
435 | } else { | 438 | } |
439 | /* if the req is empty, then add it into dev->rx_reqs_active. */ | ||
440 | else if (list_empty(&req->list)) { | ||
436 | list_add(&req->list, &dev->rx_reqs_active); | 441 | list_add(&req->list, &dev->rx_reqs_active); |
437 | } | 442 | } |
438 | } | 443 | } |
@@ -1133,6 +1138,7 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1133 | NULL, "g_printer"); | 1138 | NULL, "g_printer"); |
1134 | if (IS_ERR(dev->pdev)) { | 1139 | if (IS_ERR(dev->pdev)) { |
1135 | ERROR(dev, "Failed to create device: g_printer\n"); | 1140 | ERROR(dev, "Failed to create device: g_printer\n"); |
1141 | status = PTR_ERR(dev->pdev); | ||
1136 | goto fail; | 1142 | goto fail; |
1137 | } | 1143 | } |
1138 | 1144 | ||
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 1172eaeddd85..2a9cb674926a 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -617,7 +617,7 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg, | |||
617 | to_write = DIV_ROUND_UP(to_write, 4); | 617 | to_write = DIV_ROUND_UP(to_write, 4); |
618 | data = hs_req->req.buf + buf_pos; | 618 | data = hs_req->req.buf + buf_pos; |
619 | 619 | ||
620 | writesl(hsotg->regs + EPFIFO(hs_ep->index), data, to_write); | 620 | iowrite32_rep(hsotg->regs + EPFIFO(hs_ep->index), data, to_write); |
621 | 621 | ||
622 | return (to_write >= can_write) ? -ENOSPC : 0; | 622 | return (to_write >= can_write) ? -ENOSPC : 0; |
623 | } | 623 | } |
@@ -720,8 +720,8 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | |||
720 | ureq->length, ureq->actual); | 720 | ureq->length, ureq->actual); |
721 | if (0) | 721 | if (0) |
722 | dev_dbg(hsotg->dev, | 722 | dev_dbg(hsotg->dev, |
723 | "REQ buf %p len %d dma 0x%08x noi=%d zp=%d snok=%d\n", | 723 | "REQ buf %p len %d dma 0x%pad noi=%d zp=%d snok=%d\n", |
724 | ureq->buf, length, ureq->dma, | 724 | ureq->buf, length, &ureq->dma, |
725 | ureq->no_interrupt, ureq->zero, ureq->short_not_ok); | 725 | ureq->no_interrupt, ureq->zero, ureq->short_not_ok); |
726 | 726 | ||
727 | maxreq = get_ep_limit(hs_ep); | 727 | maxreq = get_ep_limit(hs_ep); |
@@ -789,8 +789,8 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, | |||
789 | dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index); | 789 | dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index); |
790 | writel(ureq->dma, hsotg->regs + dma_reg); | 790 | writel(ureq->dma, hsotg->regs + dma_reg); |
791 | 791 | ||
792 | dev_dbg(hsotg->dev, "%s: 0x%08x => 0x%08x\n", | 792 | dev_dbg(hsotg->dev, "%s: 0x%pad => 0x%08x\n", |
793 | __func__, ureq->dma, dma_reg); | 793 | __func__, &ureq->dma, dma_reg); |
794 | } | 794 | } |
795 | 795 | ||
796 | ctrl |= DxEPCTL_EPEna; /* ensure ep enabled */ | 796 | ctrl |= DxEPCTL_EPEna; /* ensure ep enabled */ |
@@ -1186,6 +1186,41 @@ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg); | |||
1186 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); | 1186 | static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg); |
1187 | 1187 | ||
1188 | /** | 1188 | /** |
1189 | * s3c_hsotg_stall_ep0 - stall ep0 | ||
1190 | * @hsotg: The device state | ||
1191 | * | ||
1192 | * Set stall for ep0 as response for setup request. | ||
1193 | */ | ||
1194 | static void s3c_hsotg_stall_ep0(struct s3c_hsotg *hsotg) { | ||
1195 | struct s3c_hsotg_ep *ep0 = &hsotg->eps[0]; | ||
1196 | u32 reg; | ||
1197 | u32 ctrl; | ||
1198 | |||
1199 | dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in); | ||
1200 | reg = (ep0->dir_in) ? DIEPCTL0 : DOEPCTL0; | ||
1201 | |||
1202 | /* | ||
1203 | * DxEPCTL_Stall will be cleared by EP once it has | ||
1204 | * taken effect, so no need to clear later. | ||
1205 | */ | ||
1206 | |||
1207 | ctrl = readl(hsotg->regs + reg); | ||
1208 | ctrl |= DxEPCTL_Stall; | ||
1209 | ctrl |= DxEPCTL_CNAK; | ||
1210 | writel(ctrl, hsotg->regs + reg); | ||
1211 | |||
1212 | dev_dbg(hsotg->dev, | ||
1213 | "written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", | ||
1214 | ctrl, reg, readl(hsotg->regs + reg)); | ||
1215 | |||
1216 | /* | ||
1217 | * complete won't be called, so we enqueue | ||
1218 | * setup request here | ||
1219 | */ | ||
1220 | s3c_hsotg_enqueue_setup(hsotg); | ||
1221 | } | ||
1222 | |||
1223 | /** | ||
1189 | * s3c_hsotg_process_control - process a control request | 1224 | * s3c_hsotg_process_control - process a control request |
1190 | * @hsotg: The device state | 1225 | * @hsotg: The device state |
1191 | * @ctrl: The control request received | 1226 | * @ctrl: The control request received |
@@ -1262,38 +1297,8 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg, | |||
1262 | * so respond with a STALL for the status stage to indicate failure. | 1297 | * so respond with a STALL for the status stage to indicate failure. |
1263 | */ | 1298 | */ |
1264 | 1299 | ||
1265 | if (ret < 0) { | 1300 | if (ret < 0) |
1266 | u32 reg; | 1301 | s3c_hsotg_stall_ep0(hsotg); |
1267 | u32 ctrl; | ||
1268 | |||
1269 | dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in); | ||
1270 | reg = (ep0->dir_in) ? DIEPCTL0 : DOEPCTL0; | ||
1271 | |||
1272 | /* | ||
1273 | * DxEPCTL_Stall will be cleared by EP once it has | ||
1274 | * taken effect, so no need to clear later. | ||
1275 | */ | ||
1276 | |||
1277 | ctrl = readl(hsotg->regs + reg); | ||
1278 | ctrl |= DxEPCTL_Stall; | ||
1279 | ctrl |= DxEPCTL_CNAK; | ||
1280 | writel(ctrl, hsotg->regs + reg); | ||
1281 | |||
1282 | dev_dbg(hsotg->dev, | ||
1283 | "written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n", | ||
1284 | ctrl, reg, readl(hsotg->regs + reg)); | ||
1285 | |||
1286 | /* | ||
1287 | * don't believe we need to anything more to get the EP | ||
1288 | * to reply with a STALL packet | ||
1289 | */ | ||
1290 | |||
1291 | /* | ||
1292 | * complete won't be called, so we enqueue | ||
1293 | * setup request here | ||
1294 | */ | ||
1295 | s3c_hsotg_enqueue_setup(hsotg); | ||
1296 | } | ||
1297 | } | 1302 | } |
1298 | 1303 | ||
1299 | /** | 1304 | /** |
@@ -1488,7 +1493,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1488 | * note, we might over-write the buffer end by 3 bytes depending on | 1493 | * note, we might over-write the buffer end by 3 bytes depending on |
1489 | * alignment of the data. | 1494 | * alignment of the data. |
1490 | */ | 1495 | */ |
1491 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); | 1496 | ioread32_rep(fifo, hs_req->req.buf + read_ptr, to_read); |
1492 | } | 1497 | } |
1493 | 1498 | ||
1494 | /** | 1499 | /** |
@@ -2832,6 +2837,15 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2832 | 2837 | ||
2833 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2838 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2834 | 2839 | ||
2840 | if (index == 0) { | ||
2841 | if (value) | ||
2842 | s3c_hsotg_stall_ep0(hs); | ||
2843 | else | ||
2844 | dev_warn(hs->dev, | ||
2845 | "%s: can't clear halt on ep0\n", __func__); | ||
2846 | return 0; | ||
2847 | } | ||
2848 | |||
2835 | /* write both IN and OUT control registers */ | 2849 | /* write both IN and OUT control registers */ |
2836 | 2850 | ||
2837 | epreg = DIEPCTL(index); | 2851 | epreg = DIEPCTL(index); |
@@ -3760,10 +3774,55 @@ static int s3c_hsotg_remove(struct platform_device *pdev) | |||
3760 | return 0; | 3774 | return 0; |
3761 | } | 3775 | } |
3762 | 3776 | ||
3763 | #if 1 | 3777 | static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state) |
3764 | #define s3c_hsotg_suspend NULL | 3778 | { |
3765 | #define s3c_hsotg_resume NULL | 3779 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); |
3766 | #endif | 3780 | unsigned long flags; |
3781 | int ret = 0; | ||
3782 | |||
3783 | if (hsotg->driver) | ||
3784 | dev_info(hsotg->dev, "suspending usb gadget %s\n", | ||
3785 | hsotg->driver->driver.name); | ||
3786 | |||
3787 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3788 | s3c_hsotg_disconnect(hsotg); | ||
3789 | s3c_hsotg_phy_disable(hsotg); | ||
3790 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | ||
3791 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3792 | |||
3793 | if (hsotg->driver) { | ||
3794 | int ep; | ||
3795 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | ||
3796 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | ||
3797 | |||
3798 | ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), | ||
3799 | hsotg->supplies); | ||
3800 | } | ||
3801 | |||
3802 | return ret; | ||
3803 | } | ||
3804 | |||
3805 | static int s3c_hsotg_resume(struct platform_device *pdev) | ||
3806 | { | ||
3807 | struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); | ||
3808 | unsigned long flags; | ||
3809 | int ret = 0; | ||
3810 | |||
3811 | if (hsotg->driver) { | ||
3812 | dev_info(hsotg->dev, "resuming usb gadget %s\n", | ||
3813 | hsotg->driver->driver.name); | ||
3814 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), | ||
3815 | hsotg->supplies); | ||
3816 | } | ||
3817 | |||
3818 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3819 | hsotg->last_rst = jiffies; | ||
3820 | s3c_hsotg_phy_enable(hsotg); | ||
3821 | s3c_hsotg_core_init(hsotg); | ||
3822 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3823 | |||
3824 | return ret; | ||
3825 | } | ||
3767 | 3826 | ||
3768 | #ifdef CONFIG_OF | 3827 | #ifdef CONFIG_OF |
3769 | static const struct of_device_id s3c_hsotg_of_ids[] = { | 3828 | static const struct of_device_id s3c_hsotg_of_ids[] = { |
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index ea4bbfe72ec0..10c6a128250c 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -1344,7 +1344,6 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1344 | 1344 | ||
1345 | return 0; | 1345 | return 0; |
1346 | err_add_udc: | 1346 | err_add_udc: |
1347 | err_add_device: | ||
1348 | clk_disable(hsudc->uclk); | 1347 | clk_disable(hsudc->uclk); |
1349 | err_res: | 1348 | err_res: |
1350 | if (!IS_ERR_OR_NULL(hsudc->transceiver)) | 1349 | if (!IS_ERR_OR_NULL(hsudc->transceiver)) |
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 0f8aad78b54f..460c266b8e24 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c | |||
@@ -1613,7 +1613,7 @@ static struct se_wwn *usbg_make_tport( | |||
1613 | return ERR_PTR(-ENOMEM); | 1613 | return ERR_PTR(-ENOMEM); |
1614 | } | 1614 | } |
1615 | tport->tport_wwpn = wwpn; | 1615 | tport->tport_wwpn = wwpn; |
1616 | snprintf(tport->tport_name, sizeof(tport->tport_name), wnn_name); | 1616 | snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name); |
1617 | return &tport->tport_wwn; | 1617 | return &tport->tport_wwn; |
1618 | } | 1618 | } |
1619 | 1619 | ||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index b7d4f82872b7..50d09c289137 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -48,6 +48,8 @@ | |||
48 | 48 | ||
49 | #define UETH__VERSION "29-May-2008" | 49 | #define UETH__VERSION "29-May-2008" |
50 | 50 | ||
51 | #define GETHER_NAPI_WEIGHT 32 | ||
52 | |||
51 | struct eth_dev { | 53 | struct eth_dev { |
52 | /* lock is held while accessing port_usb | 54 | /* lock is held while accessing port_usb |
53 | */ | 55 | */ |
@@ -72,6 +74,7 @@ struct eth_dev { | |||
72 | struct sk_buff_head *list); | 74 | struct sk_buff_head *list); |
73 | 75 | ||
74 | struct work_struct work; | 76 | struct work_struct work; |
77 | struct napi_struct rx_napi; | ||
75 | 78 | ||
76 | unsigned long todo; | 79 | unsigned long todo; |
77 | #define WORK_RX_MEMORY 0 | 80 | #define WORK_RX_MEMORY 0 |
@@ -253,18 +256,16 @@ enomem: | |||
253 | DBG(dev, "rx submit --> %d\n", retval); | 256 | DBG(dev, "rx submit --> %d\n", retval); |
254 | if (skb) | 257 | if (skb) |
255 | dev_kfree_skb_any(skb); | 258 | dev_kfree_skb_any(skb); |
256 | spin_lock_irqsave(&dev->req_lock, flags); | ||
257 | list_add(&req->list, &dev->rx_reqs); | ||
258 | spin_unlock_irqrestore(&dev->req_lock, flags); | ||
259 | } | 259 | } |
260 | return retval; | 260 | return retval; |
261 | } | 261 | } |
262 | 262 | ||
263 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) | 263 | static void rx_complete(struct usb_ep *ep, struct usb_request *req) |
264 | { | 264 | { |
265 | struct sk_buff *skb = req->context, *skb2; | 265 | struct sk_buff *skb = req->context; |
266 | struct eth_dev *dev = ep->driver_data; | 266 | struct eth_dev *dev = ep->driver_data; |
267 | int status = req->status; | 267 | int status = req->status; |
268 | bool rx_queue = 0; | ||
268 | 269 | ||
269 | switch (status) { | 270 | switch (status) { |
270 | 271 | ||
@@ -288,30 +289,8 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
288 | } else { | 289 | } else { |
289 | skb_queue_tail(&dev->rx_frames, skb); | 290 | skb_queue_tail(&dev->rx_frames, skb); |
290 | } | 291 | } |
291 | skb = NULL; | 292 | if (!status) |
292 | 293 | rx_queue = 1; | |
293 | skb2 = skb_dequeue(&dev->rx_frames); | ||
294 | while (skb2) { | ||
295 | if (status < 0 | ||
296 | || ETH_HLEN > skb2->len | ||
297 | || skb2->len > VLAN_ETH_FRAME_LEN) { | ||
298 | dev->net->stats.rx_errors++; | ||
299 | dev->net->stats.rx_length_errors++; | ||
300 | DBG(dev, "rx length %d\n", skb2->len); | ||
301 | dev_kfree_skb_any(skb2); | ||
302 | goto next_frame; | ||
303 | } | ||
304 | skb2->protocol = eth_type_trans(skb2, dev->net); | ||
305 | dev->net->stats.rx_packets++; | ||
306 | dev->net->stats.rx_bytes += skb2->len; | ||
307 | |||
308 | /* no buffer copies needed, unless hardware can't | ||
309 | * use skb buffers. | ||
310 | */ | ||
311 | status = netif_rx(skb2); | ||
312 | next_frame: | ||
313 | skb2 = skb_dequeue(&dev->rx_frames); | ||
314 | } | ||
315 | break; | 294 | break; |
316 | 295 | ||
317 | /* software-driven interface shutdown */ | 296 | /* software-driven interface shutdown */ |
@@ -334,22 +313,20 @@ quiesce: | |||
334 | /* FALLTHROUGH */ | 313 | /* FALLTHROUGH */ |
335 | 314 | ||
336 | default: | 315 | default: |
316 | rx_queue = 1; | ||
317 | dev_kfree_skb_any(skb); | ||
337 | dev->net->stats.rx_errors++; | 318 | dev->net->stats.rx_errors++; |
338 | DBG(dev, "rx status %d\n", status); | 319 | DBG(dev, "rx status %d\n", status); |
339 | break; | 320 | break; |
340 | } | 321 | } |
341 | 322 | ||
342 | if (skb) | ||
343 | dev_kfree_skb_any(skb); | ||
344 | if (!netif_running(dev->net)) { | ||
345 | clean: | 323 | clean: |
346 | spin_lock(&dev->req_lock); | 324 | spin_lock(&dev->req_lock); |
347 | list_add(&req->list, &dev->rx_reqs); | 325 | list_add(&req->list, &dev->rx_reqs); |
348 | spin_unlock(&dev->req_lock); | 326 | spin_unlock(&dev->req_lock); |
349 | req = NULL; | 327 | |
350 | } | 328 | if (rx_queue && likely(napi_schedule_prep(&dev->rx_napi))) |
351 | if (req) | 329 | __napi_schedule(&dev->rx_napi); |
352 | rx_submit(dev, req, GFP_ATOMIC); | ||
353 | } | 330 | } |
354 | 331 | ||
355 | static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n) | 332 | static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n) |
@@ -414,16 +391,24 @@ static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) | |||
414 | { | 391 | { |
415 | struct usb_request *req; | 392 | struct usb_request *req; |
416 | unsigned long flags; | 393 | unsigned long flags; |
394 | int rx_counts = 0; | ||
417 | 395 | ||
418 | /* fill unused rxq slots with some skb */ | 396 | /* fill unused rxq slots with some skb */ |
419 | spin_lock_irqsave(&dev->req_lock, flags); | 397 | spin_lock_irqsave(&dev->req_lock, flags); |
420 | while (!list_empty(&dev->rx_reqs)) { | 398 | while (!list_empty(&dev->rx_reqs)) { |
399 | |||
400 | if (++rx_counts > qlen(dev->gadget, dev->qmult)) | ||
401 | break; | ||
402 | |||
421 | req = container_of(dev->rx_reqs.next, | 403 | req = container_of(dev->rx_reqs.next, |
422 | struct usb_request, list); | 404 | struct usb_request, list); |
423 | list_del_init(&req->list); | 405 | list_del_init(&req->list); |
424 | spin_unlock_irqrestore(&dev->req_lock, flags); | 406 | spin_unlock_irqrestore(&dev->req_lock, flags); |
425 | 407 | ||
426 | if (rx_submit(dev, req, gfp_flags) < 0) { | 408 | if (rx_submit(dev, req, gfp_flags) < 0) { |
409 | spin_lock_irqsave(&dev->req_lock, flags); | ||
410 | list_add(&req->list, &dev->rx_reqs); | ||
411 | spin_unlock_irqrestore(&dev->req_lock, flags); | ||
427 | defer_kevent(dev, WORK_RX_MEMORY); | 412 | defer_kevent(dev, WORK_RX_MEMORY); |
428 | return; | 413 | return; |
429 | } | 414 | } |
@@ -433,6 +418,41 @@ static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) | |||
433 | spin_unlock_irqrestore(&dev->req_lock, flags); | 418 | spin_unlock_irqrestore(&dev->req_lock, flags); |
434 | } | 419 | } |
435 | 420 | ||
421 | static int gether_poll(struct napi_struct *napi, int budget) | ||
422 | { | ||
423 | struct eth_dev *dev = container_of(napi, struct eth_dev, rx_napi); | ||
424 | struct sk_buff *skb; | ||
425 | unsigned int work_done = 0; | ||
426 | int status = 0; | ||
427 | |||
428 | while ((skb = skb_dequeue(&dev->rx_frames))) { | ||
429 | if (status < 0 | ||
430 | || ETH_HLEN > skb->len | ||
431 | || skb->len > VLAN_ETH_FRAME_LEN) { | ||
432 | dev->net->stats.rx_errors++; | ||
433 | dev->net->stats.rx_length_errors++; | ||
434 | DBG(dev, "rx length %d\n", skb->len); | ||
435 | dev_kfree_skb_any(skb); | ||
436 | continue; | ||
437 | } | ||
438 | skb->protocol = eth_type_trans(skb, dev->net); | ||
439 | dev->net->stats.rx_packets++; | ||
440 | dev->net->stats.rx_bytes += skb->len; | ||
441 | |||
442 | status = netif_rx_ni(skb); | ||
443 | } | ||
444 | |||
445 | if (netif_running(dev->net)) { | ||
446 | rx_fill(dev, GFP_KERNEL); | ||
447 | work_done++; | ||
448 | } | ||
449 | |||
450 | if (work_done < budget) | ||
451 | napi_complete(&dev->rx_napi); | ||
452 | |||
453 | return work_done; | ||
454 | } | ||
455 | |||
436 | static void eth_work(struct work_struct *work) | 456 | static void eth_work(struct work_struct *work) |
437 | { | 457 | { |
438 | struct eth_dev *dev = container_of(work, struct eth_dev, work); | 458 | struct eth_dev *dev = container_of(work, struct eth_dev, work); |
@@ -625,6 +645,7 @@ static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) | |||
625 | /* and open the tx floodgates */ | 645 | /* and open the tx floodgates */ |
626 | atomic_set(&dev->tx_qlen, 0); | 646 | atomic_set(&dev->tx_qlen, 0); |
627 | netif_wake_queue(dev->net); | 647 | netif_wake_queue(dev->net); |
648 | napi_enable(&dev->rx_napi); | ||
628 | } | 649 | } |
629 | 650 | ||
630 | static int eth_open(struct net_device *net) | 651 | static int eth_open(struct net_device *net) |
@@ -651,6 +672,7 @@ static int eth_stop(struct net_device *net) | |||
651 | unsigned long flags; | 672 | unsigned long flags; |
652 | 673 | ||
653 | VDBG(dev, "%s\n", __func__); | 674 | VDBG(dev, "%s\n", __func__); |
675 | napi_disable(&dev->rx_napi); | ||
654 | netif_stop_queue(net); | 676 | netif_stop_queue(net); |
655 | 677 | ||
656 | DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", | 678 | DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", |
@@ -768,6 +790,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, | |||
768 | return ERR_PTR(-ENOMEM); | 790 | return ERR_PTR(-ENOMEM); |
769 | 791 | ||
770 | dev = netdev_priv(net); | 792 | dev = netdev_priv(net); |
793 | netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT); | ||
771 | spin_lock_init(&dev->lock); | 794 | spin_lock_init(&dev->lock); |
772 | spin_lock_init(&dev->req_lock); | 795 | spin_lock_init(&dev->req_lock); |
773 | INIT_WORK(&dev->work, eth_work); | 796 | INIT_WORK(&dev->work, eth_work); |
@@ -830,6 +853,7 @@ struct net_device *gether_setup_name_default(const char *netname) | |||
830 | return ERR_PTR(-ENOMEM); | 853 | return ERR_PTR(-ENOMEM); |
831 | 854 | ||
832 | dev = netdev_priv(net); | 855 | dev = netdev_priv(net); |
856 | netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT); | ||
833 | spin_lock_init(&dev->lock); | 857 | spin_lock_init(&dev->lock); |
834 | spin_lock_init(&dev->req_lock); | 858 | spin_lock_init(&dev->req_lock); |
835 | INIT_WORK(&dev->work, eth_work); | 859 | INIT_WORK(&dev->work, eth_work); |
@@ -1113,6 +1137,7 @@ void gether_disconnect(struct gether *link) | |||
1113 | { | 1137 | { |
1114 | struct eth_dev *dev = link->ioport; | 1138 | struct eth_dev *dev = link->ioport; |
1115 | struct usb_request *req; | 1139 | struct usb_request *req; |
1140 | struct sk_buff *skb; | ||
1116 | 1141 | ||
1117 | WARN_ON(!dev); | 1142 | WARN_ON(!dev); |
1118 | if (!dev) | 1143 | if (!dev) |
@@ -1139,6 +1164,12 @@ void gether_disconnect(struct gether *link) | |||
1139 | spin_lock(&dev->req_lock); | 1164 | spin_lock(&dev->req_lock); |
1140 | } | 1165 | } |
1141 | spin_unlock(&dev->req_lock); | 1166 | spin_unlock(&dev->req_lock); |
1167 | |||
1168 | spin_lock(&dev->rx_frames.lock); | ||
1169 | while ((skb = __skb_dequeue(&dev->rx_frames))) | ||
1170 | dev_kfree_skb_any(skb); | ||
1171 | spin_unlock(&dev->rx_frames.lock); | ||
1172 | |||
1142 | link->in_ep->driver_data = NULL; | 1173 | link->in_ep->driver_data = NULL; |
1143 | link->in_ep->desc = NULL; | 1174 | link->in_ep->desc = NULL; |
1144 | 1175 | ||
diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h index bc2d3718219b..bf0ba375d459 100644 --- a/drivers/usb/gadget/u_fs.h +++ b/drivers/usb/gadget/u_fs.h | |||
@@ -65,10 +65,8 @@ static inline void ffs_dev_unlock(void) | |||
65 | mutex_unlock(&ffs_lock); | 65 | mutex_unlock(&ffs_lock); |
66 | } | 66 | } |
67 | 67 | ||
68 | struct ffs_dev *ffs_alloc_dev(void); | ||
69 | int ffs_name_dev(struct ffs_dev *dev, const char *name); | 68 | int ffs_name_dev(struct ffs_dev *dev, const char *name); |
70 | int ffs_single_dev(struct ffs_dev *dev); | 69 | int ffs_single_dev(struct ffs_dev *dev); |
71 | void ffs_free_dev(struct ffs_dev *dev); | ||
72 | 70 | ||
73 | struct ffs_epfile; | 71 | struct ffs_epfile; |
74 | struct ffs_function; | 72 | struct ffs_function; |
@@ -125,7 +123,7 @@ enum ffs_setup_state { | |||
125 | * setup. If this state is set read/write on ep0 return | 123 | * setup. If this state is set read/write on ep0 return |
126 | * -EIDRM. This state is only set when adding event. | 124 | * -EIDRM. This state is only set when adding event. |
127 | */ | 125 | */ |
128 | FFS_SETUP_CANCELED | 126 | FFS_SETUP_CANCELLED |
129 | }; | 127 | }; |
130 | 128 | ||
131 | struct ffs_data { | 129 | struct ffs_data { |
@@ -156,7 +154,6 @@ struct ffs_data { | |||
156 | */ | 154 | */ |
157 | struct usb_request *ep0req; /* P: mutex */ | 155 | struct usb_request *ep0req; /* P: mutex */ |
158 | struct completion ep0req_completion; /* P: mutex */ | 156 | struct completion ep0req_completion; /* P: mutex */ |
159 | int ep0req_status; /* P: mutex */ | ||
160 | 157 | ||
161 | /* reference counter */ | 158 | /* reference counter */ |
162 | atomic_t ref; | 159 | atomic_t ref; |
@@ -168,19 +165,18 @@ struct ffs_data { | |||
168 | 165 | ||
169 | /* | 166 | /* |
170 | * Possible transitions: | 167 | * Possible transitions: |
171 | * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock | 168 | * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock |
172 | * happens only in ep0 read which is P: mutex | 169 | * happens only in ep0 read which is P: mutex |
173 | * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock | 170 | * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock |
174 | * happens only in ep0 i/o which is P: mutex | 171 | * happens only in ep0 i/o which is P: mutex |
175 | * + FFS_SETUP_PENDING -> FFS_SETUP_CANCELED -- P: ev.waitq.lock | 172 | * + FFS_SETUP_PENDING -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock |
176 | * + FFS_SETUP_CANCELED -> FFS_NO_SETUP -- cmpxchg | 173 | * + FFS_SETUP_CANCELLED -> FFS_NO_SETUP -- cmpxchg |
174 | * | ||
175 | * This field should never be accessed directly and instead | ||
176 | * ffs_setup_state_clear_cancelled function should be used. | ||
177 | */ | 177 | */ |
178 | enum ffs_setup_state setup_state; | 178 | enum ffs_setup_state setup_state; |
179 | 179 | ||
180 | #define FFS_SETUP_STATE(ffs) \ | ||
181 | ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state, \ | ||
182 | FFS_SETUP_CANCELED, FFS_NO_SETUP)) | ||
183 | |||
184 | /* Events & such. */ | 180 | /* Events & such. */ |
185 | struct { | 181 | struct { |
186 | u8 types[4]; | 182 | u8 types[4]; |
@@ -210,16 +206,16 @@ struct ffs_data { | |||
210 | 206 | ||
211 | /* filled by __ffs_data_got_descs() */ | 207 | /* filled by __ffs_data_got_descs() */ |
212 | /* | 208 | /* |
213 | * Real descriptors are 16 bytes after raw_descs (so you need | 209 | * raw_descs is what you kfree, real_descs points inside of raw_descs, |
214 | * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the | 210 | * where full speed, high speed and super speed descriptors start. |
215 | * first full speed descriptor). raw_descs_length and | 211 | * real_descs_length is the length of all those descriptors. |
216 | * raw_fs_descs_length do not have those 16 bytes added. | ||
217 | */ | 212 | */ |
213 | const void *raw_descs_data; | ||
218 | const void *raw_descs; | 214 | const void *raw_descs; |
219 | unsigned raw_descs_length; | 215 | unsigned raw_descs_length; |
220 | unsigned raw_fs_descs_length; | ||
221 | unsigned fs_descs_count; | 216 | unsigned fs_descs_count; |
222 | unsigned hs_descs_count; | 217 | unsigned hs_descs_count; |
218 | unsigned ss_descs_count; | ||
223 | 219 | ||
224 | unsigned short strings_count; | 220 | unsigned short strings_count; |
225 | unsigned short interfaces_count; | 221 | unsigned short interfaces_count; |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a9707da7da0b..e22b82660831 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -584,7 +584,6 @@ config FHCI_DEBUG | |||
584 | config USB_U132_HCD | 584 | config USB_U132_HCD |
585 | tristate "Elan U132 Adapter Host Controller" | 585 | tristate "Elan U132 Adapter Host Controller" |
586 | depends on USB_FTDI_ELAN | 586 | depends on USB_FTDI_ELAN |
587 | default M | ||
588 | help | 587 | help |
589 | The U132 adapter is a USB to CardBus adapter specifically designed | 588 | The U132 adapter is a USB to CardBus adapter specifically designed |
590 | for PC cards that contain an OHCI host controller. Typical PC cards | 589 | for PC cards that contain an OHCI host controller. Typical PC cards |
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 01536cfd361d..b3a0e11073aa 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2007 Steven Brown <sbrown@cortland.com> | 4 | * Copyright 2007 Steven Brown <sbrown@cortland.com> |
5 | * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> | 5 | * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> |
6 | * Copyright 2014 Hans de Goede <hdegoede@redhat.com> | ||
6 | * | 7 | * |
7 | * Derived from the ohci-ssb driver | 8 | * Derived from the ohci-ssb driver |
8 | * Copyright 2007 Michael Buesch <m@bues.ch> | 9 | * Copyright 2007 Michael Buesch <m@bues.ch> |
@@ -18,6 +19,7 @@ | |||
18 | * | 19 | * |
19 | * Licensed under the GNU/GPL. See COPYING for details. | 20 | * Licensed under the GNU/GPL. See COPYING for details. |
20 | */ | 21 | */ |
22 | #include <linux/clk.h> | ||
21 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
22 | #include <linux/err.h> | 24 | #include <linux/err.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
@@ -25,6 +27,7 @@ | |||
25 | #include <linux/io.h> | 27 | #include <linux/io.h> |
26 | #include <linux/module.h> | 28 | #include <linux/module.h> |
27 | #include <linux/of.h> | 29 | #include <linux/of.h> |
30 | #include <linux/phy/phy.h> | ||
28 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
29 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
30 | #include <linux/usb/hcd.h> | 33 | #include <linux/usb/hcd.h> |
@@ -33,6 +36,13 @@ | |||
33 | #include "ehci.h" | 36 | #include "ehci.h" |
34 | 37 | ||
35 | #define DRIVER_DESC "EHCI generic platform driver" | 38 | #define DRIVER_DESC "EHCI generic platform driver" |
39 | #define EHCI_MAX_CLKS 3 | ||
40 | #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) | ||
41 | |||
42 | struct ehci_platform_priv { | ||
43 | struct clk *clks[EHCI_MAX_CLKS]; | ||
44 | struct phy *phy; | ||
45 | }; | ||
36 | 46 | ||
37 | static const char hcd_name[] = "ehci-platform"; | 47 | static const char hcd_name[] = "ehci-platform"; |
38 | 48 | ||
@@ -45,8 +55,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd) | |||
45 | 55 | ||
46 | hcd->has_tt = pdata->has_tt; | 56 | hcd->has_tt = pdata->has_tt; |
47 | ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; | 57 | ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; |
48 | ehci->big_endian_desc = pdata->big_endian_desc; | ||
49 | ehci->big_endian_mmio = pdata->big_endian_mmio; | ||
50 | 58 | ||
51 | if (pdata->pre_setup) { | 59 | if (pdata->pre_setup) { |
52 | retval = pdata->pre_setup(hcd); | 60 | retval = pdata->pre_setup(hcd); |
@@ -64,38 +72,91 @@ static int ehci_platform_reset(struct usb_hcd *hcd) | |||
64 | return 0; | 72 | return 0; |
65 | } | 73 | } |
66 | 74 | ||
75 | static int ehci_platform_power_on(struct platform_device *dev) | ||
76 | { | ||
77 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
78 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); | ||
79 | int clk, ret; | ||
80 | |||
81 | for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { | ||
82 | ret = clk_prepare_enable(priv->clks[clk]); | ||
83 | if (ret) | ||
84 | goto err_disable_clks; | ||
85 | } | ||
86 | |||
87 | if (priv->phy) { | ||
88 | ret = phy_init(priv->phy); | ||
89 | if (ret) | ||
90 | goto err_disable_clks; | ||
91 | |||
92 | ret = phy_power_on(priv->phy); | ||
93 | if (ret) | ||
94 | goto err_exit_phy; | ||
95 | } | ||
96 | |||
97 | return 0; | ||
98 | |||
99 | err_exit_phy: | ||
100 | phy_exit(priv->phy); | ||
101 | err_disable_clks: | ||
102 | while (--clk >= 0) | ||
103 | clk_disable_unprepare(priv->clks[clk]); | ||
104 | |||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | static void ehci_platform_power_off(struct platform_device *dev) | ||
109 | { | ||
110 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
111 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); | ||
112 | int clk; | ||
113 | |||
114 | if (priv->phy) { | ||
115 | phy_power_off(priv->phy); | ||
116 | phy_exit(priv->phy); | ||
117 | } | ||
118 | |||
119 | for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) | ||
120 | if (priv->clks[clk]) | ||
121 | clk_disable_unprepare(priv->clks[clk]); | ||
122 | } | ||
123 | |||
67 | static struct hc_driver __read_mostly ehci_platform_hc_driver; | 124 | static struct hc_driver __read_mostly ehci_platform_hc_driver; |
68 | 125 | ||
69 | static const struct ehci_driver_overrides platform_overrides __initconst = { | 126 | static const struct ehci_driver_overrides platform_overrides __initconst = { |
70 | .reset = ehci_platform_reset, | 127 | .reset = ehci_platform_reset, |
128 | .extra_priv_size = sizeof(struct ehci_platform_priv), | ||
71 | }; | 129 | }; |
72 | 130 | ||
73 | static struct usb_ehci_pdata ehci_platform_defaults; | 131 | static struct usb_ehci_pdata ehci_platform_defaults = { |
132 | .power_on = ehci_platform_power_on, | ||
133 | .power_suspend = ehci_platform_power_off, | ||
134 | .power_off = ehci_platform_power_off, | ||
135 | }; | ||
74 | 136 | ||
75 | static int ehci_platform_probe(struct platform_device *dev) | 137 | static int ehci_platform_probe(struct platform_device *dev) |
76 | { | 138 | { |
77 | struct usb_hcd *hcd; | 139 | struct usb_hcd *hcd; |
78 | struct resource *res_mem; | 140 | struct resource *res_mem; |
79 | struct usb_ehci_pdata *pdata; | 141 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); |
80 | int irq; | 142 | struct ehci_platform_priv *priv; |
81 | int err; | 143 | struct ehci_hcd *ehci; |
144 | int err, irq, clk = 0; | ||
82 | 145 | ||
83 | if (usb_disabled()) | 146 | if (usb_disabled()) |
84 | return -ENODEV; | 147 | return -ENODEV; |
85 | 148 | ||
86 | /* | 149 | /* |
87 | * use reasonable defaults so platforms don't have to provide these. | 150 | * Use reasonable defaults so platforms don't have to provide these |
88 | * with DT probing on ARM, none of these are set. | 151 | * with DT probing on ARM. |
89 | */ | 152 | */ |
90 | if (!dev_get_platdata(&dev->dev)) | 153 | if (!pdata) |
91 | dev->dev.platform_data = &ehci_platform_defaults; | 154 | pdata = &ehci_platform_defaults; |
92 | 155 | ||
93 | err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); | 156 | err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); |
94 | if (err) | 157 | if (err) |
95 | return err; | 158 | return err; |
96 | 159 | ||
97 | pdata = dev_get_platdata(&dev->dev); | ||
98 | |||
99 | irq = platform_get_irq(dev, 0); | 160 | irq = platform_get_irq(dev, 0); |
100 | if (irq < 0) { | 161 | if (irq < 0) { |
101 | dev_err(&dev->dev, "no irq provided"); | 162 | dev_err(&dev->dev, "no irq provided"); |
@@ -107,17 +168,72 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
107 | return -ENXIO; | 168 | return -ENXIO; |
108 | } | 169 | } |
109 | 170 | ||
171 | hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, | ||
172 | dev_name(&dev->dev)); | ||
173 | if (!hcd) | ||
174 | return -ENOMEM; | ||
175 | |||
176 | platform_set_drvdata(dev, hcd); | ||
177 | dev->dev.platform_data = pdata; | ||
178 | priv = hcd_to_ehci_priv(hcd); | ||
179 | ehci = hcd_to_ehci(hcd); | ||
180 | |||
181 | if (pdata == &ehci_platform_defaults && dev->dev.of_node) { | ||
182 | if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) | ||
183 | ehci->big_endian_mmio = 1; | ||
184 | |||
185 | if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) | ||
186 | ehci->big_endian_desc = 1; | ||
187 | |||
188 | if (of_property_read_bool(dev->dev.of_node, "big-endian")) | ||
189 | ehci->big_endian_mmio = ehci->big_endian_desc = 1; | ||
190 | |||
191 | priv->phy = devm_phy_get(&dev->dev, "usb"); | ||
192 | if (IS_ERR(priv->phy)) { | ||
193 | err = PTR_ERR(priv->phy); | ||
194 | if (err == -EPROBE_DEFER) | ||
195 | goto err_put_hcd; | ||
196 | priv->phy = NULL; | ||
197 | } | ||
198 | |||
199 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { | ||
200 | priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); | ||
201 | if (IS_ERR(priv->clks[clk])) { | ||
202 | err = PTR_ERR(priv->clks[clk]); | ||
203 | if (err == -EPROBE_DEFER) | ||
204 | goto err_put_clks; | ||
205 | priv->clks[clk] = NULL; | ||
206 | break; | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | if (pdata->big_endian_desc) | ||
212 | ehci->big_endian_desc = 1; | ||
213 | if (pdata->big_endian_mmio) | ||
214 | ehci->big_endian_mmio = 1; | ||
215 | |||
216 | #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
217 | if (ehci->big_endian_mmio) { | ||
218 | dev_err(&dev->dev, | ||
219 | "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); | ||
220 | err = -EINVAL; | ||
221 | goto err_put_clks; | ||
222 | } | ||
223 | #endif | ||
224 | #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC | ||
225 | if (ehci->big_endian_desc) { | ||
226 | dev_err(&dev->dev, | ||
227 | "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); | ||
228 | err = -EINVAL; | ||
229 | goto err_put_clks; | ||
230 | } | ||
231 | #endif | ||
232 | |||
110 | if (pdata->power_on) { | 233 | if (pdata->power_on) { |
111 | err = pdata->power_on(dev); | 234 | err = pdata->power_on(dev); |
112 | if (err < 0) | 235 | if (err < 0) |
113 | return err; | 236 | goto err_put_clks; |
114 | } | ||
115 | |||
116 | hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, | ||
117 | dev_name(&dev->dev)); | ||
118 | if (!hcd) { | ||
119 | err = -ENOMEM; | ||
120 | goto err_power; | ||
121 | } | 237 | } |
122 | 238 | ||
123 | hcd->rsrc_start = res_mem->start; | 239 | hcd->rsrc_start = res_mem->start; |
@@ -126,22 +242,28 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
126 | hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); | 242 | hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); |
127 | if (IS_ERR(hcd->regs)) { | 243 | if (IS_ERR(hcd->regs)) { |
128 | err = PTR_ERR(hcd->regs); | 244 | err = PTR_ERR(hcd->regs); |
129 | goto err_put_hcd; | 245 | goto err_power; |
130 | } | 246 | } |
131 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | 247 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
132 | if (err) | 248 | if (err) |
133 | goto err_put_hcd; | 249 | goto err_power; |
134 | 250 | ||
135 | device_wakeup_enable(hcd->self.controller); | 251 | device_wakeup_enable(hcd->self.controller); |
136 | platform_set_drvdata(dev, hcd); | 252 | platform_set_drvdata(dev, hcd); |
137 | 253 | ||
138 | return err; | 254 | return err; |
139 | 255 | ||
140 | err_put_hcd: | ||
141 | usb_put_hcd(hcd); | ||
142 | err_power: | 256 | err_power: |
143 | if (pdata->power_off) | 257 | if (pdata->power_off) |
144 | pdata->power_off(dev); | 258 | pdata->power_off(dev); |
259 | err_put_clks: | ||
260 | while (--clk >= 0) | ||
261 | clk_put(priv->clks[clk]); | ||
262 | err_put_hcd: | ||
263 | if (pdata == &ehci_platform_defaults) | ||
264 | dev->dev.platform_data = NULL; | ||
265 | |||
266 | usb_put_hcd(hcd); | ||
145 | 267 | ||
146 | return err; | 268 | return err; |
147 | } | 269 | } |
@@ -150,13 +272,19 @@ static int ehci_platform_remove(struct platform_device *dev) | |||
150 | { | 272 | { |
151 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 273 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
152 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); | 274 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); |
275 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); | ||
276 | int clk; | ||
153 | 277 | ||
154 | usb_remove_hcd(hcd); | 278 | usb_remove_hcd(hcd); |
155 | usb_put_hcd(hcd); | ||
156 | 279 | ||
157 | if (pdata->power_off) | 280 | if (pdata->power_off) |
158 | pdata->power_off(dev); | 281 | pdata->power_off(dev); |
159 | 282 | ||
283 | for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) | ||
284 | clk_put(priv->clks[clk]); | ||
285 | |||
286 | usb_put_hcd(hcd); | ||
287 | |||
160 | if (pdata == &ehci_platform_defaults) | 288 | if (pdata == &ehci_platform_defaults) |
161 | dev->dev.platform_data = NULL; | 289 | dev->dev.platform_data = NULL; |
162 | 290 | ||
@@ -207,8 +335,10 @@ static int ehci_platform_resume(struct device *dev) | |||
207 | static const struct of_device_id vt8500_ehci_ids[] = { | 335 | static const struct of_device_id vt8500_ehci_ids[] = { |
208 | { .compatible = "via,vt8500-ehci", }, | 336 | { .compatible = "via,vt8500-ehci", }, |
209 | { .compatible = "wm,prizm-ehci", }, | 337 | { .compatible = "wm,prizm-ehci", }, |
338 | { .compatible = "generic-ehci", }, | ||
210 | {} | 339 | {} |
211 | }; | 340 | }; |
341 | MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); | ||
212 | 342 | ||
213 | static const struct platform_device_id ehci_platform_table[] = { | 343 | static const struct platform_device_id ehci_platform_table[] = { |
214 | { "ehci-platform", 0 }, | 344 | { "ehci-platform", 0 }, |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index af28b748e87a..27ac6ad53c3d 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -38,10 +38,6 @@ | |||
38 | 38 | ||
39 | #include "ehci.h" | 39 | #include "ehci.h" |
40 | 40 | ||
41 | #define TEGRA_USB_BASE 0xC5000000 | ||
42 | #define TEGRA_USB2_BASE 0xC5004000 | ||
43 | #define TEGRA_USB3_BASE 0xC5008000 | ||
44 | |||
45 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) | 41 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) |
46 | 42 | ||
47 | #define TEGRA_USB_DMA_ALIGN 32 | 43 | #define TEGRA_USB_DMA_ALIGN 32 |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index e07669993f58..d0d8fadf7066 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
@@ -261,8 +261,44 @@ static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc) | |||
261 | dev_err(dev, "cannot listen to notifications: %d\n", result); | 261 | dev_err(dev, "cannot listen to notifications: %d\n", result); |
262 | goto error_stop; | 262 | goto error_stop; |
263 | } | 263 | } |
264 | /* | ||
265 | * If WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS is set, | ||
266 | * disable transfer notifications. | ||
267 | */ | ||
268 | if (hwahc->wa.quirks & | ||
269 | WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS) { | ||
270 | struct usb_host_interface *cur_altsetting = | ||
271 | hwahc->wa.usb_iface->cur_altsetting; | ||
272 | |||
273 | result = usb_control_msg(hwahc->wa.usb_dev, | ||
274 | usb_sndctrlpipe(hwahc->wa.usb_dev, 0), | ||
275 | WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS, | ||
276 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
277 | USB_RECIP_INTERFACE, | ||
278 | WA_REQ_ALEREON_FEATURE_SET, | ||
279 | cur_altsetting->desc.bInterfaceNumber, | ||
280 | NULL, 0, | ||
281 | USB_CTRL_SET_TIMEOUT); | ||
282 | /* | ||
283 | * If we successfully sent the control message, start DTI here | ||
284 | * because no transfer notifications will be received which is | ||
285 | * where DTI is normally started. | ||
286 | */ | ||
287 | if (result == 0) | ||
288 | result = wa_dti_start(&hwahc->wa); | ||
289 | else | ||
290 | result = 0; /* OK. Continue normally. */ | ||
291 | |||
292 | if (result < 0) { | ||
293 | dev_err(dev, "cannot start DTI: %d\n", result); | ||
294 | goto error_dti_start; | ||
295 | } | ||
296 | } | ||
297 | |||
264 | return result; | 298 | return result; |
265 | 299 | ||
300 | error_dti_start: | ||
301 | wa_nep_disarm(&hwahc->wa); | ||
266 | error_stop: | 302 | error_stop: |
267 | __wa_clear_feature(&hwahc->wa, WA_ENABLE); | 303 | __wa_clear_feature(&hwahc->wa, WA_ENABLE); |
268 | return result; | 304 | return result; |
@@ -827,10 +863,12 @@ static void hwahc_disconnect(struct usb_interface *usb_iface) | |||
827 | static struct usb_device_id hwahc_id_table[] = { | 863 | static struct usb_device_id hwahc_id_table[] = { |
828 | /* Alereon 5310 */ | 864 | /* Alereon 5310 */ |
829 | { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01), | 865 | { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01), |
830 | .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC }, | 866 | .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | |
867 | WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS }, | ||
831 | /* Alereon 5611 */ | 868 | /* Alereon 5611 */ |
832 | { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5611, 0xe0, 0x02, 0x01), | 869 | { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5611, 0xe0, 0x02, 0x01), |
833 | .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC }, | 870 | .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | |
871 | WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS }, | ||
834 | /* FIXME: use class labels for this */ | 872 | /* FIXME: use class labels for this */ |
835 | { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), }, | 873 | { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), }, |
836 | {}, | 874 | {}, |
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 68f674cd095f..b6002c951c5c 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2007 Michael Buesch <m@bues.ch> | 4 | * Copyright 2007 Michael Buesch <m@bues.ch> |
5 | * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de> | 5 | * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de> |
6 | * Copyright 2014 Hans de Goede <hdegoede@redhat.com> | ||
6 | * | 7 | * |
7 | * Derived from the OCHI-SSB driver | 8 | * Derived from the OCHI-SSB driver |
8 | * Derived from the OHCI-PCI driver | 9 | * Derived from the OHCI-PCI driver |
@@ -14,11 +15,14 @@ | |||
14 | * Licensed under the GNU/GPL. See COPYING for details. | 15 | * Licensed under the GNU/GPL. See COPYING for details. |
15 | */ | 16 | */ |
16 | 17 | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/hrtimer.h> | 20 | #include <linux/hrtimer.h> |
18 | #include <linux/io.h> | 21 | #include <linux/io.h> |
19 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 23 | #include <linux/module.h> |
21 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/phy/phy.h> | ||
22 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
23 | #include <linux/usb/ohci_pdriver.h> | 27 | #include <linux/usb/ohci_pdriver.h> |
24 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
@@ -27,6 +31,13 @@ | |||
27 | #include "ohci.h" | 31 | #include "ohci.h" |
28 | 32 | ||
29 | #define DRIVER_DESC "OHCI generic platform driver" | 33 | #define DRIVER_DESC "OHCI generic platform driver" |
34 | #define OHCI_MAX_CLKS 3 | ||
35 | #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) | ||
36 | |||
37 | struct ohci_platform_priv { | ||
38 | struct clk *clks[OHCI_MAX_CLKS]; | ||
39 | struct phy *phy; | ||
40 | }; | ||
30 | 41 | ||
31 | static const char hcd_name[] = "ohci-platform"; | 42 | static const char hcd_name[] = "ohci-platform"; |
32 | 43 | ||
@@ -36,10 +47,6 @@ static int ohci_platform_reset(struct usb_hcd *hcd) | |||
36 | struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev); | 47 | struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev); |
37 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 48 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
38 | 49 | ||
39 | if (pdata->big_endian_desc) | ||
40 | ohci->flags |= OHCI_QUIRK_BE_DESC; | ||
41 | if (pdata->big_endian_mmio) | ||
42 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
43 | if (pdata->no_big_frame_no) | 50 | if (pdata->no_big_frame_no) |
44 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | 51 | ohci->flags |= OHCI_QUIRK_FRAME_NO; |
45 | if (pdata->num_ports) | 52 | if (pdata->num_ports) |
@@ -48,11 +55,67 @@ static int ohci_platform_reset(struct usb_hcd *hcd) | |||
48 | return ohci_setup(hcd); | 55 | return ohci_setup(hcd); |
49 | } | 56 | } |
50 | 57 | ||
58 | static int ohci_platform_power_on(struct platform_device *dev) | ||
59 | { | ||
60 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
61 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); | ||
62 | int clk, ret; | ||
63 | |||
64 | for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { | ||
65 | ret = clk_prepare_enable(priv->clks[clk]); | ||
66 | if (ret) | ||
67 | goto err_disable_clks; | ||
68 | } | ||
69 | |||
70 | if (priv->phy) { | ||
71 | ret = phy_init(priv->phy); | ||
72 | if (ret) | ||
73 | goto err_disable_clks; | ||
74 | |||
75 | ret = phy_power_on(priv->phy); | ||
76 | if (ret) | ||
77 | goto err_exit_phy; | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | |||
82 | err_exit_phy: | ||
83 | phy_exit(priv->phy); | ||
84 | err_disable_clks: | ||
85 | while (--clk >= 0) | ||
86 | clk_disable_unprepare(priv->clks[clk]); | ||
87 | |||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | static void ohci_platform_power_off(struct platform_device *dev) | ||
92 | { | ||
93 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
94 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); | ||
95 | int clk; | ||
96 | |||
97 | if (priv->phy) { | ||
98 | phy_power_off(priv->phy); | ||
99 | phy_exit(priv->phy); | ||
100 | } | ||
101 | |||
102 | for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) | ||
103 | if (priv->clks[clk]) | ||
104 | clk_disable_unprepare(priv->clks[clk]); | ||
105 | } | ||
106 | |||
51 | static struct hc_driver __read_mostly ohci_platform_hc_driver; | 107 | static struct hc_driver __read_mostly ohci_platform_hc_driver; |
52 | 108 | ||
53 | static const struct ohci_driver_overrides platform_overrides __initconst = { | 109 | static const struct ohci_driver_overrides platform_overrides __initconst = { |
54 | .product_desc = "Generic Platform OHCI controller", | 110 | .product_desc = "Generic Platform OHCI controller", |
55 | .reset = ohci_platform_reset, | 111 | .reset = ohci_platform_reset, |
112 | .extra_priv_size = sizeof(struct ohci_platform_priv), | ||
113 | }; | ||
114 | |||
115 | static struct usb_ohci_pdata ohci_platform_defaults = { | ||
116 | .power_on = ohci_platform_power_on, | ||
117 | .power_suspend = ohci_platform_power_off, | ||
118 | .power_off = ohci_platform_power_off, | ||
56 | }; | 119 | }; |
57 | 120 | ||
58 | static int ohci_platform_probe(struct platform_device *dev) | 121 | static int ohci_platform_probe(struct platform_device *dev) |
@@ -60,17 +123,24 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
60 | struct usb_hcd *hcd; | 123 | struct usb_hcd *hcd; |
61 | struct resource *res_mem; | 124 | struct resource *res_mem; |
62 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); | 125 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); |
63 | int irq; | 126 | struct ohci_platform_priv *priv; |
64 | int err = -ENOMEM; | 127 | struct ohci_hcd *ohci; |
65 | 128 | int err, irq, clk = 0; | |
66 | if (!pdata) { | ||
67 | WARN_ON(1); | ||
68 | return -ENODEV; | ||
69 | } | ||
70 | 129 | ||
71 | if (usb_disabled()) | 130 | if (usb_disabled()) |
72 | return -ENODEV; | 131 | return -ENODEV; |
73 | 132 | ||
133 | /* | ||
134 | * Use reasonable defaults so platforms don't have to provide these | ||
135 | * with DT probing on ARM. | ||
136 | */ | ||
137 | if (!pdata) | ||
138 | pdata = &ohci_platform_defaults; | ||
139 | |||
140 | err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); | ||
141 | if (err) | ||
142 | return err; | ||
143 | |||
74 | irq = platform_get_irq(dev, 0); | 144 | irq = platform_get_irq(dev, 0); |
75 | if (irq < 0) { | 145 | if (irq < 0) { |
76 | dev_err(&dev->dev, "no irq provided"); | 146 | dev_err(&dev->dev, "no irq provided"); |
@@ -83,17 +153,72 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
83 | return -ENXIO; | 153 | return -ENXIO; |
84 | } | 154 | } |
85 | 155 | ||
156 | hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, | ||
157 | dev_name(&dev->dev)); | ||
158 | if (!hcd) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | platform_set_drvdata(dev, hcd); | ||
162 | dev->dev.platform_data = pdata; | ||
163 | priv = hcd_to_ohci_priv(hcd); | ||
164 | ohci = hcd_to_ohci(hcd); | ||
165 | |||
166 | if (pdata == &ohci_platform_defaults && dev->dev.of_node) { | ||
167 | if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) | ||
168 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
169 | |||
170 | if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) | ||
171 | ohci->flags |= OHCI_QUIRK_BE_DESC; | ||
172 | |||
173 | if (of_property_read_bool(dev->dev.of_node, "big-endian")) | ||
174 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | ||
175 | |||
176 | priv->phy = devm_phy_get(&dev->dev, "usb"); | ||
177 | if (IS_ERR(priv->phy)) { | ||
178 | err = PTR_ERR(priv->phy); | ||
179 | if (err == -EPROBE_DEFER) | ||
180 | goto err_put_hcd; | ||
181 | priv->phy = NULL; | ||
182 | } | ||
183 | |||
184 | for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { | ||
185 | priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); | ||
186 | if (IS_ERR(priv->clks[clk])) { | ||
187 | err = PTR_ERR(priv->clks[clk]); | ||
188 | if (err == -EPROBE_DEFER) | ||
189 | goto err_put_clks; | ||
190 | priv->clks[clk] = NULL; | ||
191 | break; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if (pdata->big_endian_desc) | ||
197 | ohci->flags |= OHCI_QUIRK_BE_DESC; | ||
198 | if (pdata->big_endian_mmio) | ||
199 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
200 | |||
201 | #ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
202 | if (ohci->flags & OHCI_QUIRK_BE_MMIO) { | ||
203 | dev_err(&dev->dev, | ||
204 | "Error: CONFIG_USB_OHCI_BIG_ENDIAN_MMIO not set\n"); | ||
205 | err = -EINVAL; | ||
206 | goto err_put_clks; | ||
207 | } | ||
208 | #endif | ||
209 | #ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC | ||
210 | if (ohci->flags & OHCI_QUIRK_BE_DESC) { | ||
211 | dev_err(&dev->dev, | ||
212 | "Error: CONFIG_USB_OHCI_BIG_ENDIAN_DESC not set\n"); | ||
213 | err = -EINVAL; | ||
214 | goto err_put_clks; | ||
215 | } | ||
216 | #endif | ||
217 | |||
86 | if (pdata->power_on) { | 218 | if (pdata->power_on) { |
87 | err = pdata->power_on(dev); | 219 | err = pdata->power_on(dev); |
88 | if (err < 0) | 220 | if (err < 0) |
89 | return err; | 221 | goto err_put_clks; |
90 | } | ||
91 | |||
92 | hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, | ||
93 | dev_name(&dev->dev)); | ||
94 | if (!hcd) { | ||
95 | err = -ENOMEM; | ||
96 | goto err_power; | ||
97 | } | 222 | } |
98 | 223 | ||
99 | hcd->rsrc_start = res_mem->start; | 224 | hcd->rsrc_start = res_mem->start; |
@@ -102,11 +227,11 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
102 | hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); | 227 | hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); |
103 | if (IS_ERR(hcd->regs)) { | 228 | if (IS_ERR(hcd->regs)) { |
104 | err = PTR_ERR(hcd->regs); | 229 | err = PTR_ERR(hcd->regs); |
105 | goto err_put_hcd; | 230 | goto err_power; |
106 | } | 231 | } |
107 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | 232 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
108 | if (err) | 233 | if (err) |
109 | goto err_put_hcd; | 234 | goto err_power; |
110 | 235 | ||
111 | device_wakeup_enable(hcd->self.controller); | 236 | device_wakeup_enable(hcd->self.controller); |
112 | 237 | ||
@@ -114,11 +239,17 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
114 | 239 | ||
115 | return err; | 240 | return err; |
116 | 241 | ||
117 | err_put_hcd: | ||
118 | usb_put_hcd(hcd); | ||
119 | err_power: | 242 | err_power: |
120 | if (pdata->power_off) | 243 | if (pdata->power_off) |
121 | pdata->power_off(dev); | 244 | pdata->power_off(dev); |
245 | err_put_clks: | ||
246 | while (--clk >= 0) | ||
247 | clk_put(priv->clks[clk]); | ||
248 | err_put_hcd: | ||
249 | if (pdata == &ohci_platform_defaults) | ||
250 | dev->dev.platform_data = NULL; | ||
251 | |||
252 | usb_put_hcd(hcd); | ||
122 | 253 | ||
123 | return err; | 254 | return err; |
124 | } | 255 | } |
@@ -127,13 +258,22 @@ static int ohci_platform_remove(struct platform_device *dev) | |||
127 | { | 258 | { |
128 | struct usb_hcd *hcd = platform_get_drvdata(dev); | 259 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
129 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); | 260 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); |
261 | struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); | ||
262 | int clk; | ||
130 | 263 | ||
131 | usb_remove_hcd(hcd); | 264 | usb_remove_hcd(hcd); |
132 | usb_put_hcd(hcd); | ||
133 | 265 | ||
134 | if (pdata->power_off) | 266 | if (pdata->power_off) |
135 | pdata->power_off(dev); | 267 | pdata->power_off(dev); |
136 | 268 | ||
269 | for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) | ||
270 | clk_put(priv->clks[clk]); | ||
271 | |||
272 | usb_put_hcd(hcd); | ||
273 | |||
274 | if (pdata == &ohci_platform_defaults) | ||
275 | dev->dev.platform_data = NULL; | ||
276 | |||
137 | return 0; | 277 | return 0; |
138 | } | 278 | } |
139 | 279 | ||
@@ -180,6 +320,12 @@ static int ohci_platform_resume(struct device *dev) | |||
180 | #define ohci_platform_resume NULL | 320 | #define ohci_platform_resume NULL |
181 | #endif /* CONFIG_PM */ | 321 | #endif /* CONFIG_PM */ |
182 | 322 | ||
323 | static const struct of_device_id ohci_platform_ids[] = { | ||
324 | { .compatible = "generic-ohci", }, | ||
325 | { } | ||
326 | }; | ||
327 | MODULE_DEVICE_TABLE(of, ohci_platform_ids); | ||
328 | |||
183 | static const struct platform_device_id ohci_platform_table[] = { | 329 | static const struct platform_device_id ohci_platform_table[] = { |
184 | { "ohci-platform", 0 }, | 330 | { "ohci-platform", 0 }, |
185 | { } | 331 | { } |
@@ -200,6 +346,7 @@ static struct platform_driver ohci_platform_driver = { | |||
200 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
201 | .name = "ohci-platform", | 347 | .name = "ohci-platform", |
202 | .pm = &ohci_platform_pm_ops, | 348 | .pm = &ohci_platform_pm_ops, |
349 | .of_match_table = ohci_platform_ids, | ||
203 | } | 350 | } |
204 | }; | 351 | }; |
205 | 352 | ||
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 44e6c9da8892..01833ab2b5c3 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c | |||
@@ -148,6 +148,7 @@ static void uhci_hcd_platform_shutdown(struct platform_device *op) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | static const struct of_device_id platform_uhci_ids[] = { | 150 | static const struct of_device_id platform_uhci_ids[] = { |
151 | { .compatible = "generic-uhci", }, | ||
151 | { .compatible = "platform-uhci", }, | 152 | { .compatible = "platform-uhci", }, |
152 | {} | 153 | {} |
153 | }; | 154 | }; |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 9992fbfec85f..1ad6bc1951c7 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -732,9 +732,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
732 | /* Set the U1 and U2 exit latencies. */ | 732 | /* Set the U1 and U2 exit latencies. */ |
733 | memcpy(buf, &usb_bos_descriptor, | 733 | memcpy(buf, &usb_bos_descriptor, |
734 | USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE); | 734 | USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE); |
735 | temp = readl(&xhci->cap_regs->hcs_params3); | 735 | if ((xhci->quirks & XHCI_LPM_SUPPORT)) { |
736 | buf[12] = HCS_U1_LATENCY(temp); | 736 | temp = readl(&xhci->cap_regs->hcs_params3); |
737 | put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); | 737 | buf[12] = HCS_U1_LATENCY(temp); |
738 | put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); | ||
739 | } | ||
738 | 740 | ||
739 | /* Indicate whether the host has LTM support. */ | 741 | /* Indicate whether the host has LTM support. */ |
740 | temp = readl(&xhci->cap_regs->hcc_params); | 742 | temp = readl(&xhci->cap_regs->hcc_params); |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bce4391a0e7d..c089668308ad 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -149,14 +149,140 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | /* | ||
153 | * We need a radix tree for mapping physical addresses of TRBs to which stream | ||
154 | * ID they belong to. We need to do this because the host controller won't tell | ||
155 | * us which stream ring the TRB came from. We could store the stream ID in an | ||
156 | * event data TRB, but that doesn't help us for the cancellation case, since the | ||
157 | * endpoint may stop before it reaches that event data TRB. | ||
158 | * | ||
159 | * The radix tree maps the upper portion of the TRB DMA address to a ring | ||
160 | * segment that has the same upper portion of DMA addresses. For example, say I | ||
161 | * have segments of size 1KB, that are always 1KB aligned. A segment may | ||
162 | * start at 0x10c91000 and end at 0x10c913f0. If I use the upper 10 bits, the | ||
163 | * key to the stream ID is 0x43244. I can use the DMA address of the TRB to | ||
164 | * pass the radix tree a key to get the right stream ID: | ||
165 | * | ||
166 | * 0x10c90fff >> 10 = 0x43243 | ||
167 | * 0x10c912c0 >> 10 = 0x43244 | ||
168 | * 0x10c91400 >> 10 = 0x43245 | ||
169 | * | ||
170 | * Obviously, only those TRBs with DMA addresses that are within the segment | ||
171 | * will make the radix tree return the stream ID for that ring. | ||
172 | * | ||
173 | * Caveats for the radix tree: | ||
174 | * | ||
175 | * The radix tree uses an unsigned long as a key pair. On 32-bit systems, an | ||
176 | * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be | ||
177 | * 64-bits. Since we only request 32-bit DMA addresses, we can use that as the | ||
178 | * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit | ||
179 | * PCI DMA addresses on a 64-bit system). There might be a problem on 32-bit | ||
180 | * extended systems (where the DMA address can be bigger than 32-bits), | ||
181 | * if we allow the PCI dma mask to be bigger than 32-bits. So don't do that. | ||
182 | */ | ||
183 | static int xhci_insert_segment_mapping(struct radix_tree_root *trb_address_map, | ||
184 | struct xhci_ring *ring, | ||
185 | struct xhci_segment *seg, | ||
186 | gfp_t mem_flags) | ||
187 | { | ||
188 | unsigned long key; | ||
189 | int ret; | ||
190 | |||
191 | key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); | ||
192 | /* Skip any segments that were already added. */ | ||
193 | if (radix_tree_lookup(trb_address_map, key)) | ||
194 | return 0; | ||
195 | |||
196 | ret = radix_tree_maybe_preload(mem_flags); | ||
197 | if (ret) | ||
198 | return ret; | ||
199 | ret = radix_tree_insert(trb_address_map, | ||
200 | key, ring); | ||
201 | radix_tree_preload_end(); | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | static void xhci_remove_segment_mapping(struct radix_tree_root *trb_address_map, | ||
206 | struct xhci_segment *seg) | ||
207 | { | ||
208 | unsigned long key; | ||
209 | |||
210 | key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); | ||
211 | if (radix_tree_lookup(trb_address_map, key)) | ||
212 | radix_tree_delete(trb_address_map, key); | ||
213 | } | ||
214 | |||
215 | static int xhci_update_stream_segment_mapping( | ||
216 | struct radix_tree_root *trb_address_map, | ||
217 | struct xhci_ring *ring, | ||
218 | struct xhci_segment *first_seg, | ||
219 | struct xhci_segment *last_seg, | ||
220 | gfp_t mem_flags) | ||
221 | { | ||
222 | struct xhci_segment *seg; | ||
223 | struct xhci_segment *failed_seg; | ||
224 | int ret; | ||
225 | |||
226 | if (WARN_ON_ONCE(trb_address_map == NULL)) | ||
227 | return 0; | ||
228 | |||
229 | seg = first_seg; | ||
230 | do { | ||
231 | ret = xhci_insert_segment_mapping(trb_address_map, | ||
232 | ring, seg, mem_flags); | ||
233 | if (ret) | ||
234 | goto remove_streams; | ||
235 | if (seg == last_seg) | ||
236 | return 0; | ||
237 | seg = seg->next; | ||
238 | } while (seg != first_seg); | ||
239 | |||
240 | return 0; | ||
241 | |||
242 | remove_streams: | ||
243 | failed_seg = seg; | ||
244 | seg = first_seg; | ||
245 | do { | ||
246 | xhci_remove_segment_mapping(trb_address_map, seg); | ||
247 | if (seg == failed_seg) | ||
248 | return ret; | ||
249 | seg = seg->next; | ||
250 | } while (seg != first_seg); | ||
251 | |||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | static void xhci_remove_stream_mapping(struct xhci_ring *ring) | ||
256 | { | ||
257 | struct xhci_segment *seg; | ||
258 | |||
259 | if (WARN_ON_ONCE(ring->trb_address_map == NULL)) | ||
260 | return; | ||
261 | |||
262 | seg = ring->first_seg; | ||
263 | do { | ||
264 | xhci_remove_segment_mapping(ring->trb_address_map, seg); | ||
265 | seg = seg->next; | ||
266 | } while (seg != ring->first_seg); | ||
267 | } | ||
268 | |||
269 | static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags) | ||
270 | { | ||
271 | return xhci_update_stream_segment_mapping(ring->trb_address_map, ring, | ||
272 | ring->first_seg, ring->last_seg, mem_flags); | ||
273 | } | ||
274 | |||
152 | /* XXX: Do we need the hcd structure in all these functions? */ | 275 | /* XXX: Do we need the hcd structure in all these functions? */ |
153 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) | 276 | void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) |
154 | { | 277 | { |
155 | if (!ring) | 278 | if (!ring) |
156 | return; | 279 | return; |
157 | 280 | ||
158 | if (ring->first_seg) | 281 | if (ring->first_seg) { |
282 | if (ring->type == TYPE_STREAM) | ||
283 | xhci_remove_stream_mapping(ring); | ||
159 | xhci_free_segments_for_ring(xhci, ring->first_seg); | 284 | xhci_free_segments_for_ring(xhci, ring->first_seg); |
285 | } | ||
160 | 286 | ||
161 | kfree(ring); | 287 | kfree(ring); |
162 | } | 288 | } |
@@ -349,6 +475,21 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
349 | if (ret) | 475 | if (ret) |
350 | return -ENOMEM; | 476 | return -ENOMEM; |
351 | 477 | ||
478 | if (ring->type == TYPE_STREAM) | ||
479 | ret = xhci_update_stream_segment_mapping(ring->trb_address_map, | ||
480 | ring, first, last, flags); | ||
481 | if (ret) { | ||
482 | struct xhci_segment *next; | ||
483 | do { | ||
484 | next = first->next; | ||
485 | xhci_segment_free(xhci, first); | ||
486 | if (first == last) | ||
487 | break; | ||
488 | first = next; | ||
489 | } while (true); | ||
490 | return ret; | ||
491 | } | ||
492 | |||
352 | xhci_link_rings(xhci, ring, first, last, num_segs); | 493 | xhci_link_rings(xhci, ring, first, last, num_segs); |
353 | xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, | 494 | xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, |
354 | "ring expansion succeed, now has %d segments", | 495 | "ring expansion succeed, now has %d segments", |
@@ -434,12 +575,12 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci, | |||
434 | struct xhci_stream_ctx *stream_ctx, dma_addr_t dma) | 575 | struct xhci_stream_ctx *stream_ctx, dma_addr_t dma) |
435 | { | 576 | { |
436 | struct device *dev = xhci_to_hcd(xhci)->self.controller; | 577 | struct device *dev = xhci_to_hcd(xhci)->self.controller; |
578 | size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs; | ||
437 | 579 | ||
438 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) | 580 | if (size > MEDIUM_STREAM_ARRAY_SIZE) |
439 | dma_free_coherent(dev, | 581 | dma_free_coherent(dev, size, |
440 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, | ||
441 | stream_ctx, dma); | 582 | stream_ctx, dma); |
442 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) | 583 | else if (size <= SMALL_STREAM_ARRAY_SIZE) |
443 | return dma_pool_free(xhci->small_streams_pool, | 584 | return dma_pool_free(xhci->small_streams_pool, |
444 | stream_ctx, dma); | 585 | stream_ctx, dma); |
445 | else | 586 | else |
@@ -462,12 +603,12 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci, | |||
462 | gfp_t mem_flags) | 603 | gfp_t mem_flags) |
463 | { | 604 | { |
464 | struct device *dev = xhci_to_hcd(xhci)->self.controller; | 605 | struct device *dev = xhci_to_hcd(xhci)->self.controller; |
606 | size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs; | ||
465 | 607 | ||
466 | if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) | 608 | if (size > MEDIUM_STREAM_ARRAY_SIZE) |
467 | return dma_alloc_coherent(dev, | 609 | return dma_alloc_coherent(dev, size, |
468 | sizeof(struct xhci_stream_ctx)*num_stream_ctxs, | ||
469 | dma, mem_flags); | 610 | dma, mem_flags); |
470 | else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) | 611 | else if (size <= SMALL_STREAM_ARRAY_SIZE) |
471 | return dma_pool_alloc(xhci->small_streams_pool, | 612 | return dma_pool_alloc(xhci->small_streams_pool, |
472 | mem_flags, dma); | 613 | mem_flags, dma); |
473 | else | 614 | else |
@@ -510,36 +651,6 @@ struct xhci_ring *xhci_stream_id_to_ring( | |||
510 | * The number of stream contexts in the stream context array may be bigger than | 651 | * The number of stream contexts in the stream context array may be bigger than |
511 | * the number of streams the driver wants to use. This is because the number of | 652 | * the number of streams the driver wants to use. This is because the number of |
512 | * stream context array entries must be a power of two. | 653 | * stream context array entries must be a power of two. |
513 | * | ||
514 | * We need a radix tree for mapping physical addresses of TRBs to which stream | ||
515 | * ID they belong to. We need to do this because the host controller won't tell | ||
516 | * us which stream ring the TRB came from. We could store the stream ID in an | ||
517 | * event data TRB, but that doesn't help us for the cancellation case, since the | ||
518 | * endpoint may stop before it reaches that event data TRB. | ||
519 | * | ||
520 | * The radix tree maps the upper portion of the TRB DMA address to a ring | ||
521 | * segment that has the same upper portion of DMA addresses. For example, say I | ||
522 | * have segments of size 1KB, that are always 64-byte aligned. A segment may | ||
523 | * start at 0x10c91000 and end at 0x10c913f0. If I use the upper 10 bits, the | ||
524 | * key to the stream ID is 0x43244. I can use the DMA address of the TRB to | ||
525 | * pass the radix tree a key to get the right stream ID: | ||
526 | * | ||
527 | * 0x10c90fff >> 10 = 0x43243 | ||
528 | * 0x10c912c0 >> 10 = 0x43244 | ||
529 | * 0x10c91400 >> 10 = 0x43245 | ||
530 | * | ||
531 | * Obviously, only those TRBs with DMA addresses that are within the segment | ||
532 | * will make the radix tree return the stream ID for that ring. | ||
533 | * | ||
534 | * Caveats for the radix tree: | ||
535 | * | ||
536 | * The radix tree uses an unsigned long as a key pair. On 32-bit systems, an | ||
537 | * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be | ||
538 | * 64-bits. Since we only request 32-bit DMA addresses, we can use that as the | ||
539 | * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit | ||
540 | * PCI DMA addresses on a 64-bit system). There might be a problem on 32-bit | ||
541 | * extended systems (where the DMA address can be bigger than 32-bits), | ||
542 | * if we allow the PCI dma mask to be bigger than 32-bits. So don't do that. | ||
543 | */ | 654 | */ |
544 | struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, | 655 | struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, |
545 | unsigned int num_stream_ctxs, | 656 | unsigned int num_stream_ctxs, |
@@ -548,7 +659,6 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, | |||
548 | struct xhci_stream_info *stream_info; | 659 | struct xhci_stream_info *stream_info; |
549 | u32 cur_stream; | 660 | u32 cur_stream; |
550 | struct xhci_ring *cur_ring; | 661 | struct xhci_ring *cur_ring; |
551 | unsigned long key; | ||
552 | u64 addr; | 662 | u64 addr; |
553 | int ret; | 663 | int ret; |
554 | 664 | ||
@@ -603,6 +713,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, | |||
603 | if (!cur_ring) | 713 | if (!cur_ring) |
604 | goto cleanup_rings; | 714 | goto cleanup_rings; |
605 | cur_ring->stream_id = cur_stream; | 715 | cur_ring->stream_id = cur_stream; |
716 | cur_ring->trb_address_map = &stream_info->trb_address_map; | ||
606 | /* Set deq ptr, cycle bit, and stream context type */ | 717 | /* Set deq ptr, cycle bit, and stream context type */ |
607 | addr = cur_ring->first_seg->dma | | 718 | addr = cur_ring->first_seg->dma | |
608 | SCT_FOR_CTX(SCT_PRI_TR) | | 719 | SCT_FOR_CTX(SCT_PRI_TR) | |
@@ -612,10 +723,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, | |||
612 | xhci_dbg(xhci, "Setting stream %d ring ptr to 0x%08llx\n", | 723 | xhci_dbg(xhci, "Setting stream %d ring ptr to 0x%08llx\n", |
613 | cur_stream, (unsigned long long) addr); | 724 | cur_stream, (unsigned long long) addr); |
614 | 725 | ||
615 | key = (unsigned long) | 726 | ret = xhci_update_stream_mapping(cur_ring, mem_flags); |
616 | (cur_ring->first_seg->dma >> TRB_SEGMENT_SHIFT); | ||
617 | ret = radix_tree_insert(&stream_info->trb_address_map, | ||
618 | key, cur_ring); | ||
619 | if (ret) { | 727 | if (ret) { |
620 | xhci_ring_free(xhci, cur_ring); | 728 | xhci_ring_free(xhci, cur_ring); |
621 | stream_info->stream_rings[cur_stream] = NULL; | 729 | stream_info->stream_rings[cur_stream] = NULL; |
@@ -635,9 +743,6 @@ cleanup_rings: | |||
635 | for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { | 743 | for (cur_stream = 1; cur_stream < num_streams; cur_stream++) { |
636 | cur_ring = stream_info->stream_rings[cur_stream]; | 744 | cur_ring = stream_info->stream_rings[cur_stream]; |
637 | if (cur_ring) { | 745 | if (cur_ring) { |
638 | addr = cur_ring->first_seg->dma; | ||
639 | radix_tree_delete(&stream_info->trb_address_map, | ||
640 | addr >> TRB_SEGMENT_SHIFT); | ||
641 | xhci_ring_free(xhci, cur_ring); | 746 | xhci_ring_free(xhci, cur_ring); |
642 | stream_info->stream_rings[cur_stream] = NULL; | 747 | stream_info->stream_rings[cur_stream] = NULL; |
643 | } | 748 | } |
@@ -698,7 +803,6 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, | |||
698 | { | 803 | { |
699 | int cur_stream; | 804 | int cur_stream; |
700 | struct xhci_ring *cur_ring; | 805 | struct xhci_ring *cur_ring; |
701 | dma_addr_t addr; | ||
702 | 806 | ||
703 | if (!stream_info) | 807 | if (!stream_info) |
704 | return; | 808 | return; |
@@ -707,9 +811,6 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, | |||
707 | cur_stream++) { | 811 | cur_stream++) { |
708 | cur_ring = stream_info->stream_rings[cur_stream]; | 812 | cur_ring = stream_info->stream_rings[cur_stream]; |
709 | if (cur_ring) { | 813 | if (cur_ring) { |
710 | addr = cur_ring->first_seg->dma; | ||
711 | radix_tree_delete(&stream_info->trb_address_map, | ||
712 | addr >> TRB_SEGMENT_SHIFT); | ||
713 | xhci_ring_free(xhci, cur_ring); | 814 | xhci_ring_free(xhci, cur_ring); |
714 | stream_info->stream_rings[cur_stream] = NULL; | 815 | stream_info->stream_rings[cur_stream] = NULL; |
715 | } | 816 | } |
@@ -1711,7 +1812,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1711 | 1812 | ||
1712 | if (xhci->lpm_command) | 1813 | if (xhci->lpm_command) |
1713 | xhci_free_command(xhci, xhci->lpm_command); | 1814 | xhci_free_command(xhci, xhci->lpm_command); |
1714 | xhci->cmd_ring_reserved_trbs = 0; | ||
1715 | if (xhci->cmd_ring) | 1815 | if (xhci->cmd_ring) |
1716 | xhci_ring_free(xhci, xhci->cmd_ring); | 1816 | xhci_ring_free(xhci, xhci->cmd_ring); |
1717 | xhci->cmd_ring = NULL; | 1817 | xhci->cmd_ring = NULL; |
@@ -1776,6 +1876,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1776 | } | 1876 | } |
1777 | 1877 | ||
1778 | no_bw: | 1878 | no_bw: |
1879 | xhci->cmd_ring_reserved_trbs = 0; | ||
1779 | xhci->num_usb2_ports = 0; | 1880 | xhci->num_usb2_ports = 0; |
1780 | xhci->num_usb3_ports = 0; | 1881 | xhci->num_usb3_ports = 0; |
1781 | xhci->num_active_eps = 0; | 1882 | xhci->num_active_eps = 0; |
@@ -2274,11 +2375,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2274 | /* | 2375 | /* |
2275 | * Initialize the ring segment pool. The ring must be a contiguous | 2376 | * Initialize the ring segment pool. The ring must be a contiguous |
2276 | * structure comprised of TRBs. The TRBs must be 16 byte aligned, | 2377 | * structure comprised of TRBs. The TRBs must be 16 byte aligned, |
2277 | * however, the command ring segment needs 64-byte aligned segments, | 2378 | * however, the command ring segment needs 64-byte aligned segments |
2278 | * so we pick the greater alignment need. | 2379 | * and our use of dma addresses in the trb_address_map radix tree needs |
2380 | * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. | ||
2279 | */ | 2381 | */ |
2280 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, | 2382 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, |
2281 | TRB_SEGMENT_SIZE, 64, xhci->page_size); | 2383 | TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); |
2282 | 2384 | ||
2283 | /* See Table 46 and Note on Figure 55 */ | 2385 | /* See Table 46 and Note on Figure 55 */ |
2284 | xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, | 2386 | xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 04f986d9234f..47390e369cd4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -190,6 +190,10 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
190 | struct usb_hcd *hcd; | 190 | struct usb_hcd *hcd; |
191 | 191 | ||
192 | driver = (struct hc_driver *)id->driver_data; | 192 | driver = (struct hc_driver *)id->driver_data; |
193 | |||
194 | /* Prevent runtime suspending between USB-2 and USB-3 initialization */ | ||
195 | pm_runtime_get_noresume(&dev->dev); | ||
196 | |||
193 | /* Register the USB 2.0 roothub. | 197 | /* Register the USB 2.0 roothub. |
194 | * FIXME: USB core must know to register the USB 2.0 roothub first. | 198 | * FIXME: USB core must know to register the USB 2.0 roothub first. |
195 | * This is sort of silly, because we could just set the HCD driver flags | 199 | * This is sort of silly, because we could just set the HCD driver flags |
@@ -199,7 +203,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
199 | retval = usb_hcd_pci_probe(dev, id); | 203 | retval = usb_hcd_pci_probe(dev, id); |
200 | 204 | ||
201 | if (retval) | 205 | if (retval) |
202 | return retval; | 206 | goto put_runtime_pm; |
203 | 207 | ||
204 | /* USB 2.0 roothub is stored in the PCI device now. */ | 208 | /* USB 2.0 roothub is stored in the PCI device now. */ |
205 | hcd = dev_get_drvdata(&dev->dev); | 209 | hcd = dev_get_drvdata(&dev->dev); |
@@ -222,11 +226,11 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
222 | goto put_usb3_hcd; | 226 | goto put_usb3_hcd; |
223 | /* Roothub already marked as USB 3.0 speed */ | 227 | /* Roothub already marked as USB 3.0 speed */ |
224 | 228 | ||
225 | /* We know the LPM timeout algorithms for this host, let the USB core | 229 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) |
226 | * enable and disable LPM for devices under the USB 3.0 roothub. | 230 | xhci->shared_hcd->can_do_streams = 1; |
227 | */ | 231 | |
228 | if (xhci->quirks & XHCI_LPM_SUPPORT) | 232 | /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ |
229 | hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1; | 233 | pm_runtime_put_noidle(&dev->dev); |
230 | 234 | ||
231 | return 0; | 235 | return 0; |
232 | 236 | ||
@@ -234,6 +238,8 @@ put_usb3_hcd: | |||
234 | usb_put_hcd(xhci->shared_hcd); | 238 | usb_put_hcd(xhci->shared_hcd); |
235 | dealloc_usb2_hcd: | 239 | dealloc_usb2_hcd: |
236 | usb_hcd_pci_remove(dev); | 240 | usb_hcd_pci_remove(dev); |
241 | put_runtime_pm: | ||
242 | pm_runtime_put_noidle(&dev->dev); | ||
237 | return retval; | 243 | return retval; |
238 | } | 244 | } |
239 | 245 | ||
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 8abda5c73ca1..151901ce1ba9 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -158,6 +158,9 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
158 | */ | 158 | */ |
159 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | 159 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; |
160 | 160 | ||
161 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) | ||
162 | xhci->shared_hcd->can_do_streams = 1; | ||
163 | |||
161 | ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); | 164 | ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); |
162 | if (ret) | 165 | if (ret) |
163 | goto put_usb3_hcd; | 166 | goto put_usb3_hcd; |
@@ -226,6 +229,7 @@ static const struct dev_pm_ops xhci_plat_pm_ops = { | |||
226 | 229 | ||
227 | #ifdef CONFIG_OF | 230 | #ifdef CONFIG_OF |
228 | static const struct of_device_id usb_xhci_of_match[] = { | 231 | static const struct of_device_id usb_xhci_of_match[] = { |
232 | { .compatible = "generic-xhci" }, | ||
229 | { .compatible = "xhci-platform" }, | 233 | { .compatible = "xhci-platform" }, |
230 | { }, | 234 | { }, |
231 | }; | 235 | }; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0ed64eb68e48..5f926bea5ab1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -546,9 +546,9 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
546 | struct xhci_dequeue_state *state) | 546 | struct xhci_dequeue_state *state) |
547 | { | 547 | { |
548 | struct xhci_virt_device *dev = xhci->devs[slot_id]; | 548 | struct xhci_virt_device *dev = xhci->devs[slot_id]; |
549 | struct xhci_virt_ep *ep = &dev->eps[ep_index]; | ||
549 | struct xhci_ring *ep_ring; | 550 | struct xhci_ring *ep_ring; |
550 | struct xhci_generic_trb *trb; | 551 | struct xhci_generic_trb *trb; |
551 | struct xhci_ep_ctx *ep_ctx; | ||
552 | dma_addr_t addr; | 552 | dma_addr_t addr; |
553 | 553 | ||
554 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, | 554 | ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, |
@@ -573,8 +573,16 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, | |||
573 | /* Dig out the cycle state saved by the xHC during the stop ep cmd */ | 573 | /* Dig out the cycle state saved by the xHC during the stop ep cmd */ |
574 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 574 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
575 | "Finding endpoint context"); | 575 | "Finding endpoint context"); |
576 | ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); | 576 | /* 4.6.9 the css flag is written to the stream context for streams */ |
577 | state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); | 577 | if (ep->ep_state & EP_HAS_STREAMS) { |
578 | struct xhci_stream_ctx *ctx = | ||
579 | &ep->stream_info->stream_ctx_array[stream_id]; | ||
580 | state->new_cycle_state = 0x1 & le64_to_cpu(ctx->stream_ring); | ||
581 | } else { | ||
582 | struct xhci_ep_ctx *ep_ctx | ||
583 | = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); | ||
584 | state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); | ||
585 | } | ||
578 | 586 | ||
579 | state->new_deq_ptr = cur_td->last_trb; | 587 | state->new_deq_ptr = cur_td->last_trb; |
580 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 588 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
@@ -892,6 +900,57 @@ remove_finished_td: | |||
892 | /* Return to the event handler with xhci->lock re-acquired */ | 900 | /* Return to the event handler with xhci->lock re-acquired */ |
893 | } | 901 | } |
894 | 902 | ||
903 | static void xhci_kill_ring_urbs(struct xhci_hcd *xhci, struct xhci_ring *ring) | ||
904 | { | ||
905 | struct xhci_td *cur_td; | ||
906 | |||
907 | while (!list_empty(&ring->td_list)) { | ||
908 | cur_td = list_first_entry(&ring->td_list, | ||
909 | struct xhci_td, td_list); | ||
910 | list_del_init(&cur_td->td_list); | ||
911 | if (!list_empty(&cur_td->cancelled_td_list)) | ||
912 | list_del_init(&cur_td->cancelled_td_list); | ||
913 | xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN); | ||
914 | } | ||
915 | } | ||
916 | |||
917 | static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, | ||
918 | int slot_id, int ep_index) | ||
919 | { | ||
920 | struct xhci_td *cur_td; | ||
921 | struct xhci_virt_ep *ep; | ||
922 | struct xhci_ring *ring; | ||
923 | |||
924 | ep = &xhci->devs[slot_id]->eps[ep_index]; | ||
925 | if ((ep->ep_state & EP_HAS_STREAMS) || | ||
926 | (ep->ep_state & EP_GETTING_NO_STREAMS)) { | ||
927 | int stream_id; | ||
928 | |||
929 | for (stream_id = 0; stream_id < ep->stream_info->num_streams; | ||
930 | stream_id++) { | ||
931 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | ||
932 | "Killing URBs for slot ID %u, ep index %u, stream %u", | ||
933 | slot_id, ep_index, stream_id + 1); | ||
934 | xhci_kill_ring_urbs(xhci, | ||
935 | ep->stream_info->stream_rings[stream_id]); | ||
936 | } | ||
937 | } else { | ||
938 | ring = ep->ring; | ||
939 | if (!ring) | ||
940 | return; | ||
941 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | ||
942 | "Killing URBs for slot ID %u, ep index %u", | ||
943 | slot_id, ep_index); | ||
944 | xhci_kill_ring_urbs(xhci, ring); | ||
945 | } | ||
946 | while (!list_empty(&ep->cancelled_td_list)) { | ||
947 | cur_td = list_first_entry(&ep->cancelled_td_list, | ||
948 | struct xhci_td, cancelled_td_list); | ||
949 | list_del_init(&cur_td->cancelled_td_list); | ||
950 | xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN); | ||
951 | } | ||
952 | } | ||
953 | |||
895 | /* Watchdog timer function for when a stop endpoint command fails to complete. | 954 | /* Watchdog timer function for when a stop endpoint command fails to complete. |
896 | * In this case, we assume the host controller is broken or dying or dead. The | 955 | * In this case, we assume the host controller is broken or dying or dead. The |
897 | * host may still be completing some other events, so we have to be careful to | 956 | * host may still be completing some other events, so we have to be careful to |
@@ -915,9 +974,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
915 | { | 974 | { |
916 | struct xhci_hcd *xhci; | 975 | struct xhci_hcd *xhci; |
917 | struct xhci_virt_ep *ep; | 976 | struct xhci_virt_ep *ep; |
918 | struct xhci_virt_ep *temp_ep; | ||
919 | struct xhci_ring *ring; | ||
920 | struct xhci_td *cur_td; | ||
921 | int ret, i, j; | 977 | int ret, i, j; |
922 | unsigned long flags; | 978 | unsigned long flags; |
923 | 979 | ||
@@ -974,34 +1030,8 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) | |||
974 | for (i = 0; i < MAX_HC_SLOTS; i++) { | 1030 | for (i = 0; i < MAX_HC_SLOTS; i++) { |
975 | if (!xhci->devs[i]) | 1031 | if (!xhci->devs[i]) |
976 | continue; | 1032 | continue; |
977 | for (j = 0; j < 31; j++) { | 1033 | for (j = 0; j < 31; j++) |
978 | temp_ep = &xhci->devs[i]->eps[j]; | 1034 | xhci_kill_endpoint_urbs(xhci, i, j); |
979 | ring = temp_ep->ring; | ||
980 | if (!ring) | ||
981 | continue; | ||
982 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | ||
983 | "Killing URBs for slot ID %u, " | ||
984 | "ep index %u", i, j); | ||
985 | while (!list_empty(&ring->td_list)) { | ||
986 | cur_td = list_first_entry(&ring->td_list, | ||
987 | struct xhci_td, | ||
988 | td_list); | ||
989 | list_del_init(&cur_td->td_list); | ||
990 | if (!list_empty(&cur_td->cancelled_td_list)) | ||
991 | list_del_init(&cur_td->cancelled_td_list); | ||
992 | xhci_giveback_urb_in_irq(xhci, cur_td, | ||
993 | -ESHUTDOWN); | ||
994 | } | ||
995 | while (!list_empty(&temp_ep->cancelled_td_list)) { | ||
996 | cur_td = list_first_entry( | ||
997 | &temp_ep->cancelled_td_list, | ||
998 | struct xhci_td, | ||
999 | cancelled_td_list); | ||
1000 | list_del_init(&cur_td->cancelled_td_list); | ||
1001 | xhci_giveback_urb_in_irq(xhci, cur_td, | ||
1002 | -ESHUTDOWN); | ||
1003 | } | ||
1004 | } | ||
1005 | } | 1035 | } |
1006 | spin_unlock_irqrestore(&xhci->lock, flags); | 1036 | spin_unlock_irqrestore(&xhci->lock, flags); |
1007 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 1037 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
@@ -1073,17 +1103,18 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, | |||
1073 | unsigned int stream_id; | 1103 | unsigned int stream_id; |
1074 | struct xhci_ring *ep_ring; | 1104 | struct xhci_ring *ep_ring; |
1075 | struct xhci_virt_device *dev; | 1105 | struct xhci_virt_device *dev; |
1106 | struct xhci_virt_ep *ep; | ||
1076 | struct xhci_ep_ctx *ep_ctx; | 1107 | struct xhci_ep_ctx *ep_ctx; |
1077 | struct xhci_slot_ctx *slot_ctx; | 1108 | struct xhci_slot_ctx *slot_ctx; |
1078 | 1109 | ||
1079 | ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3])); | 1110 | ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3])); |
1080 | stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2])); | 1111 | stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2])); |
1081 | dev = xhci->devs[slot_id]; | 1112 | dev = xhci->devs[slot_id]; |
1113 | ep = &dev->eps[ep_index]; | ||
1082 | 1114 | ||
1083 | ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id); | 1115 | ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id); |
1084 | if (!ep_ring) { | 1116 | if (!ep_ring) { |
1085 | xhci_warn(xhci, "WARN Set TR deq ptr command for " | 1117 | xhci_warn(xhci, "WARN Set TR deq ptr command for freed stream ID %u\n", |
1086 | "freed stream ID %u\n", | ||
1087 | stream_id); | 1118 | stream_id); |
1088 | /* XXX: Harmless??? */ | 1119 | /* XXX: Harmless??? */ |
1089 | dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; | 1120 | dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; |
@@ -1099,12 +1130,10 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, | |||
1099 | 1130 | ||
1100 | switch (cmd_comp_code) { | 1131 | switch (cmd_comp_code) { |
1101 | case COMP_TRB_ERR: | 1132 | case COMP_TRB_ERR: |
1102 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because " | 1133 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because of stream ID configuration\n"); |
1103 | "of stream ID configuration\n"); | ||
1104 | break; | 1134 | break; |
1105 | case COMP_CTX_STATE: | 1135 | case COMP_CTX_STATE: |
1106 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due " | 1136 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due to incorrect slot or ep state.\n"); |
1107 | "to incorrect slot or ep state.\n"); | ||
1108 | ep_state = le32_to_cpu(ep_ctx->ep_info); | 1137 | ep_state = le32_to_cpu(ep_ctx->ep_info); |
1109 | ep_state &= EP_STATE_MASK; | 1138 | ep_state &= EP_STATE_MASK; |
1110 | slot_state = le32_to_cpu(slot_ctx->dev_state); | 1139 | slot_state = le32_to_cpu(slot_ctx->dev_state); |
@@ -1114,13 +1143,12 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, | |||
1114 | slot_state, ep_state); | 1143 | slot_state, ep_state); |
1115 | break; | 1144 | break; |
1116 | case COMP_EBADSLT: | 1145 | case COMP_EBADSLT: |
1117 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed because " | 1146 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed because slot %u was not enabled.\n", |
1118 | "slot %u was not enabled.\n", slot_id); | 1147 | slot_id); |
1119 | break; | 1148 | break; |
1120 | default: | 1149 | default: |
1121 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown " | 1150 | xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown completion code of %u.\n", |
1122 | "completion code of %u.\n", | 1151 | cmd_comp_code); |
1123 | cmd_comp_code); | ||
1124 | break; | 1152 | break; |
1125 | } | 1153 | } |
1126 | /* OK what do we do now? The endpoint state is hosed, and we | 1154 | /* OK what do we do now? The endpoint state is hosed, and we |
@@ -1130,23 +1158,28 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, | |||
1130 | * cancelling URBs, which might not be an error... | 1158 | * cancelling URBs, which might not be an error... |
1131 | */ | 1159 | */ |
1132 | } else { | 1160 | } else { |
1161 | u64 deq; | ||
1162 | /* 4.6.10 deq ptr is written to the stream ctx for streams */ | ||
1163 | if (ep->ep_state & EP_HAS_STREAMS) { | ||
1164 | struct xhci_stream_ctx *ctx = | ||
1165 | &ep->stream_info->stream_ctx_array[stream_id]; | ||
1166 | deq = le64_to_cpu(ctx->stream_ring) & SCTX_DEQ_MASK; | ||
1167 | } else { | ||
1168 | deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK; | ||
1169 | } | ||
1133 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 1170 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
1134 | "Successful Set TR Deq Ptr cmd, deq = @%08llx", | 1171 | "Successful Set TR Deq Ptr cmd, deq = @%08llx", deq); |
1135 | le64_to_cpu(ep_ctx->deq)); | 1172 | if (xhci_trb_virt_to_dma(ep->queued_deq_seg, |
1136 | if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, | 1173 | ep->queued_deq_ptr) == deq) { |
1137 | dev->eps[ep_index].queued_deq_ptr) == | ||
1138 | (le64_to_cpu(ep_ctx->deq) & ~(EP_CTX_CYCLE_MASK))) { | ||
1139 | /* Update the ring's dequeue segment and dequeue pointer | 1174 | /* Update the ring's dequeue segment and dequeue pointer |
1140 | * to reflect the new position. | 1175 | * to reflect the new position. |
1141 | */ | 1176 | */ |
1142 | update_ring_for_set_deq_completion(xhci, dev, | 1177 | update_ring_for_set_deq_completion(xhci, dev, |
1143 | ep_ring, ep_index); | 1178 | ep_ring, ep_index); |
1144 | } else { | 1179 | } else { |
1145 | xhci_warn(xhci, "Mismatch between completed Set TR Deq " | 1180 | xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n"); |
1146 | "Ptr command & xHCI internal state.\n"); | ||
1147 | xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", | 1181 | xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", |
1148 | dev->eps[ep_index].queued_deq_seg, | 1182 | ep->queued_deq_seg, ep->queued_deq_ptr); |
1149 | dev->eps[ep_index].queued_deq_ptr); | ||
1150 | } | 1183 | } |
1151 | } | 1184 | } |
1152 | 1185 | ||
@@ -4070,6 +4103,7 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, | |||
4070 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); | 4103 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); |
4071 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); | 4104 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); |
4072 | u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); | 4105 | u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); |
4106 | u32 trb_sct = 0; | ||
4073 | u32 type = TRB_TYPE(TRB_SET_DEQ); | 4107 | u32 type = TRB_TYPE(TRB_SET_DEQ); |
4074 | struct xhci_virt_ep *ep; | 4108 | struct xhci_virt_ep *ep; |
4075 | 4109 | ||
@@ -4088,7 +4122,9 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, | |||
4088 | } | 4122 | } |
4089 | ep->queued_deq_seg = deq_seg; | 4123 | ep->queued_deq_seg = deq_seg; |
4090 | ep->queued_deq_ptr = deq_ptr; | 4124 | ep->queued_deq_ptr = deq_ptr; |
4091 | return queue_command(xhci, lower_32_bits(addr) | cycle_state, | 4125 | if (stream_id) |
4126 | trb_sct = SCT_FOR_TRB(SCT_PRI_TR); | ||
4127 | return queue_command(xhci, lower_32_bits(addr) | trb_sct | cycle_state, | ||
4092 | upper_32_bits(addr), trb_stream_id, | 4128 | upper_32_bits(addr), trb_stream_id, |
4093 | trb_slot_id | trb_ep_index | type, false); | 4129 | trb_slot_id | trb_ep_index | type, false); |
4094 | } | 4130 | } |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 924a6ccdb622..8fe4e124ddd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -390,6 +390,10 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) | |||
390 | } | 390 | } |
391 | 391 | ||
392 | legacy_irq: | 392 | legacy_irq: |
393 | if (!strlen(hcd->irq_descr)) | ||
394 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | ||
395 | hcd->driver->description, hcd->self.busnum); | ||
396 | |||
393 | /* fall back to legacy interrupt*/ | 397 | /* fall back to legacy interrupt*/ |
394 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, | 398 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, |
395 | hcd->irq_descr, hcd); | 399 | hcd->irq_descr, hcd); |
@@ -2678,6 +2682,20 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2678 | return ret; | 2682 | return ret; |
2679 | } | 2683 | } |
2680 | 2684 | ||
2685 | static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, | ||
2686 | struct xhci_virt_device *vdev, int i) | ||
2687 | { | ||
2688 | struct xhci_virt_ep *ep = &vdev->eps[i]; | ||
2689 | |||
2690 | if (ep->ep_state & EP_HAS_STREAMS) { | ||
2691 | xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on set_interface, freeing streams.\n", | ||
2692 | xhci_get_endpoint_address(i)); | ||
2693 | xhci_free_stream_info(xhci, ep->stream_info); | ||
2694 | ep->stream_info = NULL; | ||
2695 | ep->ep_state &= ~EP_HAS_STREAMS; | ||
2696 | } | ||
2697 | } | ||
2698 | |||
2681 | /* Called after one or more calls to xhci_add_endpoint() or | 2699 | /* Called after one or more calls to xhci_add_endpoint() or |
2682 | * xhci_drop_endpoint(). If this call fails, the USB core is expected | 2700 | * xhci_drop_endpoint(). If this call fails, the USB core is expected |
2683 | * to call xhci_reset_bandwidth(). | 2701 | * to call xhci_reset_bandwidth(). |
@@ -2742,8 +2760,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
2742 | /* Free any rings that were dropped, but not changed. */ | 2760 | /* Free any rings that were dropped, but not changed. */ |
2743 | for (i = 1; i < 31; ++i) { | 2761 | for (i = 1; i < 31; ++i) { |
2744 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && | 2762 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && |
2745 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) | 2763 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) { |
2746 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2764 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
2765 | xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); | ||
2766 | } | ||
2747 | } | 2767 | } |
2748 | xhci_zero_in_ctx(xhci, virt_dev); | 2768 | xhci_zero_in_ctx(xhci, virt_dev); |
2749 | /* | 2769 | /* |
@@ -2759,6 +2779,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
2759 | if (virt_dev->eps[i].ring) { | 2779 | if (virt_dev->eps[i].ring) { |
2760 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2780 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
2761 | } | 2781 | } |
2782 | xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); | ||
2762 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; | 2783 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; |
2763 | virt_dev->eps[i].new_ring = NULL; | 2784 | virt_dev->eps[i].new_ring = NULL; |
2764 | } | 2785 | } |
@@ -2954,7 +2975,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, | |||
2954 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); | 2975 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); |
2955 | if (ret <= 0) | 2976 | if (ret <= 0) |
2956 | return -EINVAL; | 2977 | return -EINVAL; |
2957 | if (ep->ss_ep_comp.bmAttributes == 0) { | 2978 | if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) { |
2958 | xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" | 2979 | xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" |
2959 | " descriptor for ep 0x%x does not support streams\n", | 2980 | " descriptor for ep 0x%x does not support streams\n", |
2960 | ep->desc.bEndpointAddress); | 2981 | ep->desc.bEndpointAddress); |
@@ -3121,6 +3142,12 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
3121 | xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n", | 3142 | xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n", |
3122 | num_streams); | 3143 | num_streams); |
3123 | 3144 | ||
3145 | /* MaxPSASize value 0 (2 streams) means streams are not supported */ | ||
3146 | if (HCC_MAX_PSA(xhci->hcc_params) < 4) { | ||
3147 | xhci_dbg(xhci, "xHCI controller does not support streams.\n"); | ||
3148 | return -ENOSYS; | ||
3149 | } | ||
3150 | |||
3124 | config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); | 3151 | config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); |
3125 | if (!config_cmd) { | 3152 | if (!config_cmd) { |
3126 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); | 3153 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); |
@@ -3519,6 +3546,8 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3519 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; | 3546 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; |
3520 | 3547 | ||
3521 | if (ep->ep_state & EP_HAS_STREAMS) { | 3548 | if (ep->ep_state & EP_HAS_STREAMS) { |
3549 | xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on device reset, freeing streams.\n", | ||
3550 | xhci_get_endpoint_address(i)); | ||
3522 | xhci_free_stream_info(xhci, ep->stream_info); | 3551 | xhci_free_stream_info(xhci, ep->stream_info); |
3523 | ep->stream_info = NULL; | 3552 | ep->stream_info = NULL; |
3524 | ep->ep_state &= ~EP_HAS_STREAMS; | 3553 | ep->ep_state &= ~EP_HAS_STREAMS; |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 58ed9d088e63..d280e9213d08 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -703,6 +703,7 @@ struct xhci_ep_ctx { | |||
703 | 703 | ||
704 | /* deq bitmasks */ | 704 | /* deq bitmasks */ |
705 | #define EP_CTX_CYCLE_MASK (1 << 0) | 705 | #define EP_CTX_CYCLE_MASK (1 << 0) |
706 | #define SCTX_DEQ_MASK (~0xfL) | ||
706 | 707 | ||
707 | 708 | ||
708 | /** | 709 | /** |
@@ -1118,9 +1119,10 @@ enum xhci_setup_dev { | |||
1118 | #define TRB_TO_SUSPEND_PORT(p) (((p) & (1 << 23)) >> 23) | 1119 | #define TRB_TO_SUSPEND_PORT(p) (((p) & (1 << 23)) >> 23) |
1119 | #define LAST_EP_INDEX 30 | 1120 | #define LAST_EP_INDEX 30 |
1120 | 1121 | ||
1121 | /* Set TR Dequeue Pointer command TRB fields */ | 1122 | /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */ |
1122 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) | 1123 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) |
1123 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) | 1124 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) |
1125 | #define SCT_FOR_TRB(p) (((p) << 1) & 0x7) | ||
1124 | 1126 | ||
1125 | 1127 | ||
1126 | /* Port Status Change Event TRB fields */ | 1128 | /* Port Status Change Event TRB fields */ |
@@ -1341,6 +1343,7 @@ struct xhci_ring { | |||
1341 | unsigned int num_trbs_free_temp; | 1343 | unsigned int num_trbs_free_temp; |
1342 | enum xhci_ring_type type; | 1344 | enum xhci_ring_type type; |
1343 | bool last_td_was_short; | 1345 | bool last_td_was_short; |
1346 | struct radix_tree_root *trb_address_map; | ||
1344 | }; | 1347 | }; |
1345 | 1348 | ||
1346 | struct xhci_erst_entry { | 1349 | struct xhci_erst_entry { |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index ba5f70f92888..1bca274dc3b5 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -128,7 +128,6 @@ config USB_IDMOUSE | |||
128 | 128 | ||
129 | config USB_FTDI_ELAN | 129 | config USB_FTDI_ELAN |
130 | tristate "Elan PCMCIA CardBus Adapter USB Client" | 130 | tristate "Elan PCMCIA CardBus Adapter USB Client" |
131 | default M | ||
132 | help | 131 | help |
133 | ELAN's Uxxx series of adapters are USB to PCMCIA CardBus adapters. | 132 | ELAN's Uxxx series of adapters are USB to PCMCIA CardBus adapters. |
134 | Currently only the U132 adapter is available. | 133 | Currently only the U132 adapter is available. |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index de98906f786d..06b5d77cd9ad 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -2123,8 +2123,8 @@ sisusb_get_ramconfig(struct sisusb_usb_data *sisusb) | |||
2123 | u8 tmp8, tmp82, ramtype; | 2123 | u8 tmp8, tmp82, ramtype; |
2124 | int bw = 0; | 2124 | int bw = 0; |
2125 | char *ramtypetext1 = NULL; | 2125 | char *ramtypetext1 = NULL; |
2126 | const char *ramtypetext2[] = { "SDR SDRAM", "SDR SGRAM", | 2126 | static const char ram_datarate[4] = {'S', 'S', 'D', 'D'}; |
2127 | "DDR SDRAM", "DDR SGRAM" }; | 2127 | static const char ram_dynamictype[4] = {'D', 'G', 'D', 'G'}; |
2128 | static const int busSDR[4] = {64, 64, 128, 128}; | 2128 | static const int busSDR[4] = {64, 64, 128, 128}; |
2129 | static const int busDDR[4] = {32, 32, 64, 64}; | 2129 | static const int busDDR[4] = {32, 32, 64, 64}; |
2130 | static const int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2}; | 2130 | static const int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2}; |
@@ -2156,8 +2156,10 @@ sisusb_get_ramconfig(struct sisusb_usb_data *sisusb) | |||
2156 | break; | 2156 | break; |
2157 | } | 2157 | } |
2158 | 2158 | ||
2159 | dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %s, bus width %d\n", (sisusb->vramsize >> 20), ramtypetext1, | 2159 | |
2160 | ramtypetext2[ramtype], bw); | 2160 | dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %cDR S%cRAM, bus width %d\n", |
2161 | sisusb->vramsize >> 20, ramtypetext1, | ||
2162 | ram_datarate[ramtype], ram_dynamictype[ramtype], bw); | ||
2161 | } | 2163 | } |
2162 | 2164 | ||
2163 | static int | 2165 | static int |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 78eb4ff33269..bdef0d6eb91d 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -22,8 +22,27 @@ | |||
22 | enum led_type { | 22 | enum led_type { |
23 | DELCOM_VISUAL_SIGNAL_INDICATOR, | 23 | DELCOM_VISUAL_SIGNAL_INDICATOR, |
24 | DREAM_CHEEKY_WEBMAIL_NOTIFIER, | 24 | DREAM_CHEEKY_WEBMAIL_NOTIFIER, |
25 | RISO_KAGAKU_LED | ||
25 | }; | 26 | }; |
26 | 27 | ||
28 | /* the Webmail LED made by RISO KAGAKU CORP. decodes a color index | ||
29 | internally, we want to keep the red+green+blue sysfs api, so we decode | ||
30 | from 1-bit RGB to the riso kagaku color index according to this table... */ | ||
31 | |||
32 | static unsigned const char riso_kagaku_tbl[] = { | ||
33 | /* R+2G+4B -> riso kagaku color index */ | ||
34 | [0] = 0, /* black */ | ||
35 | [1] = 2, /* red */ | ||
36 | [2] = 1, /* green */ | ||
37 | [3] = 5, /* yellow */ | ||
38 | [4] = 3, /* blue */ | ||
39 | [5] = 6, /* magenta */ | ||
40 | [6] = 4, /* cyan */ | ||
41 | [7] = 7 /* white */ | ||
42 | }; | ||
43 | |||
44 | #define RISO_KAGAKU_IX(r,g,b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] | ||
45 | |||
27 | /* table of devices that work with this driver */ | 46 | /* table of devices that work with this driver */ |
28 | static const struct usb_device_id id_table[] = { | 47 | static const struct usb_device_id id_table[] = { |
29 | { USB_DEVICE(0x0fc5, 0x1223), | 48 | { USB_DEVICE(0x0fc5, 0x1223), |
@@ -32,6 +51,8 @@ static const struct usb_device_id id_table[] = { | |||
32 | .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, | 51 | .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, |
33 | { USB_DEVICE(0x1d34, 0x000a), | 52 | { USB_DEVICE(0x1d34, 0x000a), |
34 | .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, | 53 | .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, |
54 | { USB_DEVICE(0x1294, 0x1320), | ||
55 | .driver_info = RISO_KAGAKU_LED }, | ||
35 | { }, | 56 | { }, |
36 | }; | 57 | }; |
37 | MODULE_DEVICE_TABLE(usb, id_table); | 58 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -48,6 +69,7 @@ static void change_color(struct usb_led *led) | |||
48 | { | 69 | { |
49 | int retval = 0; | 70 | int retval = 0; |
50 | unsigned char *buffer; | 71 | unsigned char *buffer; |
72 | int actlength; | ||
51 | 73 | ||
52 | buffer = kmalloc(8, GFP_KERNEL); | 74 | buffer = kmalloc(8, GFP_KERNEL); |
53 | if (!buffer) { | 75 | if (!buffer) { |
@@ -104,6 +126,18 @@ static void change_color(struct usb_led *led) | |||
104 | 2000); | 126 | 2000); |
105 | break; | 127 | break; |
106 | 128 | ||
129 | case RISO_KAGAKU_LED: | ||
130 | buffer[0] = RISO_KAGAKU_IX(led->red, led->green, led->blue); | ||
131 | buffer[1] = 0; | ||
132 | buffer[2] = 0; | ||
133 | buffer[3] = 0; | ||
134 | buffer[4] = 0; | ||
135 | |||
136 | retval = usb_interrupt_msg(led->udev, | ||
137 | usb_sndctrlpipe(led->udev, 2), | ||
138 | buffer, 5, &actlength, 1000 /*ms timeout*/); | ||
139 | break; | ||
140 | |||
107 | default: | 141 | default: |
108 | dev_err(&led->udev->dev, "unknown device type %d\n", led->type); | 142 | dev_err(&led->udev->dev, "unknown device type %d\n", led->type); |
109 | } | 143 | } |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 688dc8bb192d..8b789792f6fa 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -43,6 +43,7 @@ config USB_MUSB_HOST | |||
43 | config USB_MUSB_GADGET | 43 | config USB_MUSB_GADGET |
44 | bool "Gadget only mode" | 44 | bool "Gadget only mode" |
45 | depends on USB_GADGET=y || USB_GADGET=USB_MUSB_HDRC | 45 | depends on USB_GADGET=y || USB_GADGET=USB_MUSB_HDRC |
46 | depends on HAS_DMA | ||
46 | help | 47 | help |
47 | Select this when you want to use MUSB in gadget mode only, | 48 | Select this when you want to use MUSB in gadget mode only, |
48 | thereby the host feature will be regressed. | 49 | thereby the host feature will be regressed. |
@@ -50,6 +51,7 @@ config USB_MUSB_GADGET | |||
50 | config USB_MUSB_DUAL_ROLE | 51 | config USB_MUSB_DUAL_ROLE |
51 | bool "Dual Role mode" | 52 | bool "Dual Role mode" |
52 | depends on ((USB=y || USB=USB_MUSB_HDRC) && (USB_GADGET=y || USB_GADGET=USB_MUSB_HDRC)) | 53 | depends on ((USB=y || USB=USB_MUSB_HDRC) && (USB_GADGET=y || USB_GADGET=USB_MUSB_HDRC)) |
54 | depends on HAS_DMA | ||
53 | help | 55 | help |
54 | This is the default mode of working of MUSB controller where | 56 | This is the default mode of working of MUSB controller where |
55 | both host and gadget features are enabled. | 57 | both host and gadget features are enabled. |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 239ad0b1ceb6..07576907e2c6 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -438,7 +438,6 @@ void musb_hnp_stop(struct musb *musb) | |||
438 | static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | 438 | static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, |
439 | u8 devctl) | 439 | u8 devctl) |
440 | { | 440 | { |
441 | struct usb_otg *otg = musb->xceiv->otg; | ||
442 | irqreturn_t handled = IRQ_NONE; | 441 | irqreturn_t handled = IRQ_NONE; |
443 | 442 | ||
444 | dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, | 443 | dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, |
@@ -656,7 +655,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
656 | break; | 655 | break; |
657 | case OTG_STATE_B_PERIPHERAL: | 656 | case OTG_STATE_B_PERIPHERAL: |
658 | musb_g_suspend(musb); | 657 | musb_g_suspend(musb); |
659 | musb->is_active = otg->gadget->b_hnp_enable; | 658 | musb->is_active = musb->g.b_hnp_enable; |
660 | if (musb->is_active) { | 659 | if (musb->is_active) { |
661 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | 660 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; |
662 | dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); | 661 | dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); |
@@ -672,7 +671,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
672 | break; | 671 | break; |
673 | case OTG_STATE_A_HOST: | 672 | case OTG_STATE_A_HOST: |
674 | musb->xceiv->state = OTG_STATE_A_SUSPEND; | 673 | musb->xceiv->state = OTG_STATE_A_SUSPEND; |
675 | musb->is_active = otg->host->b_hnp_enable; | 674 | musb->is_active = musb->hcd->self.b_hnp_enable; |
676 | break; | 675 | break; |
677 | case OTG_STATE_B_HOST: | 676 | case OTG_STATE_B_HOST: |
678 | /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ | 677 | /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index f88929609bac..7b8bbf53127e 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -39,6 +39,7 @@ struct cppi41_dma_channel { | |||
39 | u32 transferred; | 39 | u32 transferred; |
40 | u32 packet_sz; | 40 | u32 packet_sz; |
41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
42 | struct work_struct dma_completion; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | #define MUSB_DMA_NUM_CHANNELS 15 | 45 | #define MUSB_DMA_NUM_CHANNELS 15 |
@@ -112,6 +113,18 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) | |||
112 | return true; | 113 | return true; |
113 | } | 114 | } |
114 | 115 | ||
116 | static bool is_isoc(struct musb_hw_ep *hw_ep, bool in) | ||
117 | { | ||
118 | if (in && hw_ep->in_qh) { | ||
119 | if (hw_ep->in_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
120 | return true; | ||
121 | } else if (hw_ep->out_qh) { | ||
122 | if (hw_ep->out_qh->type == USB_ENDPOINT_XFER_ISOC) | ||
123 | return true; | ||
124 | } | ||
125 | return false; | ||
126 | } | ||
127 | |||
115 | static void cppi41_dma_callback(void *private_data); | 128 | static void cppi41_dma_callback(void *private_data); |
116 | 129 | ||
117 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | 130 | static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) |
@@ -119,7 +132,8 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
119 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 132 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
120 | struct musb *musb = hw_ep->musb; | 133 | struct musb *musb = hw_ep->musb; |
121 | 134 | ||
122 | if (!cppi41_channel->prog_len) { | 135 | if (!cppi41_channel->prog_len || |
136 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { | ||
123 | 137 | ||
124 | /* done, complete */ | 138 | /* done, complete */ |
125 | cppi41_channel->channel.actual_len = | 139 | cppi41_channel->channel.actual_len = |
@@ -165,6 +179,32 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
165 | } | 179 | } |
166 | } | 180 | } |
167 | 181 | ||
182 | static void cppi_trans_done_work(struct work_struct *work) | ||
183 | { | ||
184 | unsigned long flags; | ||
185 | struct cppi41_dma_channel *cppi41_channel = | ||
186 | container_of(work, struct cppi41_dma_channel, dma_completion); | ||
187 | struct cppi41_dma_controller *controller = cppi41_channel->controller; | ||
188 | struct musb *musb = controller->musb; | ||
189 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
190 | bool empty; | ||
191 | |||
192 | if (!cppi41_channel->is_tx && is_isoc(hw_ep, 1)) { | ||
193 | spin_lock_irqsave(&musb->lock, flags); | ||
194 | cppi41_trans_done(cppi41_channel); | ||
195 | spin_unlock_irqrestore(&musb->lock, flags); | ||
196 | } else { | ||
197 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
198 | if (empty) { | ||
199 | spin_lock_irqsave(&musb->lock, flags); | ||
200 | cppi41_trans_done(cppi41_channel); | ||
201 | spin_unlock_irqrestore(&musb->lock, flags); | ||
202 | } else { | ||
203 | schedule_work(&cppi41_channel->dma_completion); | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
168 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) | 208 | static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) |
169 | { | 209 | { |
170 | struct cppi41_dma_controller *controller; | 210 | struct cppi41_dma_controller *controller; |
@@ -228,6 +268,14 @@ static void cppi41_dma_callback(void *private_data) | |||
228 | transferred < cppi41_channel->packet_sz) | 268 | transferred < cppi41_channel->packet_sz) |
229 | cppi41_channel->prog_len = 0; | 269 | cppi41_channel->prog_len = 0; |
230 | 270 | ||
271 | if (!cppi41_channel->is_tx) { | ||
272 | if (is_isoc(hw_ep, 1)) | ||
273 | schedule_work(&cppi41_channel->dma_completion); | ||
274 | else | ||
275 | cppi41_trans_done(cppi41_channel); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
231 | empty = musb_is_tx_fifo_empty(hw_ep); | 279 | empty = musb_is_tx_fifo_empty(hw_ep); |
232 | if (empty) { | 280 | if (empty) { |
233 | cppi41_trans_done(cppi41_channel); | 281 | cppi41_trans_done(cppi41_channel); |
@@ -264,6 +312,10 @@ static void cppi41_dma_callback(void *private_data) | |||
264 | goto out; | 312 | goto out; |
265 | } | 313 | } |
266 | } | 314 | } |
315 | if (is_isoc(hw_ep, 0)) { | ||
316 | schedule_work(&cppi41_channel->dma_completion); | ||
317 | goto out; | ||
318 | } | ||
267 | list_add_tail(&cppi41_channel->tx_check, | 319 | list_add_tail(&cppi41_channel->tx_check, |
268 | &controller->early_tx_list); | 320 | &controller->early_tx_list); |
269 | if (!hrtimer_active(&controller->early_tx)) { | 321 | if (!hrtimer_active(&controller->early_tx)) { |
@@ -448,12 +500,25 @@ static int cppi41_dma_channel_program(struct dma_channel *channel, | |||
448 | dma_addr_t dma_addr, u32 len) | 500 | dma_addr_t dma_addr, u32 len) |
449 | { | 501 | { |
450 | int ret; | 502 | int ret; |
503 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; | ||
504 | int hb_mult = 0; | ||
451 | 505 | ||
452 | BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || | 506 | BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || |
453 | channel->status == MUSB_DMA_STATUS_BUSY); | 507 | channel->status == MUSB_DMA_STATUS_BUSY); |
454 | 508 | ||
509 | if (is_host_active(cppi41_channel->controller->musb)) { | ||
510 | if (cppi41_channel->is_tx) | ||
511 | hb_mult = cppi41_channel->hw_ep->out_qh->hb_mult; | ||
512 | else | ||
513 | hb_mult = cppi41_channel->hw_ep->in_qh->hb_mult; | ||
514 | } | ||
515 | |||
455 | channel->status = MUSB_DMA_STATUS_BUSY; | 516 | channel->status = MUSB_DMA_STATUS_BUSY; |
456 | channel->actual_len = 0; | 517 | channel->actual_len = 0; |
518 | |||
519 | if (hb_mult) | ||
520 | packet_sz = hb_mult * (packet_sz & 0x7FF); | ||
521 | |||
457 | ret = cppi41_configure_channel(channel, packet_sz, mode, dma_addr, len); | 522 | ret = cppi41_configure_channel(channel, packet_sz, mode, dma_addr, len); |
458 | if (!ret) | 523 | if (!ret) |
459 | channel->status = MUSB_DMA_STATUS_FREE; | 524 | channel->status = MUSB_DMA_STATUS_FREE; |
@@ -607,6 +672,8 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) | |||
607 | cppi41_channel->port_num = port; | 672 | cppi41_channel->port_num = port; |
608 | cppi41_channel->is_tx = is_tx; | 673 | cppi41_channel->is_tx = is_tx; |
609 | INIT_LIST_HEAD(&cppi41_channel->tx_check); | 674 | INIT_LIST_HEAD(&cppi41_channel->tx_check); |
675 | INIT_WORK(&cppi41_channel->dma_completion, | ||
676 | cppi_trans_done_work); | ||
610 | 677 | ||
611 | musb_dma = &cppi41_channel->channel; | 678 | musb_dma = &cppi41_channel->channel; |
612 | musb_dma->private_data = cppi41_channel; | 679 | musb_dma->private_data = cppi41_channel; |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 7a109eae9b9a..3372ded5def7 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/of_irq.h> | 45 | #include <linux/of_irq.h> |
46 | #include <linux/usb/of.h> | 46 | #include <linux/usb/of.h> |
47 | 47 | ||
48 | #include <linux/debugfs.h> | ||
49 | |||
48 | #include "musb_core.h" | 50 | #include "musb_core.h" |
49 | 51 | ||
50 | static const struct of_device_id musb_dsps_of_match[]; | 52 | static const struct of_device_id musb_dsps_of_match[]; |
@@ -136,6 +138,26 @@ struct dsps_glue { | |||
136 | unsigned long last_timer; /* last timer data for each instance */ | 138 | unsigned long last_timer; /* last timer data for each instance */ |
137 | 139 | ||
138 | struct dsps_context context; | 140 | struct dsps_context context; |
141 | struct debugfs_regset32 regset; | ||
142 | struct dentry *dbgfs_root; | ||
143 | }; | ||
144 | |||
145 | static const struct debugfs_reg32 dsps_musb_regs[] = { | ||
146 | { "revision", 0x00 }, | ||
147 | { "control", 0x14 }, | ||
148 | { "status", 0x18 }, | ||
149 | { "eoi", 0x24 }, | ||
150 | { "intr0_stat", 0x30 }, | ||
151 | { "intr1_stat", 0x34 }, | ||
152 | { "intr0_set", 0x38 }, | ||
153 | { "intr1_set", 0x3c }, | ||
154 | { "txmode", 0x70 }, | ||
155 | { "rxmode", 0x74 }, | ||
156 | { "autoreq", 0xd0 }, | ||
157 | { "srpfixtime", 0xd4 }, | ||
158 | { "tdown", 0xd8 }, | ||
159 | { "phy_utmi", 0xe0 }, | ||
160 | { "mode", 0xe8 }, | ||
139 | }; | 161 | }; |
140 | 162 | ||
141 | static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) | 163 | static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) |
@@ -368,6 +390,30 @@ out: | |||
368 | return ret; | 390 | return ret; |
369 | } | 391 | } |
370 | 392 | ||
393 | static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue) | ||
394 | { | ||
395 | struct dentry *root; | ||
396 | struct dentry *file; | ||
397 | char buf[128]; | ||
398 | |||
399 | sprintf(buf, "%s.dsps", dev_name(musb->controller)); | ||
400 | root = debugfs_create_dir(buf, NULL); | ||
401 | if (!root) | ||
402 | return -ENOMEM; | ||
403 | glue->dbgfs_root = root; | ||
404 | |||
405 | glue->regset.regs = dsps_musb_regs; | ||
406 | glue->regset.nregs = ARRAY_SIZE(dsps_musb_regs); | ||
407 | glue->regset.base = musb->ctrl_base; | ||
408 | |||
409 | file = debugfs_create_regset32("regdump", S_IRUGO, root, &glue->regset); | ||
410 | if (!file) { | ||
411 | debugfs_remove_recursive(root); | ||
412 | return -ENOMEM; | ||
413 | } | ||
414 | return 0; | ||
415 | } | ||
416 | |||
371 | static int dsps_musb_init(struct musb *musb) | 417 | static int dsps_musb_init(struct musb *musb) |
372 | { | 418 | { |
373 | struct device *dev = musb->controller; | 419 | struct device *dev = musb->controller; |
@@ -377,6 +423,7 @@ static int dsps_musb_init(struct musb *musb) | |||
377 | void __iomem *reg_base; | 423 | void __iomem *reg_base; |
378 | struct resource *r; | 424 | struct resource *r; |
379 | u32 rev, val; | 425 | u32 rev, val; |
426 | int ret; | ||
380 | 427 | ||
381 | r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); | 428 | r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); |
382 | if (!r) | 429 | if (!r) |
@@ -410,6 +457,10 @@ static int dsps_musb_init(struct musb *musb) | |||
410 | val &= ~(1 << wrp->otg_disable); | 457 | val &= ~(1 << wrp->otg_disable); |
411 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); | 458 | dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); |
412 | 459 | ||
460 | ret = dsps_musb_dbg_init(musb, glue); | ||
461 | if (ret) | ||
462 | return ret; | ||
463 | |||
413 | return 0; | 464 | return 0; |
414 | } | 465 | } |
415 | 466 | ||
@@ -616,7 +667,7 @@ static int dsps_probe(struct platform_device *pdev) | |||
616 | wrp = match->data; | 667 | wrp = match->data; |
617 | 668 | ||
618 | /* allocate glue */ | 669 | /* allocate glue */ |
619 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 670 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
620 | if (!glue) { | 671 | if (!glue) { |
621 | dev_err(&pdev->dev, "unable to allocate glue memory\n"); | 672 | dev_err(&pdev->dev, "unable to allocate glue memory\n"); |
622 | return -ENOMEM; | 673 | return -ENOMEM; |
@@ -644,7 +695,6 @@ err3: | |||
644 | pm_runtime_put(&pdev->dev); | 695 | pm_runtime_put(&pdev->dev); |
645 | err2: | 696 | err2: |
646 | pm_runtime_disable(&pdev->dev); | 697 | pm_runtime_disable(&pdev->dev); |
647 | kfree(glue); | ||
648 | return ret; | 698 | return ret; |
649 | } | 699 | } |
650 | 700 | ||
@@ -657,7 +707,9 @@ static int dsps_remove(struct platform_device *pdev) | |||
657 | /* disable usbss clocks */ | 707 | /* disable usbss clocks */ |
658 | pm_runtime_put(&pdev->dev); | 708 | pm_runtime_put(&pdev->dev); |
659 | pm_runtime_disable(&pdev->dev); | 709 | pm_runtime_disable(&pdev->dev); |
660 | kfree(glue); | 710 | |
711 | debugfs_remove_recursive(glue->dbgfs_root); | ||
712 | |||
661 | return 0; | 713 | return 0; |
662 | } | 714 | } |
663 | 715 | ||
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index abb38c3833ef..eb06291a40c8 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -1694,7 +1694,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1694 | | MUSB_RXCSR_RXPKTRDY); | 1694 | | MUSB_RXCSR_RXPKTRDY); |
1695 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | 1695 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); |
1696 | 1696 | ||
1697 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) | 1697 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) || \ |
1698 | defined(CONFIG_USB_TI_CPPI41_DMA) | ||
1698 | if (usb_pipeisoc(pipe)) { | 1699 | if (usb_pipeisoc(pipe)) { |
1699 | struct usb_iso_packet_descriptor *d; | 1700 | struct usb_iso_packet_descriptor *d; |
1700 | 1701 | ||
@@ -1707,10 +1708,30 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1707 | if (d->status != -EILSEQ && d->status != -EOVERFLOW) | 1708 | if (d->status != -EILSEQ && d->status != -EOVERFLOW) |
1708 | d->status = 0; | 1709 | d->status = 0; |
1709 | 1710 | ||
1710 | if (++qh->iso_idx >= urb->number_of_packets) | 1711 | if (++qh->iso_idx >= urb->number_of_packets) { |
1711 | done = true; | 1712 | done = true; |
1712 | else | 1713 | } else { |
1714 | #if defined(CONFIG_USB_TI_CPPI41_DMA) | ||
1715 | struct dma_controller *c; | ||
1716 | dma_addr_t *buf; | ||
1717 | u32 length, ret; | ||
1718 | |||
1719 | c = musb->dma_controller; | ||
1720 | buf = (void *) | ||
1721 | urb->iso_frame_desc[qh->iso_idx].offset | ||
1722 | + (u32)urb->transfer_dma; | ||
1723 | |||
1724 | length = | ||
1725 | urb->iso_frame_desc[qh->iso_idx].length; | ||
1726 | |||
1727 | val |= MUSB_RXCSR_DMAENAB; | ||
1728 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | ||
1729 | |||
1730 | ret = c->channel_program(dma, qh->maxpacket, | ||
1731 | 0, (u32) buf, length); | ||
1732 | #endif | ||
1713 | done = false; | 1733 | done = false; |
1734 | } | ||
1714 | 1735 | ||
1715 | } else { | 1736 | } else { |
1716 | /* done if urb buffer is full or short packet is recd */ | 1737 | /* done if urb buffer is full or short packet is recd */ |
@@ -1750,7 +1771,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1750 | } | 1771 | } |
1751 | 1772 | ||
1752 | /* we are expecting IN packets */ | 1773 | /* we are expecting IN packets */ |
1753 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) | 1774 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) || \ |
1775 | defined(CONFIG_USB_TI_CPPI41_DMA) | ||
1754 | if (dma) { | 1776 | if (dma) { |
1755 | struct dma_controller *c; | 1777 | struct dma_controller *c; |
1756 | u16 rx_count; | 1778 | u16 rx_count; |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 8aa59a2c5eb2..d341c149a2f9 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/err.h> | 37 | #include <linux/err.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/usb/musb-omap.h> | 39 | #include <linux/usb/musb-omap.h> |
40 | #include <linux/usb/omap_control_usb.h> | 40 | #include <linux/phy/omap_control_phy.h> |
41 | #include <linux/of_platform.h> | 41 | #include <linux/of_platform.h> |
42 | 42 | ||
43 | #include "musb_core.h" | 43 | #include "musb_core.h" |
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7d1451d5bbea..416e0c8cf6ff 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
@@ -75,27 +75,6 @@ config NOP_USB_XCEIV | |||
75 | built-in with usb ip or which are autonomous and doesn't require any | 75 | built-in with usb ip or which are autonomous and doesn't require any |
76 | phy programming such as ISP1x04 etc. | 76 | phy programming such as ISP1x04 etc. |
77 | 77 | ||
78 | config OMAP_CONTROL_USB | ||
79 | tristate "OMAP CONTROL USB Driver" | ||
80 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
81 | help | ||
82 | Enable this to add support for the USB part present in the control | ||
83 | module. This driver has API to power on the USB2 PHY and to write to | ||
84 | the mailbox. The mailbox is present only in omap4 and the register to | ||
85 | power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an | ||
86 | additional register to power on USB3 PHY. | ||
87 | |||
88 | config OMAP_USB3 | ||
89 | tristate "OMAP USB3 PHY Driver" | ||
90 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
91 | select OMAP_CONTROL_USB | ||
92 | select USB_PHY | ||
93 | help | ||
94 | Enable this to support the USB3 PHY that is part of SOC. This | ||
95 | driver takes care of all the PHY functionality apart from comparator. | ||
96 | This driver interacts with the "OMAP Control USB Driver" to power | ||
97 | on/off the PHY. | ||
98 | |||
99 | config AM335X_CONTROL_USB | 78 | config AM335X_CONTROL_USB |
100 | tristate | 79 | tristate |
101 | 80 | ||
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index be58adae3496..f8fa719a31b9 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile | |||
@@ -13,11 +13,9 @@ obj-$(CONFIG_ISP1301_OMAP) += phy-isp1301-omap.o | |||
13 | obj-$(CONFIG_MV_U3D_PHY) += phy-mv-u3d-usb.o | 13 | obj-$(CONFIG_MV_U3D_PHY) += phy-mv-u3d-usb.o |
14 | obj-$(CONFIG_NOP_USB_XCEIV) += phy-generic.o | 14 | obj-$(CONFIG_NOP_USB_XCEIV) += phy-generic.o |
15 | obj-$(CONFIG_TAHVO_USB) += phy-tahvo.o | 15 | obj-$(CONFIG_TAHVO_USB) += phy-tahvo.o |
16 | obj-$(CONFIG_OMAP_CONTROL_USB) += phy-omap-control.o | ||
17 | obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o | 16 | obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o |
18 | obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o | 17 | obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o |
19 | obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o | 18 | obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o |
20 | obj-$(CONFIG_OMAP_USB3) += phy-omap-usb3.o | ||
21 | obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o | 19 | obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o |
22 | obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o | 20 | obj-$(CONFIG_SAMSUNG_USB2PHY) += phy-samsung-usb2.o |
23 | obj-$(CONFIG_SAMSUNG_USB3PHY) += phy-samsung-usb3.o | 21 | obj-$(CONFIG_SAMSUNG_USB3PHY) += phy-samsung-usb3.o |
diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c index 7aa314ef4a8a..c47e5a6edde2 100644 --- a/drivers/usb/phy/phy-fsm-usb.c +++ b/drivers/usb/phy/phy-fsm-usb.c | |||
@@ -317,10 +317,12 @@ int otg_statemachine(struct otg_fsm *fsm) | |||
317 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | 317 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); |
318 | break; | 318 | break; |
319 | case OTG_STATE_A_HOST: | 319 | case OTG_STATE_A_HOST: |
320 | if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && | 320 | if (fsm->id || fsm->a_bus_drop) |
321 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | ||
322 | else if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && | ||
321 | fsm->otg->host->b_hnp_enable) | 323 | fsm->otg->host->b_hnp_enable) |
322 | otg_set_state(fsm, OTG_STATE_A_SUSPEND); | 324 | otg_set_state(fsm, OTG_STATE_A_SUSPEND); |
323 | else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) | 325 | else if (!fsm->b_conn) |
324 | otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | 326 | otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); |
325 | else if (!fsm->a_vbus_vld) | 327 | else if (!fsm->a_vbus_vld) |
326 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | 328 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); |
@@ -346,8 +348,7 @@ int otg_statemachine(struct otg_fsm *fsm) | |||
346 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | 348 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); |
347 | break; | 349 | break; |
348 | case OTG_STATE_A_WAIT_VFALL: | 350 | case OTG_STATE_A_WAIT_VFALL: |
349 | if (fsm->a_wait_vfall_tmout || fsm->id || fsm->a_bus_req || | 351 | if (fsm->a_wait_vfall_tmout) |
350 | (!fsm->a_sess_vld && !fsm->b_conn)) | ||
351 | otg_set_state(fsm, OTG_STATE_A_IDLE); | 352 | otg_set_state(fsm, OTG_STATE_A_IDLE); |
352 | break; | 353 | break; |
353 | case OTG_STATE_A_VBUS_ERR: | 354 | case OTG_STATE_A_VBUS_ERR: |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index d204f745ed05..5b37b81f2ef6 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -1428,7 +1428,8 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1428 | motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | 1428 | motg->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); |
1429 | if (!motg->phy.otg) { | 1429 | if (!motg->phy.otg) { |
1430 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | 1430 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); |
1431 | return -ENOMEM; | 1431 | ret = -ENOMEM; |
1432 | goto free_motg; | ||
1432 | } | 1433 | } |
1433 | 1434 | ||
1434 | motg->pdata = dev_get_platdata(&pdev->dev); | 1435 | motg->pdata = dev_get_platdata(&pdev->dev); |
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index b42897b6474c..c42bdf0c4a1f 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2012 Freescale Semiconductor, Inc. | 2 | * Copyright 2012-2013 Freescale Semiconductor, Inc. |
3 | * Copyright (C) 2012 Marek Vasut <marex@denx.de> | 3 | * Copyright (C) 2012 Marek Vasut <marex@denx.de> |
4 | * on behalf of DENX Software Engineering GmbH | 4 | * on behalf of DENX Software Engineering GmbH |
5 | * | 5 | * |
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of_device.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/mfd/syscon.h> | ||
23 | 26 | ||
24 | #define DRIVER_NAME "mxs_phy" | 27 | #define DRIVER_NAME "mxs_phy" |
25 | 28 | ||
@@ -28,18 +31,134 @@ | |||
28 | #define HW_USBPHY_CTRL_SET 0x34 | 31 | #define HW_USBPHY_CTRL_SET 0x34 |
29 | #define HW_USBPHY_CTRL_CLR 0x38 | 32 | #define HW_USBPHY_CTRL_CLR 0x38 |
30 | 33 | ||
34 | #define HW_USBPHY_DEBUG_SET 0x54 | ||
35 | #define HW_USBPHY_DEBUG_CLR 0x58 | ||
36 | |||
37 | #define HW_USBPHY_IP 0x90 | ||
38 | #define HW_USBPHY_IP_SET 0x94 | ||
39 | #define HW_USBPHY_IP_CLR 0x98 | ||
40 | |||
31 | #define BM_USBPHY_CTRL_SFTRST BIT(31) | 41 | #define BM_USBPHY_CTRL_SFTRST BIT(31) |
32 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) | 42 | #define BM_USBPHY_CTRL_CLKGATE BIT(30) |
43 | #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26) | ||
44 | #define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25) | ||
45 | #define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23) | ||
46 | #define BM_USBPHY_CTRL_ENIDCHG_WKUP BIT(22) | ||
47 | #define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21) | ||
48 | #define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20) | ||
49 | #define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19) | ||
50 | #define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL BIT(18) | ||
33 | #define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) | 51 | #define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) |
34 | #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) | 52 | #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) |
35 | #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) | 53 | #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) |
36 | 54 | ||
55 | #define BM_USBPHY_IP_FIX (BIT(17) | BIT(18)) | ||
56 | |||
57 | #define BM_USBPHY_DEBUG_CLKGATE BIT(30) | ||
58 | |||
59 | /* Anatop Registers */ | ||
60 | #define ANADIG_ANA_MISC0 0x150 | ||
61 | #define ANADIG_ANA_MISC0_SET 0x154 | ||
62 | #define ANADIG_ANA_MISC0_CLR 0x158 | ||
63 | |||
64 | #define ANADIG_USB1_VBUS_DET_STAT 0x1c0 | ||
65 | #define ANADIG_USB2_VBUS_DET_STAT 0x220 | ||
66 | |||
67 | #define ANADIG_USB1_LOOPBACK_SET 0x1e4 | ||
68 | #define ANADIG_USB1_LOOPBACK_CLR 0x1e8 | ||
69 | #define ANADIG_USB2_LOOPBACK_SET 0x244 | ||
70 | #define ANADIG_USB2_LOOPBACK_CLR 0x248 | ||
71 | |||
72 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12) | ||
73 | #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11) | ||
74 | |||
75 | #define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3) | ||
76 | #define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3) | ||
77 | |||
78 | #define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2) | ||
79 | #define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5) | ||
80 | #define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2) | ||
81 | #define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5) | ||
82 | |||
83 | #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) | ||
84 | |||
85 | /* Do disconnection between PHY and controller without vbus */ | ||
86 | #define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0) | ||
87 | |||
88 | /* | ||
89 | * The PHY will be in messy if there is a wakeup after putting | ||
90 | * bus to suspend (set portsc.suspendM) but before setting PHY to low | ||
91 | * power mode (set portsc.phcd). | ||
92 | */ | ||
93 | #define MXS_PHY_ABNORMAL_IN_SUSPEND BIT(1) | ||
94 | |||
95 | /* | ||
96 | * The SOF sends too fast after resuming, it will cause disconnection | ||
97 | * between host and high speed device. | ||
98 | */ | ||
99 | #define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2) | ||
100 | |||
101 | /* | ||
102 | * IC has bug fixes logic, they include | ||
103 | * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST | ||
104 | * which are described at above flags, the RTL will handle it | ||
105 | * according to different versions. | ||
106 | */ | ||
107 | #define MXS_PHY_NEED_IP_FIX BIT(3) | ||
108 | |||
109 | struct mxs_phy_data { | ||
110 | unsigned int flags; | ||
111 | }; | ||
112 | |||
113 | static const struct mxs_phy_data imx23_phy_data = { | ||
114 | .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST, | ||
115 | }; | ||
116 | |||
117 | static const struct mxs_phy_data imx6q_phy_data = { | ||
118 | .flags = MXS_PHY_SENDING_SOF_TOO_FAST | | ||
119 | MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | | ||
120 | MXS_PHY_NEED_IP_FIX, | ||
121 | }; | ||
122 | |||
123 | static const struct mxs_phy_data imx6sl_phy_data = { | ||
124 | .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | | ||
125 | MXS_PHY_NEED_IP_FIX, | ||
126 | }; | ||
127 | |||
128 | static const struct of_device_id mxs_phy_dt_ids[] = { | ||
129 | { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, }, | ||
130 | { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, }, | ||
131 | { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, }, | ||
132 | { /* sentinel */ } | ||
133 | }; | ||
134 | MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); | ||
135 | |||
37 | struct mxs_phy { | 136 | struct mxs_phy { |
38 | struct usb_phy phy; | 137 | struct usb_phy phy; |
39 | struct clk *clk; | 138 | struct clk *clk; |
139 | const struct mxs_phy_data *data; | ||
140 | struct regmap *regmap_anatop; | ||
141 | int port_id; | ||
40 | }; | 142 | }; |
41 | 143 | ||
42 | #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) | 144 | static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy) |
145 | { | ||
146 | return mxs_phy->data == &imx6q_phy_data; | ||
147 | } | ||
148 | |||
149 | static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy) | ||
150 | { | ||
151 | return mxs_phy->data == &imx6sl_phy_data; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * PHY needs some 32K cycles to switch from 32K clock to | ||
156 | * bus (such as AHB/AXI, etc) clock. | ||
157 | */ | ||
158 | static void mxs_phy_clock_switch_delay(void) | ||
159 | { | ||
160 | usleep_range(300, 400); | ||
161 | } | ||
43 | 162 | ||
44 | static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) | 163 | static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) |
45 | { | 164 | { |
@@ -53,19 +172,105 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) | |||
53 | /* Power up the PHY */ | 172 | /* Power up the PHY */ |
54 | writel(0, base + HW_USBPHY_PWD); | 173 | writel(0, base + HW_USBPHY_PWD); |
55 | 174 | ||
56 | /* enable FS/LS device */ | 175 | /* |
57 | writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | | 176 | * USB PHY Ctrl Setting |
58 | BM_USBPHY_CTRL_ENUTMILEVEL3, | 177 | * - Auto clock/power on |
178 | * - Enable full/low speed support | ||
179 | */ | ||
180 | writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS | | ||
181 | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE | | ||
182 | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD | | ||
183 | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE | | ||
184 | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL | | ||
185 | BM_USBPHY_CTRL_ENUTMILEVEL2 | | ||
186 | BM_USBPHY_CTRL_ENUTMILEVEL3, | ||
59 | base + HW_USBPHY_CTRL_SET); | 187 | base + HW_USBPHY_CTRL_SET); |
60 | 188 | ||
189 | if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX) | ||
190 | writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET); | ||
191 | |||
61 | return 0; | 192 | return 0; |
62 | } | 193 | } |
63 | 194 | ||
195 | /* Return true if the vbus is there */ | ||
196 | static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy) | ||
197 | { | ||
198 | unsigned int vbus_value; | ||
199 | |||
200 | if (mxs_phy->port_id == 0) | ||
201 | regmap_read(mxs_phy->regmap_anatop, | ||
202 | ANADIG_USB1_VBUS_DET_STAT, | ||
203 | &vbus_value); | ||
204 | else if (mxs_phy->port_id == 1) | ||
205 | regmap_read(mxs_phy->regmap_anatop, | ||
206 | ANADIG_USB2_VBUS_DET_STAT, | ||
207 | &vbus_value); | ||
208 | |||
209 | if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID) | ||
210 | return true; | ||
211 | else | ||
212 | return false; | ||
213 | } | ||
214 | |||
215 | static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) | ||
216 | { | ||
217 | void __iomem *base = mxs_phy->phy.io_priv; | ||
218 | u32 reg; | ||
219 | |||
220 | if (disconnect) | ||
221 | writel_relaxed(BM_USBPHY_DEBUG_CLKGATE, | ||
222 | base + HW_USBPHY_DEBUG_CLR); | ||
223 | |||
224 | if (mxs_phy->port_id == 0) { | ||
225 | reg = disconnect ? ANADIG_USB1_LOOPBACK_SET | ||
226 | : ANADIG_USB1_LOOPBACK_CLR; | ||
227 | regmap_write(mxs_phy->regmap_anatop, reg, | ||
228 | BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 | | ||
229 | BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN); | ||
230 | } else if (mxs_phy->port_id == 1) { | ||
231 | reg = disconnect ? ANADIG_USB2_LOOPBACK_SET | ||
232 | : ANADIG_USB2_LOOPBACK_CLR; | ||
233 | regmap_write(mxs_phy->regmap_anatop, reg, | ||
234 | BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 | | ||
235 | BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN); | ||
236 | } | ||
237 | |||
238 | if (!disconnect) | ||
239 | writel_relaxed(BM_USBPHY_DEBUG_CLKGATE, | ||
240 | base + HW_USBPHY_DEBUG_SET); | ||
241 | |||
242 | /* Delay some time, and let Linestate be SE0 for controller */ | ||
243 | if (disconnect) | ||
244 | usleep_range(500, 1000); | ||
245 | } | ||
246 | |||
247 | static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) | ||
248 | { | ||
249 | bool vbus_is_on = false; | ||
250 | |||
251 | /* If the SoCs don't need to disconnect line without vbus, quit */ | ||
252 | if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS)) | ||
253 | return; | ||
254 | |||
255 | /* If the SoCs don't have anatop, quit */ | ||
256 | if (!mxs_phy->regmap_anatop) | ||
257 | return; | ||
258 | |||
259 | vbus_is_on = mxs_phy_get_vbus_status(mxs_phy); | ||
260 | |||
261 | if (on && !vbus_is_on) | ||
262 | __mxs_phy_disconnect_line(mxs_phy, true); | ||
263 | else | ||
264 | __mxs_phy_disconnect_line(mxs_phy, false); | ||
265 | |||
266 | } | ||
267 | |||
64 | static int mxs_phy_init(struct usb_phy *phy) | 268 | static int mxs_phy_init(struct usb_phy *phy) |
65 | { | 269 | { |
66 | int ret; | 270 | int ret; |
67 | struct mxs_phy *mxs_phy = to_mxs_phy(phy); | 271 | struct mxs_phy *mxs_phy = to_mxs_phy(phy); |
68 | 272 | ||
273 | mxs_phy_clock_switch_delay(); | ||
69 | ret = clk_prepare_enable(mxs_phy->clk); | 274 | ret = clk_prepare_enable(mxs_phy->clk); |
70 | if (ret) | 275 | if (ret) |
71 | return ret; | 276 | return ret; |
@@ -94,6 +299,7 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) | |||
94 | x->io_priv + HW_USBPHY_CTRL_SET); | 299 | x->io_priv + HW_USBPHY_CTRL_SET); |
95 | clk_disable_unprepare(mxs_phy->clk); | 300 | clk_disable_unprepare(mxs_phy->clk); |
96 | } else { | 301 | } else { |
302 | mxs_phy_clock_switch_delay(); | ||
97 | ret = clk_prepare_enable(mxs_phy->clk); | 303 | ret = clk_prepare_enable(mxs_phy->clk); |
98 | if (ret) | 304 | if (ret) |
99 | return ret; | 305 | return ret; |
@@ -105,11 +311,28 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend) | |||
105 | return 0; | 311 | return 0; |
106 | } | 312 | } |
107 | 313 | ||
314 | static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled) | ||
315 | { | ||
316 | struct mxs_phy *mxs_phy = to_mxs_phy(x); | ||
317 | u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP | | ||
318 | BM_USBPHY_CTRL_ENDPDMCHG_WKUP | | ||
319 | BM_USBPHY_CTRL_ENIDCHG_WKUP; | ||
320 | if (enabled) { | ||
321 | mxs_phy_disconnect_line(mxs_phy, true); | ||
322 | writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET); | ||
323 | } else { | ||
324 | writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR); | ||
325 | mxs_phy_disconnect_line(mxs_phy, false); | ||
326 | } | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
108 | static int mxs_phy_on_connect(struct usb_phy *phy, | 331 | static int mxs_phy_on_connect(struct usb_phy *phy, |
109 | enum usb_device_speed speed) | 332 | enum usb_device_speed speed) |
110 | { | 333 | { |
111 | dev_dbg(phy->dev, "%s speed device has connected\n", | 334 | dev_dbg(phy->dev, "%s device has connected\n", |
112 | (speed == USB_SPEED_HIGH) ? "high" : "non-high"); | 335 | (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); |
113 | 336 | ||
114 | if (speed == USB_SPEED_HIGH) | 337 | if (speed == USB_SPEED_HIGH) |
115 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, | 338 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, |
@@ -121,8 +344,8 @@ static int mxs_phy_on_connect(struct usb_phy *phy, | |||
121 | static int mxs_phy_on_disconnect(struct usb_phy *phy, | 344 | static int mxs_phy_on_disconnect(struct usb_phy *phy, |
122 | enum usb_device_speed speed) | 345 | enum usb_device_speed speed) |
123 | { | 346 | { |
124 | dev_dbg(phy->dev, "%s speed device has disconnected\n", | 347 | dev_dbg(phy->dev, "%s device has disconnected\n", |
125 | (speed == USB_SPEED_HIGH) ? "high" : "non-high"); | 348 | (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS"); |
126 | 349 | ||
127 | if (speed == USB_SPEED_HIGH) | 350 | if (speed == USB_SPEED_HIGH) |
128 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, | 351 | writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, |
@@ -138,6 +361,9 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
138 | struct clk *clk; | 361 | struct clk *clk; |
139 | struct mxs_phy *mxs_phy; | 362 | struct mxs_phy *mxs_phy; |
140 | int ret; | 363 | int ret; |
364 | const struct of_device_id *of_id = | ||
365 | of_match_device(mxs_phy_dt_ids, &pdev->dev); | ||
366 | struct device_node *np = pdev->dev.of_node; | ||
141 | 367 | ||
142 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 368 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
143 | base = devm_ioremap_resource(&pdev->dev, res); | 369 | base = devm_ioremap_resource(&pdev->dev, res); |
@@ -157,6 +383,22 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
157 | return -ENOMEM; | 383 | return -ENOMEM; |
158 | } | 384 | } |
159 | 385 | ||
386 | /* Some SoCs don't have anatop registers */ | ||
387 | if (of_get_property(np, "fsl,anatop", NULL)) { | ||
388 | mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle | ||
389 | (np, "fsl,anatop"); | ||
390 | if (IS_ERR(mxs_phy->regmap_anatop)) { | ||
391 | dev_dbg(&pdev->dev, | ||
392 | "failed to find regmap for anatop\n"); | ||
393 | return PTR_ERR(mxs_phy->regmap_anatop); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | ret = of_alias_get_id(np, "usbphy"); | ||
398 | if (ret < 0) | ||
399 | dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret); | ||
400 | mxs_phy->port_id = ret; | ||
401 | |||
160 | mxs_phy->phy.io_priv = base; | 402 | mxs_phy->phy.io_priv = base; |
161 | mxs_phy->phy.dev = &pdev->dev; | 403 | mxs_phy->phy.dev = &pdev->dev; |
162 | mxs_phy->phy.label = DRIVER_NAME; | 404 | mxs_phy->phy.label = DRIVER_NAME; |
@@ -166,11 +408,15 @@ static int mxs_phy_probe(struct platform_device *pdev) | |||
166 | mxs_phy->phy.notify_connect = mxs_phy_on_connect; | 408 | mxs_phy->phy.notify_connect = mxs_phy_on_connect; |
167 | mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; | 409 | mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; |
168 | mxs_phy->phy.type = USB_PHY_TYPE_USB2; | 410 | mxs_phy->phy.type = USB_PHY_TYPE_USB2; |
411 | mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup; | ||
169 | 412 | ||
170 | mxs_phy->clk = clk; | 413 | mxs_phy->clk = clk; |
414 | mxs_phy->data = of_id->data; | ||
171 | 415 | ||
172 | platform_set_drvdata(pdev, mxs_phy); | 416 | platform_set_drvdata(pdev, mxs_phy); |
173 | 417 | ||
418 | device_set_wakeup_capable(&pdev->dev, true); | ||
419 | |||
174 | ret = usb_add_phy_dev(&mxs_phy->phy); | 420 | ret = usb_add_phy_dev(&mxs_phy->phy); |
175 | if (ret) | 421 | if (ret) |
176 | return ret; | 422 | return ret; |
@@ -187,11 +433,46 @@ static int mxs_phy_remove(struct platform_device *pdev) | |||
187 | return 0; | 433 | return 0; |
188 | } | 434 | } |
189 | 435 | ||
190 | static const struct of_device_id mxs_phy_dt_ids[] = { | 436 | #ifdef CONFIG_PM_SLEEP |
191 | { .compatible = "fsl,imx23-usbphy", }, | 437 | static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on) |
192 | { /* sentinel */ } | 438 | { |
193 | }; | 439 | unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR; |
194 | MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); | 440 | |
441 | /* If the SoCs don't have anatop, quit */ | ||
442 | if (!mxs_phy->regmap_anatop) | ||
443 | return; | ||
444 | |||
445 | if (is_imx6q_phy(mxs_phy)) | ||
446 | regmap_write(mxs_phy->regmap_anatop, reg, | ||
447 | BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG); | ||
448 | else if (is_imx6sl_phy(mxs_phy)) | ||
449 | regmap_write(mxs_phy->regmap_anatop, | ||
450 | reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL); | ||
451 | } | ||
452 | |||
453 | static int mxs_phy_system_suspend(struct device *dev) | ||
454 | { | ||
455 | struct mxs_phy *mxs_phy = dev_get_drvdata(dev); | ||
456 | |||
457 | if (device_may_wakeup(dev)) | ||
458 | mxs_phy_enable_ldo_in_suspend(mxs_phy, true); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static int mxs_phy_system_resume(struct device *dev) | ||
464 | { | ||
465 | struct mxs_phy *mxs_phy = dev_get_drvdata(dev); | ||
466 | |||
467 | if (device_may_wakeup(dev)) | ||
468 | mxs_phy_enable_ldo_in_suspend(mxs_phy, false); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | #endif /* CONFIG_PM_SLEEP */ | ||
473 | |||
474 | static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, | ||
475 | mxs_phy_system_resume); | ||
195 | 476 | ||
196 | static struct platform_driver mxs_phy_driver = { | 477 | static struct platform_driver mxs_phy_driver = { |
197 | .probe = mxs_phy_probe, | 478 | .probe = mxs_phy_probe, |
@@ -200,6 +481,7 @@ static struct platform_driver mxs_phy_driver = { | |||
200 | .name = DRIVER_NAME, | 481 | .name = DRIVER_NAME, |
201 | .owner = THIS_MODULE, | 482 | .owner = THIS_MODULE, |
202 | .of_match_table = mxs_phy_dt_ids, | 483 | .of_match_table = mxs_phy_dt_ids, |
484 | .pm = &mxs_phy_pm, | ||
203 | }, | 485 | }, |
204 | }; | 486 | }; |
205 | 487 | ||
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c deleted file mode 100644 index 0c6ba29bdddd..000000000000 --- a/drivers/usb/phy/phy-omap-usb3.c +++ /dev/null | |||
@@ -1,361 +0,0 @@ | |||
1 | /* | ||
2 | * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP. | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
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 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/usb/omap_usb.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/clk.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/pm_runtime.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/usb/omap_control_usb.h> | ||
29 | #include <linux/of_platform.h> | ||
30 | |||
31 | #define PLL_STATUS 0x00000004 | ||
32 | #define PLL_GO 0x00000008 | ||
33 | #define PLL_CONFIGURATION1 0x0000000C | ||
34 | #define PLL_CONFIGURATION2 0x00000010 | ||
35 | #define PLL_CONFIGURATION3 0x00000014 | ||
36 | #define PLL_CONFIGURATION4 0x00000020 | ||
37 | |||
38 | #define PLL_REGM_MASK 0x001FFE00 | ||
39 | #define PLL_REGM_SHIFT 0x9 | ||
40 | #define PLL_REGM_F_MASK 0x0003FFFF | ||
41 | #define PLL_REGM_F_SHIFT 0x0 | ||
42 | #define PLL_REGN_MASK 0x000001FE | ||
43 | #define PLL_REGN_SHIFT 0x1 | ||
44 | #define PLL_SELFREQDCO_MASK 0x0000000E | ||
45 | #define PLL_SELFREQDCO_SHIFT 0x1 | ||
46 | #define PLL_SD_MASK 0x0003FC00 | ||
47 | #define PLL_SD_SHIFT 0x9 | ||
48 | #define SET_PLL_GO 0x1 | ||
49 | #define PLL_TICOPWDN 0x10000 | ||
50 | #define PLL_LOCK 0x2 | ||
51 | #define PLL_IDLE 0x1 | ||
52 | |||
53 | /* | ||
54 | * This is an Empirical value that works, need to confirm the actual | ||
55 | * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status | ||
56 | * to be correctly reflected in the USB3PHY_PLL_STATUS register. | ||
57 | */ | ||
58 | # define PLL_IDLE_TIME 100; | ||
59 | |||
60 | struct usb_dpll_map { | ||
61 | unsigned long rate; | ||
62 | struct usb_dpll_params params; | ||
63 | }; | ||
64 | |||
65 | static struct usb_dpll_map dpll_map[] = { | ||
66 | {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ | ||
67 | {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ | ||
68 | {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ | ||
69 | {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ | ||
70 | {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ | ||
71 | {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ | ||
72 | }; | ||
73 | |||
74 | static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate) | ||
75 | { | ||
76 | int i; | ||
77 | |||
78 | for (i = 0; i < ARRAY_SIZE(dpll_map); i++) { | ||
79 | if (rate == dpll_map[i].rate) | ||
80 | return &dpll_map[i].params; | ||
81 | } | ||
82 | |||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | static int omap_usb3_suspend(struct usb_phy *x, int suspend) | ||
87 | { | ||
88 | struct omap_usb *phy = phy_to_omapusb(x); | ||
89 | int val; | ||
90 | int timeout = PLL_IDLE_TIME; | ||
91 | |||
92 | if (suspend && !phy->is_suspended) { | ||
93 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
94 | val |= PLL_IDLE; | ||
95 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
96 | |||
97 | do { | ||
98 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
99 | if (val & PLL_TICOPWDN) | ||
100 | break; | ||
101 | udelay(1); | ||
102 | } while (--timeout); | ||
103 | |||
104 | omap_control_usb_phy_power(phy->control_dev, 0); | ||
105 | |||
106 | phy->is_suspended = 1; | ||
107 | } else if (!suspend && phy->is_suspended) { | ||
108 | phy->is_suspended = 0; | ||
109 | |||
110 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
111 | val &= ~PLL_IDLE; | ||
112 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
113 | |||
114 | do { | ||
115 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
116 | if (!(val & PLL_TICOPWDN)) | ||
117 | break; | ||
118 | udelay(1); | ||
119 | } while (--timeout); | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static void omap_usb_dpll_relock(struct omap_usb *phy) | ||
126 | { | ||
127 | u32 val; | ||
128 | unsigned long timeout; | ||
129 | |||
130 | omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); | ||
131 | |||
132 | timeout = jiffies + msecs_to_jiffies(20); | ||
133 | do { | ||
134 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS); | ||
135 | if (val & PLL_LOCK) | ||
136 | break; | ||
137 | } while (!WARN_ON(time_after(jiffies, timeout))); | ||
138 | } | ||
139 | |||
140 | static int omap_usb_dpll_lock(struct omap_usb *phy) | ||
141 | { | ||
142 | u32 val; | ||
143 | unsigned long rate; | ||
144 | struct usb_dpll_params *dpll_params; | ||
145 | |||
146 | rate = clk_get_rate(phy->sys_clk); | ||
147 | dpll_params = omap_usb3_get_dpll_params(rate); | ||
148 | if (!dpll_params) { | ||
149 | dev_err(phy->dev, | ||
150 | "No DPLL configuration for %lu Hz SYS CLK\n", rate); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | |||
154 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
155 | val &= ~PLL_REGN_MASK; | ||
156 | val |= dpll_params->n << PLL_REGN_SHIFT; | ||
157 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
158 | |||
159 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); | ||
160 | val &= ~PLL_SELFREQDCO_MASK; | ||
161 | val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; | ||
162 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); | ||
163 | |||
164 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); | ||
165 | val &= ~PLL_REGM_MASK; | ||
166 | val |= dpll_params->m << PLL_REGM_SHIFT; | ||
167 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); | ||
168 | |||
169 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); | ||
170 | val &= ~PLL_REGM_F_MASK; | ||
171 | val |= dpll_params->mf << PLL_REGM_F_SHIFT; | ||
172 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); | ||
173 | |||
174 | val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); | ||
175 | val &= ~PLL_SD_MASK; | ||
176 | val |= dpll_params->sd << PLL_SD_SHIFT; | ||
177 | omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); | ||
178 | |||
179 | omap_usb_dpll_relock(phy); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int omap_usb3_init(struct usb_phy *x) | ||
185 | { | ||
186 | struct omap_usb *phy = phy_to_omapusb(x); | ||
187 | int ret; | ||
188 | |||
189 | ret = omap_usb_dpll_lock(phy); | ||
190 | if (ret) | ||
191 | return ret; | ||
192 | |||
193 | omap_control_usb_phy_power(phy->control_dev, 1); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int omap_usb3_probe(struct platform_device *pdev) | ||
199 | { | ||
200 | struct omap_usb *phy; | ||
201 | struct resource *res; | ||
202 | struct device_node *node = pdev->dev.of_node; | ||
203 | struct device_node *control_node; | ||
204 | struct platform_device *control_pdev; | ||
205 | |||
206 | if (!node) | ||
207 | return -EINVAL; | ||
208 | |||
209 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | ||
210 | if (!phy) { | ||
211 | dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n"); | ||
212 | return -ENOMEM; | ||
213 | } | ||
214 | |||
215 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); | ||
216 | phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); | ||
217 | if (IS_ERR(phy->pll_ctrl_base)) | ||
218 | return PTR_ERR(phy->pll_ctrl_base); | ||
219 | |||
220 | phy->dev = &pdev->dev; | ||
221 | |||
222 | phy->phy.dev = phy->dev; | ||
223 | phy->phy.label = "omap-usb3"; | ||
224 | phy->phy.init = omap_usb3_init; | ||
225 | phy->phy.set_suspend = omap_usb3_suspend; | ||
226 | phy->phy.type = USB_PHY_TYPE_USB3; | ||
227 | |||
228 | phy->is_suspended = 1; | ||
229 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | ||
230 | if (IS_ERR(phy->wkupclk)) { | ||
231 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | ||
232 | return PTR_ERR(phy->wkupclk); | ||
233 | } | ||
234 | clk_prepare(phy->wkupclk); | ||
235 | |||
236 | phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); | ||
237 | if (IS_ERR(phy->optclk)) { | ||
238 | dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); | ||
239 | return PTR_ERR(phy->optclk); | ||
240 | } | ||
241 | clk_prepare(phy->optclk); | ||
242 | |||
243 | phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); | ||
244 | if (IS_ERR(phy->sys_clk)) { | ||
245 | pr_err("%s: unable to get sys_clkin\n", __func__); | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | control_node = of_parse_phandle(node, "ctrl-module", 0); | ||
250 | if (!control_node) { | ||
251 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | control_pdev = of_find_device_by_node(control_node); | ||
255 | if (!control_pdev) { | ||
256 | dev_err(&pdev->dev, "Failed to get control device\n"); | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | |||
260 | phy->control_dev = &control_pdev->dev; | ||
261 | |||
262 | omap_control_usb_phy_power(phy->control_dev, 0); | ||
263 | usb_add_phy_dev(&phy->phy); | ||
264 | |||
265 | platform_set_drvdata(pdev, phy); | ||
266 | |||
267 | pm_runtime_enable(phy->dev); | ||
268 | pm_runtime_get(&pdev->dev); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int omap_usb3_remove(struct platform_device *pdev) | ||
274 | { | ||
275 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
276 | |||
277 | clk_unprepare(phy->wkupclk); | ||
278 | clk_unprepare(phy->optclk); | ||
279 | usb_remove_phy(&phy->phy); | ||
280 | if (!pm_runtime_suspended(&pdev->dev)) | ||
281 | pm_runtime_put(&pdev->dev); | ||
282 | pm_runtime_disable(&pdev->dev); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | #ifdef CONFIG_PM_RUNTIME | ||
288 | |||
289 | static int omap_usb3_runtime_suspend(struct device *dev) | ||
290 | { | ||
291 | struct platform_device *pdev = to_platform_device(dev); | ||
292 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
293 | |||
294 | clk_disable(phy->wkupclk); | ||
295 | clk_disable(phy->optclk); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static int omap_usb3_runtime_resume(struct device *dev) | ||
301 | { | ||
302 | u32 ret = 0; | ||
303 | struct platform_device *pdev = to_platform_device(dev); | ||
304 | struct omap_usb *phy = platform_get_drvdata(pdev); | ||
305 | |||
306 | ret = clk_enable(phy->optclk); | ||
307 | if (ret) { | ||
308 | dev_err(phy->dev, "Failed to enable optclk %d\n", ret); | ||
309 | goto err1; | ||
310 | } | ||
311 | |||
312 | ret = clk_enable(phy->wkupclk); | ||
313 | if (ret) { | ||
314 | dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); | ||
315 | goto err2; | ||
316 | } | ||
317 | |||
318 | return 0; | ||
319 | |||
320 | err2: | ||
321 | clk_disable(phy->optclk); | ||
322 | |||
323 | err1: | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | static const struct dev_pm_ops omap_usb3_pm_ops = { | ||
328 | SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume, | ||
329 | NULL) | ||
330 | }; | ||
331 | |||
332 | #define DEV_PM_OPS (&omap_usb3_pm_ops) | ||
333 | #else | ||
334 | #define DEV_PM_OPS NULL | ||
335 | #endif | ||
336 | |||
337 | #ifdef CONFIG_OF | ||
338 | static const struct of_device_id omap_usb3_id_table[] = { | ||
339 | { .compatible = "ti,omap-usb3" }, | ||
340 | {} | ||
341 | }; | ||
342 | MODULE_DEVICE_TABLE(of, omap_usb3_id_table); | ||
343 | #endif | ||
344 | |||
345 | static struct platform_driver omap_usb3_driver = { | ||
346 | .probe = omap_usb3_probe, | ||
347 | .remove = omap_usb3_remove, | ||
348 | .driver = { | ||
349 | .name = "omap-usb3", | ||
350 | .owner = THIS_MODULE, | ||
351 | .pm = DEV_PM_OPS, | ||
352 | .of_match_table = of_match_ptr(omap_usb3_id_table), | ||
353 | }, | ||
354 | }; | ||
355 | |||
356 | module_platform_driver(omap_usb3_driver); | ||
357 | |||
358 | MODULE_ALIAS("platform: omap_usb3"); | ||
359 | MODULE_AUTHOR("Texas Instruments Inc."); | ||
360 | MODULE_DESCRIPTION("OMAP USB3 phy driver"); | ||
361 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c index 551e0a6c0e22..388d89f6b141 100644 --- a/drivers/usb/phy/phy-rcar-gen2-usb.c +++ b/drivers/usb/phy/phy-rcar-gen2-usb.c | |||
@@ -177,15 +177,15 @@ static int rcar_gen2_usb_phy_probe(struct platform_device *pdev) | |||
177 | struct clk *clk; | 177 | struct clk *clk; |
178 | int retval; | 178 | int retval; |
179 | 179 | ||
180 | pdata = dev_get_platdata(&pdev->dev); | 180 | pdata = dev_get_platdata(dev); |
181 | if (!pdata) { | 181 | if (!pdata) { |
182 | dev_err(dev, "No platform data\n"); | 182 | dev_err(dev, "No platform data\n"); |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | } | 184 | } |
185 | 185 | ||
186 | clk = devm_clk_get(&pdev->dev, "usbhs"); | 186 | clk = devm_clk_get(dev, "usbhs"); |
187 | if (IS_ERR(clk)) { | 187 | if (IS_ERR(clk)) { |
188 | dev_err(&pdev->dev, "Can't get the clock\n"); | 188 | dev_err(dev, "Can't get the clock\n"); |
189 | return PTR_ERR(clk); | 189 | return PTR_ERR(clk); |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 214172b68d5d..04778cf80d60 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/usb/musb-omap.h> | 28 | #include <linux/usb/musb-omap.h> |
29 | #include <linux/usb/phy_companion.h> | 29 | #include <linux/usb/phy_companion.h> |
30 | #include <linux/usb/omap_usb.h> | 30 | #include <linux/phy/omap_usb.h> |
31 | #include <linux/i2c/twl.h> | 31 | #include <linux/i2c/twl.h> |
32 | #include <linux/regulator/consumer.h> | 32 | #include <linux/regulator/consumer.h> |
33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 217339dd7a90..17ea3f271bd8 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c | |||
@@ -47,6 +47,8 @@ struct ulpi_info { | |||
47 | static struct ulpi_info ulpi_ids[] = { | 47 | static struct ulpi_info ulpi_ids[] = { |
48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), | 48 | ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), |
49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), | 49 | ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), |
50 | ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), | ||
51 | ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | static int ulpi_set_otg_flags(struct usb_phy *phy) | 54 | static int ulpi_set_otg_flags(struct usb_phy *phy) |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 82371f61f23d..2d72aa3564a3 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -323,11 +323,11 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
323 | if (r) | 323 | if (r) |
324 | goto out; | 324 | goto out; |
325 | 325 | ||
326 | dev_dbg(&port->dev, "%s - submitting interrupt urb", __func__); | 326 | dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__); |
327 | r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 327 | r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
328 | if (r) { | 328 | if (r) { |
329 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | 329 | dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n", |
330 | " error %d\n", __func__, r); | 330 | __func__, r); |
331 | ch341_close(port); | 331 | ch341_close(port); |
332 | goto out; | 332 | goto out; |
333 | } | 333 | } |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 0ac3b3b3236c..2916dea3ede8 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -220,7 +220,7 @@ static int cyberjack_write(struct tty_struct *tty, | |||
220 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 220 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
221 | if (result) { | 221 | if (result) { |
222 | dev_err(&port->dev, | 222 | dev_err(&port->dev, |
223 | "%s - failed submitting write urb, error %d", | 223 | "%s - failed submitting write urb, error %d\n", |
224 | __func__, result); | 224 | __func__, result); |
225 | /* Throw away data. No better idea what to do with it. */ | 225 | /* Throw away data. No better idea what to do with it. */ |
226 | priv->wrfilled = 0; | 226 | priv->wrfilled = 0; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index bccb1223143a..01bf53392819 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -279,7 +279,7 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) | |||
279 | * the generic firmware, but are not used with | 279 | * the generic firmware, but are not used with |
280 | * NMEA and SiRF protocols */ | 280 | * NMEA and SiRF protocols */ |
281 | dev_dbg(&port->dev, | 281 | dev_dbg(&port->dev, |
282 | "%s - failed setting baud rate, unsupported speed of %d on Earthmate GPS", | 282 | "%s - failed setting baud rate, unsupported speed of %d on Earthmate GPS\n", |
283 | __func__, new_rate); | 283 | __func__, new_rate); |
284 | return -1; | 284 | return -1; |
285 | } | 285 | } |
@@ -1224,7 +1224,6 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1224 | struct usb_serial_port *port = urb->context; | 1224 | struct usb_serial_port *port = urb->context; |
1225 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1225 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1226 | struct device *dev = &urb->dev->dev; | 1226 | struct device *dev = &urb->dev->dev; |
1227 | int result; | ||
1228 | int status = urb->status; | 1227 | int status = urb->status; |
1229 | 1228 | ||
1230 | switch (status) { | 1229 | switch (status) { |
@@ -1239,21 +1238,9 @@ static void cypress_write_int_callback(struct urb *urb) | |||
1239 | __func__, status); | 1238 | __func__, status); |
1240 | priv->write_urb_in_use = 0; | 1239 | priv->write_urb_in_use = 0; |
1241 | return; | 1240 | return; |
1242 | case -EPIPE: /* no break needed; clear halt and resubmit */ | 1241 | case -EPIPE: |
1243 | if (!priv->comm_is_ok) | 1242 | /* Cannot call usb_clear_halt while in_interrupt */ |
1244 | break; | 1243 | /* FALLTHROUGH */ |
1245 | usb_clear_halt(port->serial->dev, 0x02); | ||
1246 | /* error in the urb, so we have to resubmit it */ | ||
1247 | dev_dbg(dev, "%s - nonzero write bulk status received: %d\n", | ||
1248 | __func__, status); | ||
1249 | port->interrupt_out_urb->transfer_buffer_length = 1; | ||
1250 | result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); | ||
1251 | if (!result) | ||
1252 | return; | ||
1253 | dev_err(dev, "%s - failed resubmitting write urb, error %d\n", | ||
1254 | __func__, result); | ||
1255 | cypress_set_dead(port); | ||
1256 | break; | ||
1257 | default: | 1244 | default: |
1258 | dev_err(dev, "%s - unexpected nonzero write status received: %d\n", | 1245 | dev_err(dev, "%s - unexpected nonzero write status received: %d\n", |
1259 | __func__, status); | 1246 | __func__, status); |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index b63ce023f96f..1bd192290b08 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -332,9 +332,9 @@ void usb_serial_generic_process_read_urb(struct urb *urb) | |||
332 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of | 332 | * stuff like 3G modems, so shortcircuit it in the 99.9999999% of |
333 | * cases where the USB serial is not a console anyway. | 333 | * cases where the USB serial is not a console anyway. |
334 | */ | 334 | */ |
335 | if (!port->port.console || !port->sysrq) | 335 | if (!port->port.console || !port->sysrq) { |
336 | tty_insert_flip_string(&port->port, ch, urb->actual_length); | 336 | tty_insert_flip_string(&port->port, ch, urb->actual_length); |
337 | else { | 337 | } else { |
338 | for (i = 0; i < urb->actual_length; i++, ch++) { | 338 | for (i = 0; i < urb->actual_length; i++, ch++) { |
339 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 339 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
340 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); | 340 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); |
@@ -359,24 +359,38 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) | |||
359 | 359 | ||
360 | dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, | 360 | dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, |
361 | urb->actual_length); | 361 | urb->actual_length); |
362 | 362 | switch (urb->status) { | |
363 | if (urb->status) { | 363 | case 0: |
364 | dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", | 364 | break; |
365 | __func__, urb->status); | 365 | case -ENOENT: |
366 | case -ECONNRESET: | ||
367 | case -ESHUTDOWN: | ||
368 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", | ||
369 | __func__, urb->status); | ||
366 | return; | 370 | return; |
371 | case -EPIPE: | ||
372 | dev_err(&port->dev, "%s - urb stopped: %d\n", | ||
373 | __func__, urb->status); | ||
374 | return; | ||
375 | default: | ||
376 | dev_err(&port->dev, "%s - nonzero urb status: %d\n", | ||
377 | __func__, urb->status); | ||
378 | goto resubmit; | ||
367 | } | 379 | } |
368 | 380 | ||
369 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 381 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
370 | port->serial->type->process_read_urb(urb); | 382 | port->serial->type->process_read_urb(urb); |
371 | 383 | ||
384 | resubmit: | ||
372 | /* Throttle the device if requested by tty */ | 385 | /* Throttle the device if requested by tty */ |
373 | spin_lock_irqsave(&port->lock, flags); | 386 | spin_lock_irqsave(&port->lock, flags); |
374 | port->throttled = port->throttle_req; | 387 | port->throttled = port->throttle_req; |
375 | if (!port->throttled) { | 388 | if (!port->throttled) { |
376 | spin_unlock_irqrestore(&port->lock, flags); | 389 | spin_unlock_irqrestore(&port->lock, flags); |
377 | usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); | 390 | usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); |
378 | } else | 391 | } else { |
379 | spin_unlock_irqrestore(&port->lock, flags); | 392 | spin_unlock_irqrestore(&port->lock, flags); |
393 | } | ||
380 | } | 394 | } |
381 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); | 395 | EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); |
382 | 396 | ||
@@ -384,29 +398,38 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
384 | { | 398 | { |
385 | unsigned long flags; | 399 | unsigned long flags; |
386 | struct usb_serial_port *port = urb->context; | 400 | struct usb_serial_port *port = urb->context; |
387 | int status = urb->status; | ||
388 | int i; | 401 | int i; |
389 | 402 | ||
390 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | 403 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { |
391 | if (port->write_urbs[i] == urb) | 404 | if (port->write_urbs[i] == urb) |
392 | break; | 405 | break; |
393 | 406 | } | |
394 | spin_lock_irqsave(&port->lock, flags); | 407 | spin_lock_irqsave(&port->lock, flags); |
395 | port->tx_bytes -= urb->transfer_buffer_length; | 408 | port->tx_bytes -= urb->transfer_buffer_length; |
396 | set_bit(i, &port->write_urbs_free); | 409 | set_bit(i, &port->write_urbs_free); |
397 | spin_unlock_irqrestore(&port->lock, flags); | 410 | spin_unlock_irqrestore(&port->lock, flags); |
398 | 411 | ||
399 | if (status) { | 412 | switch (urb->status) { |
400 | dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", | 413 | case 0: |
401 | __func__, status); | 414 | break; |
402 | 415 | case -ENOENT: | |
403 | spin_lock_irqsave(&port->lock, flags); | 416 | case -ECONNRESET: |
404 | kfifo_reset_out(&port->write_fifo); | 417 | case -ESHUTDOWN: |
405 | spin_unlock_irqrestore(&port->lock, flags); | 418 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", |
406 | } else { | 419 | __func__, urb->status); |
407 | usb_serial_generic_write_start(port, GFP_ATOMIC); | 420 | return; |
421 | case -EPIPE: | ||
422 | dev_err_console(port, "%s - urb stopped: %d\n", | ||
423 | __func__, urb->status); | ||
424 | return; | ||
425 | default: | ||
426 | dev_err_console(port, "%s - nonzero urb status: %d\n", | ||
427 | __func__, urb->status); | ||
428 | goto resubmit; | ||
408 | } | 429 | } |
409 | 430 | ||
431 | resubmit: | ||
432 | usb_serial_generic_write_start(port, GFP_ATOMIC); | ||
410 | usb_serial_port_softint(port); | 433 | usb_serial_port_softint(port); |
411 | } | 434 | } |
412 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 435 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index d00dae17d520..5ad4a0fb4b26 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -1151,7 +1151,7 @@ static ssize_t vcc_mode_store(struct device *dev, | |||
1151 | goto fail_store_vcc_mode; | 1151 | goto fail_store_vcc_mode; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | dev_dbg(dev, "%s: setting vcc_mode = %ld", __func__, v); | 1154 | dev_dbg(dev, "%s: setting vcc_mode = %ld\n", __func__, v); |
1155 | 1155 | ||
1156 | if ((v != 3) && (v != 5)) { | 1156 | if ((v != 3) && (v != 5)) { |
1157 | dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v); | 1157 | dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v); |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 265c6776b081..d3acaead5a81 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -397,17 +397,6 @@ static void usa26_instat_callback(struct urb *urb) | |||
397 | 397 | ||
398 | msg = (struct keyspan_usa26_portStatusMessage *)data; | 398 | msg = (struct keyspan_usa26_portStatusMessage *)data; |
399 | 399 | ||
400 | #if 0 | ||
401 | dev_dbg(&urb->dev->dev, | ||
402 | "%s - port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d", | ||
403 | __func__, msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, | ||
404 | msg->ri, msg->_txOff, msg->_txXoff, msg->rxEnabled, | ||
405 | msg->controlResponse); | ||
406 | #endif | ||
407 | |||
408 | /* Now do something useful with the data */ | ||
409 | |||
410 | |||
411 | /* Check port number from message and retrieve private data */ | 400 | /* Check port number from message and retrieve private data */ |
412 | if (msg->port >= serial->num_ports) { | 401 | if (msg->port >= serial->num_ports) { |
413 | dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", __func__, msg->port); | 402 | dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", __func__, msg->port); |
@@ -523,9 +512,6 @@ static void usa28_instat_callback(struct urb *urb) | |||
523 | goto exit; | 512 | goto exit; |
524 | } | 513 | } |
525 | 514 | ||
526 | /*dev_dbg(&urb->dev->dev, "%s %12ph", __func__, data);*/ | ||
527 | |||
528 | /* Now do something useful with the data */ | ||
529 | msg = (struct keyspan_usa28_portStatusMessage *)data; | 515 | msg = (struct keyspan_usa28_portStatusMessage *)data; |
530 | 516 | ||
531 | /* Check port number from message and retrieve private data */ | 517 | /* Check port number from message and retrieve private data */ |
@@ -605,9 +591,6 @@ static void usa49_instat_callback(struct urb *urb) | |||
605 | goto exit; | 591 | goto exit; |
606 | } | 592 | } |
607 | 593 | ||
608 | /*dev_dbg(&urb->dev->dev, "%s: %11ph", __func__, data);*/ | ||
609 | |||
610 | /* Now do something useful with the data */ | ||
611 | msg = (struct keyspan_usa49_portStatusMessage *)data; | 594 | msg = (struct keyspan_usa49_portStatusMessage *)data; |
612 | 595 | ||
613 | /* Check port number from message and retrieve private data */ | 596 | /* Check port number from message and retrieve private data */ |
@@ -1793,12 +1776,6 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, | |||
1793 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 1776 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
1794 | if (err != 0) | 1777 | if (err != 0) |
1795 | dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed\n", __func__); | 1778 | dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed\n", __func__); |
1796 | #if 0 | ||
1797 | else { | ||
1798 | dev_dbg(&port->dev, "%s - usb_submit_urb(setup) OK %d bytes\n", __func__, | ||
1799 | this_urb->transfer_buffer_length); | ||
1800 | } | ||
1801 | #endif | ||
1802 | 1779 | ||
1803 | return 0; | 1780 | return 0; |
1804 | } | 1781 | } |
@@ -1976,13 +1953,6 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, | |||
1976 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 1953 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
1977 | if (err != 0) | 1954 | if (err != 0) |
1978 | dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err); | 1955 | dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err); |
1979 | #if 0 | ||
1980 | else { | ||
1981 | dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__, | ||
1982 | outcont_urb, this_urb->transfer_buffer_length, | ||
1983 | usb_pipeendpoint(this_urb->pipe)); | ||
1984 | } | ||
1985 | #endif | ||
1986 | 1956 | ||
1987 | return 0; | 1957 | return 0; |
1988 | } | 1958 | } |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index e972412b614b..742d827f876c 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -189,7 +189,7 @@ exit: | |||
189 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 189 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
190 | if (retval) | 190 | if (retval) |
191 | dev_err(&port->dev, | 191 | dev_err(&port->dev, |
192 | "%s - usb_submit_urb failed with result %d", | 192 | "%s - usb_submit_urb failed with result %d\n", |
193 | __func__, retval); | 193 | __func__, retval); |
194 | } | 194 | } |
195 | 195 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index c88cc4966b23..d7440b7557af 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -201,7 +201,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, | |||
201 | else { | 201 | else { |
202 | status = get_unaligned_le16(status_buf); | 202 | status = get_unaligned_le16(status_buf); |
203 | 203 | ||
204 | dev_info(&port->serial->dev->dev, "read status %x %x", | 204 | dev_info(&port->serial->dev->dev, "read status %x %x\n", |
205 | status_buf[0], status_buf[1]); | 205 | status_buf[0], status_buf[1]); |
206 | 206 | ||
207 | *line_state_p = klsi_105_status2linestate(status); | 207 | *line_state_p = klsi_105_status2linestate(status); |
@@ -464,7 +464,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
464 | priv->cfg.baudrate = kl5kusb105a_sio_b115200; | 464 | priv->cfg.baudrate = kl5kusb105a_sio_b115200; |
465 | break; | 465 | break; |
466 | default: | 466 | default: |
467 | dev_dbg(dev, "KLSI USB->Serial converter: unsupported baudrate request, using default of 9600"); | 467 | dev_dbg(dev, "unsupported baudrate, using 9600\n"); |
468 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; | 468 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; |
469 | baud = 9600; | 469 | baud = 9600; |
470 | break; | 470 | break; |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 618c1c1f227e..fee242387f55 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -557,7 +557,8 @@ static int kobil_ioctl(struct tty_struct *tty, | |||
557 | ); | 557 | ); |
558 | 558 | ||
559 | dev_dbg(&port->dev, | 559 | dev_dbg(&port->dev, |
560 | "%s - Send reset_all_queues (FLUSH) URB returns: %i", __func__, result); | 560 | "%s - Send reset_all_queues (FLUSH) URB returns: %i\n", |
561 | __func__, result); | ||
561 | kfree(transfer_buffer); | 562 | kfree(transfer_buffer); |
562 | return (result < 0) ? -EIO: 0; | 563 | return (result < 0) ? -EIO: 0; |
563 | default: | 564 | default: |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 4eb277225a77..dfd728a263d2 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -209,7 +209,7 @@ static int write_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, | |||
209 | index, NULL, 0, MOS_WDR_TIMEOUT); | 209 | index, NULL, 0, MOS_WDR_TIMEOUT); |
210 | if (status < 0) | 210 | if (status < 0) |
211 | dev_err(&usbdev->dev, | 211 | dev_err(&usbdev->dev, |
212 | "mos7720: usb_control_msg() failed: %d", status); | 212 | "mos7720: usb_control_msg() failed: %d\n", status); |
213 | return status; | 213 | return status; |
214 | } | 214 | } |
215 | 215 | ||
@@ -240,7 +240,7 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, | |||
240 | *data = *buf; | 240 | *data = *buf; |
241 | else if (status < 0) | 241 | else if (status < 0) |
242 | dev_err(&usbdev->dev, | 242 | dev_err(&usbdev->dev, |
243 | "mos7720: usb_control_msg() failed: %d", status); | 243 | "mos7720: usb_control_msg() failed: %d\n", status); |
244 | kfree(buf); | 244 | kfree(buf); |
245 | 245 | ||
246 | return status; | 246 | return status; |
@@ -399,7 +399,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | |||
399 | &mos_parport->deferred_urbs); | 399 | &mos_parport->deferred_urbs); |
400 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | 400 | spin_unlock_irqrestore(&mos_parport->listlock, flags); |
401 | tasklet_schedule(&mos_parport->urb_tasklet); | 401 | tasklet_schedule(&mos_parport->urb_tasklet); |
402 | dev_dbg(&usbdev->dev, "tasklet scheduled"); | 402 | dev_dbg(&usbdev->dev, "tasklet scheduled\n"); |
403 | return 0; | 403 | return 0; |
404 | } | 404 | } |
405 | 405 | ||
@@ -418,7 +418,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, | |||
418 | mutex_unlock(&serial->disc_mutex); | 418 | mutex_unlock(&serial->disc_mutex); |
419 | if (ret_val) { | 419 | if (ret_val) { |
420 | dev_err(&usbdev->dev, | 420 | dev_err(&usbdev->dev, |
421 | "%s: submit_urb() failed: %d", __func__, ret_val); | 421 | "%s: submit_urb() failed: %d\n", __func__, ret_val); |
422 | spin_lock_irqsave(&mos_parport->listlock, flags); | 422 | spin_lock_irqsave(&mos_parport->listlock, flags); |
423 | list_del(&urbtrack->urblist_entry); | 423 | list_del(&urbtrack->urblist_entry); |
424 | spin_unlock_irqrestore(&mos_parport->listlock, flags); | 424 | spin_unlock_irqrestore(&mos_parport->listlock, flags); |
@@ -656,7 +656,7 @@ static size_t parport_mos7715_write_compat(struct parport *pp, | |||
656 | parport_epilogue(pp); | 656 | parport_epilogue(pp); |
657 | if (retval) { | 657 | if (retval) { |
658 | dev_err(&mos_parport->serial->dev->dev, | 658 | dev_err(&mos_parport->serial->dev->dev, |
659 | "mos7720: usb_bulk_msg() failed: %d", retval); | 659 | "mos7720: usb_bulk_msg() failed: %d\n", retval); |
660 | return 0; | 660 | return 0; |
661 | } | 661 | } |
662 | return actual_len; | 662 | return actual_len; |
@@ -875,7 +875,7 @@ static void mos7715_interrupt_callback(struct urb *urb) | |||
875 | if (!(iir & 0x01)) { /* serial port interrupt pending */ | 875 | if (!(iir & 0x01)) { /* serial port interrupt pending */ |
876 | switch (iir & 0x0f) { | 876 | switch (iir & 0x0f) { |
877 | case SERIAL_IIR_RLS: | 877 | case SERIAL_IIR_RLS: |
878 | dev_dbg(dev, "Serial Port: Receiver status error or address bit detected in 9-bit mode\n\n"); | 878 | dev_dbg(dev, "Serial Port: Receiver status error or address bit detected in 9-bit mode\n"); |
879 | break; | 879 | break; |
880 | case SERIAL_IIR_CTI: | 880 | case SERIAL_IIR_CTI: |
881 | dev_dbg(dev, "Serial Port: Receiver time out\n"); | 881 | dev_dbg(dev, "Serial Port: Receiver time out\n"); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index e9d967ff521b..393be562d875 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -522,11 +522,11 @@ static void mos7840_set_led_callback(struct urb *urb) | |||
522 | case -ENOENT: | 522 | case -ENOENT: |
523 | case -ESHUTDOWN: | 523 | case -ESHUTDOWN: |
524 | /* This urb is terminated, clean up */ | 524 | /* This urb is terminated, clean up */ |
525 | dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d", | 525 | dev_dbg(&urb->dev->dev, "%s - urb shutting down: %d\n", |
526 | __func__, urb->status); | 526 | __func__, urb->status); |
527 | break; | 527 | break; |
528 | default: | 528 | default: |
529 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d", | 529 | dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", |
530 | __func__, urb->status); | 530 | __func__, urb->status); |
531 | } | 531 | } |
532 | } | 532 | } |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 7725ed261ed6..504f5bff79c0 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -372,7 +372,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
372 | device_port, data, 2, QT2_USB_TIMEOUT); | 372 | device_port, data, 2, QT2_USB_TIMEOUT); |
373 | 373 | ||
374 | if (status < 0) { | 374 | if (status < 0) { |
375 | dev_err(&port->dev, "%s - open port failed %i", __func__, | 375 | dev_err(&port->dev, "%s - open port failed %i\n", __func__, |
376 | status); | 376 | status); |
377 | kfree(data); | 377 | kfree(data); |
378 | return status; | 378 | return status; |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 4ec04f73c800..ef0dbf0703c5 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -220,9 +220,9 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) | |||
220 | GET_UART_STATUS, GET_UART_STATUS_TYPE, | 220 | GET_UART_STATUS, GET_UART_STATUS_TYPE, |
221 | 0, GET_UART_STATUS_MSR, buf, 1, 100); | 221 | 0, GET_UART_STATUS_MSR, buf, 1, 100); |
222 | if (ret < 0) | 222 | if (ret < 0) |
223 | dev_err(&port->dev, "failed to get modem status: %d", ret); | 223 | dev_err(&port->dev, "failed to get modem status: %d\n", ret); |
224 | 224 | ||
225 | dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x", ret, *buf); | 225 | dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf); |
226 | *status = *buf; | 226 | *status = *buf; |
227 | kfree(buf); | 227 | kfree(buf); |
228 | 228 | ||
@@ -342,8 +342,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
342 | case 1000000: | 342 | case 1000000: |
343 | buf[0] = 0x0b; break; | 343 | buf[0] = 0x0b; break; |
344 | default: | 344 | default: |
345 | dev_err(&port->dev, "spcp825 driver does not support the " | 345 | dev_err(&port->dev, "unsupported baudrate, using 9600\n"); |
346 | "baudrate requested, using default of 9600.\n"); | ||
347 | } | 346 | } |
348 | 347 | ||
349 | /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ | 348 | /* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */ |
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 9fa7dd413e83..8fceec7298e0 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -74,9 +74,7 @@ static void symbol_int_callback(struct urb *urb) | |||
74 | tty_insert_flip_string(&port->port, &data[1], data_length); | 74 | tty_insert_flip_string(&port->port, &data[1], data_length); |
75 | tty_flip_buffer_push(&port->port); | 75 | tty_flip_buffer_push(&port->port); |
76 | } else { | 76 | } else { |
77 | dev_dbg(&port->dev, | 77 | dev_dbg(&port->dev, "%s - short packet\n", __func__); |
78 | "Improper amount of data received from the device, " | ||
79 | "%d bytes", urb->actual_length); | ||
80 | } | 78 | } |
81 | 79 | ||
82 | exit: | 80 | exit: |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index ec7cea585663..3dd3ff8c50d3 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -293,7 +293,7 @@ static int ti_startup(struct usb_serial *serial) | |||
293 | int status; | 293 | int status; |
294 | 294 | ||
295 | dev_dbg(&dev->dev, | 295 | dev_dbg(&dev->dev, |
296 | "%s - product 0x%4X, num configurations %d, configuration value %d", | 296 | "%s - product 0x%4X, num configurations %d, configuration value %d\n", |
297 | __func__, le16_to_cpu(dev->descriptor.idProduct), | 297 | __func__, le16_to_cpu(dev->descriptor.idProduct), |
298 | dev->descriptor.bNumConfigurations, | 298 | dev->descriptor.bNumConfigurations, |
299 | dev->actconfig->desc.bConfigurationValue); | 299 | dev->actconfig->desc.bConfigurationValue); |
@@ -803,7 +803,7 @@ static void ti_set_termios(struct tty_struct *tty, | |||
803 | tty_encode_baud_rate(tty, baud, baud); | 803 | tty_encode_baud_rate(tty, baud, baud); |
804 | 804 | ||
805 | dev_dbg(&port->dev, | 805 | dev_dbg(&port->dev, |
806 | "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d", | 806 | "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d\n", |
807 | __func__, baud, config->wBaudRate, config->wFlags, | 807 | __func__, baud, config->wBaudRate, config->wFlags, |
808 | config->bDataBits, config->bParity, config->bStopBits, | 808 | config->bDataBits, config->bParity, config->bStopBits, |
809 | config->cXon, config->cXoff, config->bUartMode); | 809 | config->cXon, config->cXoff, config->bUartMode); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 7c9dc28640bb..81fc0dfcfdcf 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -868,7 +868,7 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
868 | max_endpoints = max(max_endpoints, (int)serial->num_ports); | 868 | max_endpoints = max(max_endpoints, (int)serial->num_ports); |
869 | serial->num_port_pointers = max_endpoints; | 869 | serial->num_port_pointers = max_endpoints; |
870 | 870 | ||
871 | dev_dbg(ddev, "setting up %d port structures for this device", max_endpoints); | 871 | dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints); |
872 | for (i = 0; i < max_endpoints; ++i) { | 872 | for (i = 0; i < max_endpoints; ++i) { |
873 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); | 873 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
874 | if (!port) | 874 | if (!port) |
@@ -923,9 +923,8 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
923 | port = serial->port[i]; | 923 | port = serial->port[i]; |
924 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) | 924 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) |
925 | goto probe_error; | 925 | goto probe_error; |
926 | buffer_size = serial->type->bulk_out_size; | 926 | buffer_size = max_t(int, serial->type->bulk_out_size, |
927 | if (!buffer_size) | 927 | usb_endpoint_maxp(endpoint)); |
928 | buffer_size = usb_endpoint_maxp(endpoint); | ||
929 | port->bulk_out_size = buffer_size; | 928 | port->bulk_out_size = buffer_size; |
930 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; | 929 | port->bulk_out_endpointAddress = endpoint->bEndpointAddress; |
931 | 930 | ||
@@ -1034,7 +1033,7 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
1034 | for (i = 0; i < num_ports; ++i) { | 1033 | for (i = 0; i < num_ports; ++i) { |
1035 | port = serial->port[i]; | 1034 | port = serial->port[i]; |
1036 | dev_set_name(&port->dev, "ttyUSB%d", port->minor); | 1035 | dev_set_name(&port->dev, "ttyUSB%d", port->minor); |
1037 | dev_dbg(ddev, "registering %s", dev_name(&port->dev)); | 1036 | dev_dbg(ddev, "registering %s\n", dev_name(&port->dev)); |
1038 | device_enable_async_suspend(&port->dev); | 1037 | device_enable_async_suspend(&port->dev); |
1039 | 1038 | ||
1040 | retval = device_add(&port->dev); | 1039 | retval = device_add(&port->dev); |
@@ -1161,9 +1160,9 @@ static int usb_serial_reset_resume(struct usb_interface *intf) | |||
1161 | usb_serial_unpoison_port_urbs(serial); | 1160 | usb_serial_unpoison_port_urbs(serial); |
1162 | 1161 | ||
1163 | serial->suspending = 0; | 1162 | serial->suspending = 0; |
1164 | if (serial->type->reset_resume) | 1163 | if (serial->type->reset_resume) { |
1165 | rv = serial->type->reset_resume(serial); | 1164 | rv = serial->type->reset_resume(serial); |
1166 | else { | 1165 | } else { |
1167 | rv = -EOPNOTSUPP; | 1166 | rv = -EOPNOTSUPP; |
1168 | intf->needs_binding = 1; | 1167 | intf->needs_binding = 1; |
1169 | } | 1168 | } |
@@ -1338,9 +1337,9 @@ static int usb_serial_register(struct usb_serial_driver *driver) | |||
1338 | if (retval) { | 1337 | if (retval) { |
1339 | pr_err("problem %d when registering driver %s\n", retval, driver->description); | 1338 | pr_err("problem %d when registering driver %s\n", retval, driver->description); |
1340 | list_del(&driver->driver_list); | 1339 | list_del(&driver->driver_list); |
1341 | } else | 1340 | } else { |
1342 | pr_info("USB Serial support registered for %s\n", driver->description); | 1341 | pr_info("USB Serial support registered for %s\n", driver->description); |
1343 | 1342 | } | |
1344 | mutex_unlock(&table_lock); | 1343 | mutex_unlock(&table_lock); |
1345 | return retval; | 1344 | return retval; |
1346 | } | 1345 | } |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 1dd0604d1911..13b5bfbaf951 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -204,7 +204,7 @@ config USB_STORAGE_ENE_UB6250 | |||
204 | 204 | ||
205 | config USB_UAS | 205 | config USB_UAS |
206 | tristate "USB Attached SCSI" | 206 | tristate "USB Attached SCSI" |
207 | depends on SCSI && BROKEN | 207 | depends on SCSI && USB_STORAGE |
208 | help | 208 | help |
209 | The USB Attached SCSI protocol is supported by some USB | 209 | The USB Attached SCSI protocol is supported by some USB |
210 | storage devices. It permits higher performance by supporting | 210 | storage devices. It permits higher performance by supporting |
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h new file mode 100644 index 000000000000..bb05b984d5f6 --- /dev/null +++ b/drivers/usb/storage/uas-detect.h | |||
@@ -0,0 +1,96 @@ | |||
1 | #include <linux/usb.h> | ||
2 | #include <linux/usb/hcd.h> | ||
3 | #include "usb.h" | ||
4 | |||
5 | static int uas_is_interface(struct usb_host_interface *intf) | ||
6 | { | ||
7 | return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE && | ||
8 | intf->desc.bInterfaceSubClass == USB_SC_SCSI && | ||
9 | intf->desc.bInterfaceProtocol == USB_PR_UAS); | ||
10 | } | ||
11 | |||
12 | static int uas_isnt_supported(struct usb_device *udev) | ||
13 | { | ||
14 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
15 | |||
16 | dev_warn(&udev->dev, "The driver for the USB controller %s does not " | ||
17 | "support scatter-gather which is\n", | ||
18 | hcd->driver->description); | ||
19 | dev_warn(&udev->dev, "required by the UAS driver. Please try an" | ||
20 | "alternative USB controller if you wish to use UAS.\n"); | ||
21 | return -ENODEV; | ||
22 | } | ||
23 | |||
24 | static int uas_find_uas_alt_setting(struct usb_interface *intf) | ||
25 | { | ||
26 | int i; | ||
27 | struct usb_device *udev = interface_to_usbdev(intf); | ||
28 | int sg_supported = udev->bus->sg_tablesize != 0; | ||
29 | |||
30 | for (i = 0; i < intf->num_altsetting; i++) { | ||
31 | struct usb_host_interface *alt = &intf->altsetting[i]; | ||
32 | |||
33 | if (uas_is_interface(alt)) { | ||
34 | if (!sg_supported) | ||
35 | return uas_isnt_supported(udev); | ||
36 | return alt->desc.bAlternateSetting; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | return -ENODEV; | ||
41 | } | ||
42 | |||
43 | static int uas_find_endpoints(struct usb_host_interface *alt, | ||
44 | struct usb_host_endpoint *eps[]) | ||
45 | { | ||
46 | struct usb_host_endpoint *endpoint = alt->endpoint; | ||
47 | unsigned i, n_endpoints = alt->desc.bNumEndpoints; | ||
48 | |||
49 | for (i = 0; i < n_endpoints; i++) { | ||
50 | unsigned char *extra = endpoint[i].extra; | ||
51 | int len = endpoint[i].extralen; | ||
52 | while (len >= 3) { | ||
53 | if (extra[1] == USB_DT_PIPE_USAGE) { | ||
54 | unsigned pipe_id = extra[2]; | ||
55 | if (pipe_id > 0 && pipe_id < 5) | ||
56 | eps[pipe_id - 1] = &endpoint[i]; | ||
57 | break; | ||
58 | } | ||
59 | len -= extra[0]; | ||
60 | extra += extra[0]; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | if (!eps[0] || !eps[1] || !eps[2] || !eps[3]) | ||
65 | return -ENODEV; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int uas_use_uas_driver(struct usb_interface *intf, | ||
71 | const struct usb_device_id *id) | ||
72 | { | ||
73 | struct usb_host_endpoint *eps[4] = { }; | ||
74 | struct usb_device *udev = interface_to_usbdev(intf); | ||
75 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
76 | unsigned long flags = id->driver_info; | ||
77 | int r, alt; | ||
78 | |||
79 | usb_stor_adjust_quirks(udev, &flags); | ||
80 | |||
81 | if (flags & US_FL_IGNORE_UAS) | ||
82 | return 0; | ||
83 | |||
84 | if (udev->speed >= USB_SPEED_SUPER && !hcd->can_do_streams) | ||
85 | return 0; | ||
86 | |||
87 | alt = uas_find_uas_alt_setting(intf); | ||
88 | if (alt < 0) | ||
89 | return 0; | ||
90 | |||
91 | r = uas_find_endpoints(&intf->altsetting[alt], eps); | ||
92 | if (r < 0) | ||
93 | return 0; | ||
94 | |||
95 | return 1; | ||
96 | } | ||
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index d966b59f7d7b..a7ac97cc5949 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * USB Attached SCSI | 2 | * USB Attached SCSI |
3 | * Note that this is not the same as the USB Mass Storage driver | 3 | * Note that this is not the same as the USB Mass Storage driver |
4 | * | 4 | * |
5 | * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 | ||
5 | * Copyright Matthew Wilcox for Intel Corp, 2010 | 6 | * Copyright Matthew Wilcox for Intel Corp, 2010 |
6 | * Copyright Sarah Sharp for Intel Corp, 2010 | 7 | * Copyright Sarah Sharp for Intel Corp, 2010 |
7 | * | 8 | * |
@@ -13,17 +14,21 @@ | |||
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb_usual.h> | ||
16 | #include <linux/usb/hcd.h> | 18 | #include <linux/usb/hcd.h> |
17 | #include <linux/usb/storage.h> | 19 | #include <linux/usb/storage.h> |
18 | #include <linux/usb/uas.h> | 20 | #include <linux/usb/uas.h> |
19 | 21 | ||
20 | #include <scsi/scsi.h> | 22 | #include <scsi/scsi.h> |
23 | #include <scsi/scsi_eh.h> | ||
21 | #include <scsi/scsi_dbg.h> | 24 | #include <scsi/scsi_dbg.h> |
22 | #include <scsi/scsi_cmnd.h> | 25 | #include <scsi/scsi_cmnd.h> |
23 | #include <scsi/scsi_device.h> | 26 | #include <scsi/scsi_device.h> |
24 | #include <scsi/scsi_host.h> | 27 | #include <scsi/scsi_host.h> |
25 | #include <scsi/scsi_tcq.h> | 28 | #include <scsi/scsi_tcq.h> |
26 | 29 | ||
30 | #include "uas-detect.h" | ||
31 | |||
27 | /* | 32 | /* |
28 | * The r00-r01c specs define this version of the SENSE IU data structure. | 33 | * The r00-r01c specs define this version of the SENSE IU data structure. |
29 | * It's still in use by several different firmware releases. | 34 | * It's still in use by several different firmware releases. |
@@ -45,12 +50,17 @@ struct uas_dev_info { | |||
45 | struct usb_anchor sense_urbs; | 50 | struct usb_anchor sense_urbs; |
46 | struct usb_anchor data_urbs; | 51 | struct usb_anchor data_urbs; |
47 | int qdepth, resetting; | 52 | int qdepth, resetting; |
48 | struct response_ui response; | 53 | struct response_iu response; |
49 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; | 54 | unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; |
50 | unsigned use_streams:1; | 55 | unsigned use_streams:1; |
51 | unsigned uas_sense_old:1; | 56 | unsigned uas_sense_old:1; |
57 | unsigned running_task:1; | ||
58 | unsigned shutdown:1; | ||
52 | struct scsi_cmnd *cmnd; | 59 | struct scsi_cmnd *cmnd; |
53 | spinlock_t lock; | 60 | spinlock_t lock; |
61 | struct work_struct work; | ||
62 | struct list_head inflight_list; | ||
63 | struct list_head dead_list; | ||
54 | }; | 64 | }; |
55 | 65 | ||
56 | enum { | 66 | enum { |
@@ -85,103 +95,117 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
85 | struct uas_dev_info *devinfo, gfp_t gfp); | 95 | struct uas_dev_info *devinfo, gfp_t gfp); |
86 | static void uas_do_work(struct work_struct *work); | 96 | static void uas_do_work(struct work_struct *work); |
87 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller); | 97 | static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller); |
98 | static void uas_free_streams(struct uas_dev_info *devinfo); | ||
99 | static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *caller); | ||
88 | 100 | ||
89 | static DECLARE_WORK(uas_work, uas_do_work); | 101 | /* Must be called with devinfo->lock held, will temporary unlock the lock */ |
90 | static DEFINE_SPINLOCK(uas_work_lock); | ||
91 | static LIST_HEAD(uas_work_list); | ||
92 | |||
93 | static void uas_unlink_data_urbs(struct uas_dev_info *devinfo, | 102 | static void uas_unlink_data_urbs(struct uas_dev_info *devinfo, |
94 | struct uas_cmd_info *cmdinfo) | 103 | struct uas_cmd_info *cmdinfo, |
104 | unsigned long *lock_flags) | ||
95 | { | 105 | { |
96 | unsigned long flags; | ||
97 | |||
98 | /* | 106 | /* |
99 | * The UNLINK_DATA_URBS flag makes sure uas_try_complete | 107 | * The UNLINK_DATA_URBS flag makes sure uas_try_complete |
100 | * (called by urb completion) doesn't release cmdinfo | 108 | * (called by urb completion) doesn't release cmdinfo |
101 | * underneath us. | 109 | * underneath us. |
102 | */ | 110 | */ |
103 | spin_lock_irqsave(&devinfo->lock, flags); | ||
104 | cmdinfo->state |= UNLINK_DATA_URBS; | 111 | cmdinfo->state |= UNLINK_DATA_URBS; |
105 | spin_unlock_irqrestore(&devinfo->lock, flags); | 112 | spin_unlock_irqrestore(&devinfo->lock, *lock_flags); |
106 | 113 | ||
107 | if (cmdinfo->data_in_urb) | 114 | if (cmdinfo->data_in_urb) |
108 | usb_unlink_urb(cmdinfo->data_in_urb); | 115 | usb_unlink_urb(cmdinfo->data_in_urb); |
109 | if (cmdinfo->data_out_urb) | 116 | if (cmdinfo->data_out_urb) |
110 | usb_unlink_urb(cmdinfo->data_out_urb); | 117 | usb_unlink_urb(cmdinfo->data_out_urb); |
111 | 118 | ||
112 | spin_lock_irqsave(&devinfo->lock, flags); | 119 | spin_lock_irqsave(&devinfo->lock, *lock_flags); |
113 | cmdinfo->state &= ~UNLINK_DATA_URBS; | 120 | cmdinfo->state &= ~UNLINK_DATA_URBS; |
114 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
115 | } | 121 | } |
116 | 122 | ||
117 | static void uas_do_work(struct work_struct *work) | 123 | static void uas_do_work(struct work_struct *work) |
118 | { | 124 | { |
125 | struct uas_dev_info *devinfo = | ||
126 | container_of(work, struct uas_dev_info, work); | ||
119 | struct uas_cmd_info *cmdinfo; | 127 | struct uas_cmd_info *cmdinfo; |
120 | struct uas_cmd_info *temp; | ||
121 | struct list_head list; | ||
122 | unsigned long flags; | 128 | unsigned long flags; |
123 | int err; | 129 | int err; |
124 | 130 | ||
125 | spin_lock_irq(&uas_work_lock); | 131 | spin_lock_irqsave(&devinfo->lock, flags); |
126 | list_replace_init(&uas_work_list, &list); | 132 | list_for_each_entry(cmdinfo, &devinfo->inflight_list, list) { |
127 | spin_unlock_irq(&uas_work_lock); | ||
128 | |||
129 | list_for_each_entry_safe(cmdinfo, temp, &list, list) { | ||
130 | struct scsi_pointer *scp = (void *)cmdinfo; | 133 | struct scsi_pointer *scp = (void *)cmdinfo; |
131 | struct scsi_cmnd *cmnd = container_of(scp, | 134 | struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, |
132 | struct scsi_cmnd, SCp); | 135 | SCp); |
133 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 136 | |
134 | spin_lock_irqsave(&devinfo->lock, flags); | 137 | if (!(cmdinfo->state & IS_IN_WORK_LIST)) |
135 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | 138 | continue; |
139 | |||
140 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); | ||
136 | if (!err) | 141 | if (!err) |
137 | cmdinfo->state &= ~IS_IN_WORK_LIST; | 142 | cmdinfo->state &= ~IS_IN_WORK_LIST; |
138 | spin_unlock_irqrestore(&devinfo->lock, flags); | 143 | else |
139 | if (err) { | 144 | schedule_work(&devinfo->work); |
140 | list_del(&cmdinfo->list); | ||
141 | spin_lock_irq(&uas_work_lock); | ||
142 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
143 | spin_unlock_irq(&uas_work_lock); | ||
144 | schedule_work(&uas_work); | ||
145 | } | ||
146 | } | 145 | } |
146 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
147 | } | 147 | } |
148 | 148 | ||
149 | static void uas_abort_work(struct uas_dev_info *devinfo) | 149 | static void uas_mark_cmd_dead(struct uas_dev_info *devinfo, |
150 | struct uas_cmd_info *cmdinfo, | ||
151 | int result, const char *caller) | ||
152 | { | ||
153 | struct scsi_pointer *scp = (void *)cmdinfo; | ||
154 | struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp); | ||
155 | |||
156 | uas_log_cmd_state(cmnd, caller); | ||
157 | WARN_ON_ONCE(!spin_is_locked(&devinfo->lock)); | ||
158 | WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED); | ||
159 | cmdinfo->state |= COMMAND_ABORTED; | ||
160 | cmdinfo->state &= ~IS_IN_WORK_LIST; | ||
161 | cmnd->result = result << 16; | ||
162 | list_move_tail(&cmdinfo->list, &devinfo->dead_list); | ||
163 | } | ||
164 | |||
165 | static void uas_abort_inflight(struct uas_dev_info *devinfo, int result, | ||
166 | const char *caller) | ||
150 | { | 167 | { |
151 | struct uas_cmd_info *cmdinfo; | 168 | struct uas_cmd_info *cmdinfo; |
152 | struct uas_cmd_info *temp; | 169 | struct uas_cmd_info *temp; |
153 | struct list_head list; | ||
154 | unsigned long flags; | 170 | unsigned long flags; |
155 | 171 | ||
156 | spin_lock_irq(&uas_work_lock); | 172 | spin_lock_irqsave(&devinfo->lock, flags); |
157 | list_replace_init(&uas_work_list, &list); | 173 | list_for_each_entry_safe(cmdinfo, temp, &devinfo->inflight_list, list) |
158 | spin_unlock_irq(&uas_work_lock); | 174 | uas_mark_cmd_dead(devinfo, cmdinfo, result, caller); |
175 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
176 | } | ||
177 | |||
178 | static void uas_add_work(struct uas_cmd_info *cmdinfo) | ||
179 | { | ||
180 | struct scsi_pointer *scp = (void *)cmdinfo; | ||
181 | struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp); | ||
182 | struct uas_dev_info *devinfo = cmnd->device->hostdata; | ||
183 | |||
184 | WARN_ON_ONCE(!spin_is_locked(&devinfo->lock)); | ||
185 | cmdinfo->state |= IS_IN_WORK_LIST; | ||
186 | schedule_work(&devinfo->work); | ||
187 | } | ||
188 | |||
189 | static void uas_zap_dead(struct uas_dev_info *devinfo) | ||
190 | { | ||
191 | struct uas_cmd_info *cmdinfo; | ||
192 | struct uas_cmd_info *temp; | ||
193 | unsigned long flags; | ||
159 | 194 | ||
160 | spin_lock_irqsave(&devinfo->lock, flags); | 195 | spin_lock_irqsave(&devinfo->lock, flags); |
161 | list_for_each_entry_safe(cmdinfo, temp, &list, list) { | 196 | list_for_each_entry_safe(cmdinfo, temp, &devinfo->dead_list, list) { |
162 | struct scsi_pointer *scp = (void *)cmdinfo; | 197 | struct scsi_pointer *scp = (void *)cmdinfo; |
163 | struct scsi_cmnd *cmnd = container_of(scp, | 198 | struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, |
164 | struct scsi_cmnd, SCp); | 199 | SCp); |
165 | struct uas_dev_info *di = (void *)cmnd->device->hostdata; | 200 | uas_log_cmd_state(cmnd, __func__); |
166 | 201 | WARN_ON_ONCE(!(cmdinfo->state & COMMAND_ABORTED)); | |
167 | if (di == devinfo) { | 202 | /* all urbs are killed, clear inflight bits */ |
168 | cmdinfo->state |= COMMAND_ABORTED; | 203 | cmdinfo->state &= ~(COMMAND_INFLIGHT | |
169 | cmdinfo->state &= ~IS_IN_WORK_LIST; | 204 | DATA_IN_URB_INFLIGHT | |
170 | if (devinfo->resetting) { | 205 | DATA_OUT_URB_INFLIGHT); |
171 | /* uas_stat_cmplt() will not do that | 206 | uas_try_complete(cmnd, __func__); |
172 | * when a device reset is in | ||
173 | * progress */ | ||
174 | cmdinfo->state &= ~COMMAND_INFLIGHT; | ||
175 | } | ||
176 | uas_try_complete(cmnd, __func__); | ||
177 | } else { | ||
178 | /* not our uas device, relink into list */ | ||
179 | list_del(&cmdinfo->list); | ||
180 | spin_lock_irq(&uas_work_lock); | ||
181 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
182 | spin_unlock_irq(&uas_work_lock); | ||
183 | } | ||
184 | } | 207 | } |
208 | devinfo->running_task = 0; | ||
185 | spin_unlock_irqrestore(&devinfo->lock, flags); | 209 | spin_unlock_irqrestore(&devinfo->lock, flags); |
186 | } | 210 | } |
187 | 211 | ||
@@ -259,20 +283,19 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) | |||
259 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 283 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
260 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; | 284 | struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; |
261 | 285 | ||
262 | WARN_ON(!spin_is_locked(&devinfo->lock)); | 286 | WARN_ON_ONCE(!spin_is_locked(&devinfo->lock)); |
263 | if (cmdinfo->state & (COMMAND_INFLIGHT | | 287 | if (cmdinfo->state & (COMMAND_INFLIGHT | |
264 | DATA_IN_URB_INFLIGHT | | 288 | DATA_IN_URB_INFLIGHT | |
265 | DATA_OUT_URB_INFLIGHT | | 289 | DATA_OUT_URB_INFLIGHT | |
266 | UNLINK_DATA_URBS)) | 290 | UNLINK_DATA_URBS)) |
267 | return -EBUSY; | 291 | return -EBUSY; |
268 | BUG_ON(cmdinfo->state & COMMAND_COMPLETED); | 292 | WARN_ON_ONCE(cmdinfo->state & COMMAND_COMPLETED); |
269 | cmdinfo->state |= COMMAND_COMPLETED; | 293 | cmdinfo->state |= COMMAND_COMPLETED; |
270 | usb_free_urb(cmdinfo->data_in_urb); | 294 | usb_free_urb(cmdinfo->data_in_urb); |
271 | usb_free_urb(cmdinfo->data_out_urb); | 295 | usb_free_urb(cmdinfo->data_out_urb); |
272 | if (cmdinfo->state & COMMAND_ABORTED) { | 296 | if (cmdinfo->state & COMMAND_ABORTED) |
273 | scmd_printk(KERN_INFO, cmnd, "abort completed\n"); | 297 | scmd_printk(KERN_INFO, cmnd, "abort completed\n"); |
274 | cmnd->result = DID_ABORT << 16; | 298 | list_del(&cmdinfo->list); |
275 | } | ||
276 | cmnd->scsi_done(cmnd); | 299 | cmnd->scsi_done(cmnd); |
277 | return 0; | 300 | return 0; |
278 | } | 301 | } |
@@ -286,11 +309,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
286 | cmdinfo->state |= direction | SUBMIT_STATUS_URB; | 309 | cmdinfo->state |= direction | SUBMIT_STATUS_URB; |
287 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | 310 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); |
288 | if (err) { | 311 | if (err) { |
289 | spin_lock(&uas_work_lock); | 312 | uas_add_work(cmdinfo); |
290 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
291 | cmdinfo->state |= IS_IN_WORK_LIST; | ||
292 | spin_unlock(&uas_work_lock); | ||
293 | schedule_work(&uas_work); | ||
294 | } | 313 | } |
295 | } | 314 | } |
296 | 315 | ||
@@ -298,14 +317,20 @@ static void uas_stat_cmplt(struct urb *urb) | |||
298 | { | 317 | { |
299 | struct iu *iu = urb->transfer_buffer; | 318 | struct iu *iu = urb->transfer_buffer; |
300 | struct Scsi_Host *shost = urb->context; | 319 | struct Scsi_Host *shost = urb->context; |
301 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 320 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; |
302 | struct scsi_cmnd *cmnd; | 321 | struct scsi_cmnd *cmnd; |
303 | struct uas_cmd_info *cmdinfo; | 322 | struct uas_cmd_info *cmdinfo; |
304 | unsigned long flags; | 323 | unsigned long flags; |
305 | u16 tag; | 324 | u16 tag; |
306 | 325 | ||
307 | if (urb->status) { | 326 | if (urb->status) { |
308 | dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status); | 327 | if (urb->status == -ENOENT) { |
328 | dev_err(&urb->dev->dev, "stat urb: killed, stream %d\n", | ||
329 | urb->stream_id); | ||
330 | } else { | ||
331 | dev_err(&urb->dev->dev, "stat urb: status %d\n", | ||
332 | urb->status); | ||
333 | } | ||
309 | usb_free_urb(urb); | 334 | usb_free_urb(urb); |
310 | return; | 335 | return; |
311 | } | 336 | } |
@@ -324,6 +349,9 @@ static void uas_stat_cmplt(struct urb *urb) | |||
324 | 349 | ||
325 | if (!cmnd) { | 350 | if (!cmnd) { |
326 | if (iu->iu_id == IU_ID_RESPONSE) { | 351 | if (iu->iu_id == IU_ID_RESPONSE) { |
352 | if (!devinfo->running_task) | ||
353 | dev_warn(&urb->dev->dev, | ||
354 | "stat urb: recv unexpected response iu\n"); | ||
327 | /* store results for uas_eh_task_mgmt() */ | 355 | /* store results for uas_eh_task_mgmt() */ |
328 | memcpy(&devinfo->response, iu, sizeof(devinfo->response)); | 356 | memcpy(&devinfo->response, iu, sizeof(devinfo->response)); |
329 | } | 357 | } |
@@ -346,17 +374,25 @@ static void uas_stat_cmplt(struct urb *urb) | |||
346 | uas_sense(urb, cmnd); | 374 | uas_sense(urb, cmnd); |
347 | if (cmnd->result != 0) { | 375 | if (cmnd->result != 0) { |
348 | /* cancel data transfers on error */ | 376 | /* cancel data transfers on error */ |
349 | spin_unlock_irqrestore(&devinfo->lock, flags); | 377 | uas_unlink_data_urbs(devinfo, cmdinfo, &flags); |
350 | uas_unlink_data_urbs(devinfo, cmdinfo); | ||
351 | spin_lock_irqsave(&devinfo->lock, flags); | ||
352 | } | 378 | } |
353 | cmdinfo->state &= ~COMMAND_INFLIGHT; | 379 | cmdinfo->state &= ~COMMAND_INFLIGHT; |
354 | uas_try_complete(cmnd, __func__); | 380 | uas_try_complete(cmnd, __func__); |
355 | break; | 381 | break; |
356 | case IU_ID_READ_READY: | 382 | case IU_ID_READ_READY: |
383 | if (!cmdinfo->data_in_urb || | ||
384 | (cmdinfo->state & DATA_IN_URB_INFLIGHT)) { | ||
385 | scmd_printk(KERN_ERR, cmnd, "unexpected read rdy\n"); | ||
386 | break; | ||
387 | } | ||
357 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB); | 388 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_IN_URB); |
358 | break; | 389 | break; |
359 | case IU_ID_WRITE_READY: | 390 | case IU_ID_WRITE_READY: |
391 | if (!cmdinfo->data_out_urb || | ||
392 | (cmdinfo->state & DATA_OUT_URB_INFLIGHT)) { | ||
393 | scmd_printk(KERN_ERR, cmnd, "unexpected write rdy\n"); | ||
394 | break; | ||
395 | } | ||
360 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); | 396 | uas_xfer_data(urb, cmnd, SUBMIT_DATA_OUT_URB); |
361 | break; | 397 | break; |
362 | default: | 398 | default: |
@@ -383,8 +419,15 @@ static void uas_data_cmplt(struct urb *urb) | |||
383 | sdb = scsi_out(cmnd); | 419 | sdb = scsi_out(cmnd); |
384 | cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; | 420 | cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT; |
385 | } | 421 | } |
386 | BUG_ON(sdb == NULL); | 422 | if (sdb == NULL) { |
387 | if (urb->status) { | 423 | WARN_ON_ONCE(1); |
424 | } else if (urb->status) { | ||
425 | if (urb->status != -ECONNRESET) { | ||
426 | uas_log_cmd_state(cmnd, __func__); | ||
427 | scmd_printk(KERN_ERR, cmnd, | ||
428 | "data cmplt err %d stream %d\n", | ||
429 | urb->status, urb->stream_id); | ||
430 | } | ||
388 | /* error: no data transfered */ | 431 | /* error: no data transfered */ |
389 | sdb->resid = sdb->length; | 432 | sdb->resid = sdb->length; |
390 | } else { | 433 | } else { |
@@ -394,6 +437,17 @@ static void uas_data_cmplt(struct urb *urb) | |||
394 | spin_unlock_irqrestore(&devinfo->lock, flags); | 437 | spin_unlock_irqrestore(&devinfo->lock, flags); |
395 | } | 438 | } |
396 | 439 | ||
440 | static void uas_cmd_cmplt(struct urb *urb) | ||
441 | { | ||
442 | struct scsi_cmnd *cmnd = urb->context; | ||
443 | |||
444 | if (urb->status) { | ||
445 | uas_log_cmd_state(cmnd, __func__); | ||
446 | scmd_printk(KERN_ERR, cmnd, "cmd cmplt err %d\n", urb->status); | ||
447 | } | ||
448 | usb_free_urb(urb); | ||
449 | } | ||
450 | |||
397 | static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, | 451 | static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, |
398 | unsigned int pipe, u16 stream_id, | 452 | unsigned int pipe, u16 stream_id, |
399 | struct scsi_cmnd *cmnd, | 453 | struct scsi_cmnd *cmnd, |
@@ -408,8 +462,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
408 | goto out; | 462 | goto out; |
409 | usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, | 463 | usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, |
410 | uas_data_cmplt, cmnd); | 464 | uas_data_cmplt, cmnd); |
411 | if (devinfo->use_streams) | 465 | urb->stream_id = stream_id; |
412 | urb->stream_id = stream_id; | ||
413 | urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; | 466 | urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; |
414 | urb->sg = sdb->table.sgl; | 467 | urb->sg = sdb->table.sgl; |
415 | out: | 468 | out: |
@@ -442,7 +495,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
442 | } | 495 | } |
443 | 496 | ||
444 | static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | 497 | static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, |
445 | struct scsi_cmnd *cmnd, u16 stream_id) | 498 | struct scsi_cmnd *cmnd) |
446 | { | 499 | { |
447 | struct usb_device *udev = devinfo->udev; | 500 | struct usb_device *udev = devinfo->udev; |
448 | struct scsi_device *sdev = cmnd->device; | 501 | struct scsi_device *sdev = cmnd->device; |
@@ -472,7 +525,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
472 | memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); | 525 | memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); |
473 | 526 | ||
474 | usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len, | 527 | usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len, |
475 | usb_free_urb, NULL); | 528 | uas_cmd_cmplt, cmnd); |
476 | urb->transfer_flags |= URB_FREE_BUFFER; | 529 | urb->transfer_flags |= URB_FREE_BUFFER; |
477 | out: | 530 | out: |
478 | return urb; | 531 | return urb; |
@@ -512,13 +565,17 @@ static int uas_submit_task_urb(struct scsi_cmnd *cmnd, gfp_t gfp, | |||
512 | } | 565 | } |
513 | 566 | ||
514 | usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu), | 567 | usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu), |
515 | usb_free_urb, NULL); | 568 | uas_cmd_cmplt, cmnd); |
516 | urb->transfer_flags |= URB_FREE_BUFFER; | 569 | urb->transfer_flags |= URB_FREE_BUFFER; |
517 | 570 | ||
571 | usb_anchor_urb(urb, &devinfo->cmd_urbs); | ||
518 | err = usb_submit_urb(urb, gfp); | 572 | err = usb_submit_urb(urb, gfp); |
519 | if (err) | 573 | if (err) { |
574 | usb_unanchor_urb(urb); | ||
575 | uas_log_cmd_state(cmnd, __func__); | ||
576 | scmd_printk(KERN_ERR, cmnd, "task submission err %d\n", err); | ||
520 | goto err; | 577 | goto err; |
521 | usb_anchor_urb(urb, &devinfo->cmd_urbs); | 578 | } |
522 | 579 | ||
523 | return 0; | 580 | return 0; |
524 | 581 | ||
@@ -533,38 +590,43 @@ err: | |||
533 | * daft to me. | 590 | * daft to me. |
534 | */ | 591 | */ |
535 | 592 | ||
536 | static int uas_submit_sense_urb(struct Scsi_Host *shost, | 593 | static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd, |
537 | gfp_t gfp, unsigned int stream) | 594 | gfp_t gfp, unsigned int stream) |
538 | { | 595 | { |
539 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 596 | struct Scsi_Host *shost = cmnd->device->host; |
597 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
540 | struct urb *urb; | 598 | struct urb *urb; |
599 | int err; | ||
541 | 600 | ||
542 | urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream); | 601 | urb = uas_alloc_sense_urb(devinfo, gfp, shost, stream); |
543 | if (!urb) | 602 | if (!urb) |
544 | return SCSI_MLQUEUE_DEVICE_BUSY; | 603 | return NULL; |
545 | if (usb_submit_urb(urb, gfp)) { | 604 | usb_anchor_urb(urb, &devinfo->sense_urbs); |
605 | err = usb_submit_urb(urb, gfp); | ||
606 | if (err) { | ||
607 | usb_unanchor_urb(urb); | ||
608 | uas_log_cmd_state(cmnd, __func__); | ||
546 | shost_printk(KERN_INFO, shost, | 609 | shost_printk(KERN_INFO, shost, |
547 | "sense urb submission failure\n"); | 610 | "sense urb submission error %d stream %d\n", |
611 | err, stream); | ||
548 | usb_free_urb(urb); | 612 | usb_free_urb(urb); |
549 | return SCSI_MLQUEUE_DEVICE_BUSY; | 613 | return NULL; |
550 | } | 614 | } |
551 | usb_anchor_urb(urb, &devinfo->sense_urbs); | 615 | return urb; |
552 | return 0; | ||
553 | } | 616 | } |
554 | 617 | ||
555 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, | 618 | static int uas_submit_urbs(struct scsi_cmnd *cmnd, |
556 | struct uas_dev_info *devinfo, gfp_t gfp) | 619 | struct uas_dev_info *devinfo, gfp_t gfp) |
557 | { | 620 | { |
558 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 621 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
622 | struct urb *urb; | ||
559 | int err; | 623 | int err; |
560 | 624 | ||
561 | WARN_ON(!spin_is_locked(&devinfo->lock)); | 625 | WARN_ON_ONCE(!spin_is_locked(&devinfo->lock)); |
562 | if (cmdinfo->state & SUBMIT_STATUS_URB) { | 626 | if (cmdinfo->state & SUBMIT_STATUS_URB) { |
563 | err = uas_submit_sense_urb(cmnd->device->host, gfp, | 627 | urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream); |
564 | cmdinfo->stream); | 628 | if (!urb) |
565 | if (err) { | 629 | return SCSI_MLQUEUE_DEVICE_BUSY; |
566 | return err; | ||
567 | } | ||
568 | cmdinfo->state &= ~SUBMIT_STATUS_URB; | 630 | cmdinfo->state &= ~SUBMIT_STATUS_URB; |
569 | } | 631 | } |
570 | 632 | ||
@@ -578,14 +640,18 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
578 | } | 640 | } |
579 | 641 | ||
580 | if (cmdinfo->state & SUBMIT_DATA_IN_URB) { | 642 | if (cmdinfo->state & SUBMIT_DATA_IN_URB) { |
581 | if (usb_submit_urb(cmdinfo->data_in_urb, gfp)) { | 643 | usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); |
644 | err = usb_submit_urb(cmdinfo->data_in_urb, gfp); | ||
645 | if (err) { | ||
646 | usb_unanchor_urb(cmdinfo->data_in_urb); | ||
647 | uas_log_cmd_state(cmnd, __func__); | ||
582 | scmd_printk(KERN_INFO, cmnd, | 648 | scmd_printk(KERN_INFO, cmnd, |
583 | "data in urb submission failure\n"); | 649 | "data in urb submission error %d stream %d\n", |
650 | err, cmdinfo->data_in_urb->stream_id); | ||
584 | return SCSI_MLQUEUE_DEVICE_BUSY; | 651 | return SCSI_MLQUEUE_DEVICE_BUSY; |
585 | } | 652 | } |
586 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; | 653 | cmdinfo->state &= ~SUBMIT_DATA_IN_URB; |
587 | cmdinfo->state |= DATA_IN_URB_INFLIGHT; | 654 | cmdinfo->state |= DATA_IN_URB_INFLIGHT; |
588 | usb_anchor_urb(cmdinfo->data_in_urb, &devinfo->data_urbs); | ||
589 | } | 655 | } |
590 | 656 | ||
591 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { | 657 | if (cmdinfo->state & ALLOC_DATA_OUT_URB) { |
@@ -598,33 +664,37 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
598 | } | 664 | } |
599 | 665 | ||
600 | if (cmdinfo->state & SUBMIT_DATA_OUT_URB) { | 666 | if (cmdinfo->state & SUBMIT_DATA_OUT_URB) { |
601 | if (usb_submit_urb(cmdinfo->data_out_urb, gfp)) { | 667 | usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); |
668 | err = usb_submit_urb(cmdinfo->data_out_urb, gfp); | ||
669 | if (err) { | ||
670 | usb_unanchor_urb(cmdinfo->data_out_urb); | ||
671 | uas_log_cmd_state(cmnd, __func__); | ||
602 | scmd_printk(KERN_INFO, cmnd, | 672 | scmd_printk(KERN_INFO, cmnd, |
603 | "data out urb submission failure\n"); | 673 | "data out urb submission error %d stream %d\n", |
674 | err, cmdinfo->data_out_urb->stream_id); | ||
604 | return SCSI_MLQUEUE_DEVICE_BUSY; | 675 | return SCSI_MLQUEUE_DEVICE_BUSY; |
605 | } | 676 | } |
606 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; | 677 | cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; |
607 | cmdinfo->state |= DATA_OUT_URB_INFLIGHT; | 678 | cmdinfo->state |= DATA_OUT_URB_INFLIGHT; |
608 | usb_anchor_urb(cmdinfo->data_out_urb, &devinfo->data_urbs); | ||
609 | } | 679 | } |
610 | 680 | ||
611 | if (cmdinfo->state & ALLOC_CMD_URB) { | 681 | if (cmdinfo->state & ALLOC_CMD_URB) { |
612 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd, | 682 | cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd); |
613 | cmdinfo->stream); | ||
614 | if (!cmdinfo->cmd_urb) | 683 | if (!cmdinfo->cmd_urb) |
615 | return SCSI_MLQUEUE_DEVICE_BUSY; | 684 | return SCSI_MLQUEUE_DEVICE_BUSY; |
616 | cmdinfo->state &= ~ALLOC_CMD_URB; | 685 | cmdinfo->state &= ~ALLOC_CMD_URB; |
617 | } | 686 | } |
618 | 687 | ||
619 | if (cmdinfo->state & SUBMIT_CMD_URB) { | 688 | if (cmdinfo->state & SUBMIT_CMD_URB) { |
620 | usb_get_urb(cmdinfo->cmd_urb); | 689 | usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs); |
621 | if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) { | 690 | err = usb_submit_urb(cmdinfo->cmd_urb, gfp); |
691 | if (err) { | ||
692 | usb_unanchor_urb(cmdinfo->cmd_urb); | ||
693 | uas_log_cmd_state(cmnd, __func__); | ||
622 | scmd_printk(KERN_INFO, cmnd, | 694 | scmd_printk(KERN_INFO, cmnd, |
623 | "cmd urb submission failure\n"); | 695 | "cmd urb submission error %d\n", err); |
624 | return SCSI_MLQUEUE_DEVICE_BUSY; | 696 | return SCSI_MLQUEUE_DEVICE_BUSY; |
625 | } | 697 | } |
626 | usb_anchor_urb(cmdinfo->cmd_urb, &devinfo->cmd_urbs); | ||
627 | usb_put_urb(cmdinfo->cmd_urb); | ||
628 | cmdinfo->cmd_urb = NULL; | 698 | cmdinfo->cmd_urb = NULL; |
629 | cmdinfo->state &= ~SUBMIT_CMD_URB; | 699 | cmdinfo->state &= ~SUBMIT_CMD_URB; |
630 | cmdinfo->state |= COMMAND_INFLIGHT; | 700 | cmdinfo->state |= COMMAND_INFLIGHT; |
@@ -644,18 +714,22 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
644 | 714 | ||
645 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 715 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
646 | 716 | ||
717 | spin_lock_irqsave(&devinfo->lock, flags); | ||
718 | |||
647 | if (devinfo->resetting) { | 719 | if (devinfo->resetting) { |
648 | cmnd->result = DID_ERROR << 16; | 720 | cmnd->result = DID_ERROR << 16; |
649 | cmnd->scsi_done(cmnd); | 721 | cmnd->scsi_done(cmnd); |
722 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
650 | return 0; | 723 | return 0; |
651 | } | 724 | } |
652 | 725 | ||
653 | spin_lock_irqsave(&devinfo->lock, flags); | ||
654 | if (devinfo->cmnd) { | 726 | if (devinfo->cmnd) { |
655 | spin_unlock_irqrestore(&devinfo->lock, flags); | 727 | spin_unlock_irqrestore(&devinfo->lock, flags); |
656 | return SCSI_MLQUEUE_DEVICE_BUSY; | 728 | return SCSI_MLQUEUE_DEVICE_BUSY; |
657 | } | 729 | } |
658 | 730 | ||
731 | memset(cmdinfo, 0, sizeof(*cmdinfo)); | ||
732 | |||
659 | if (blk_rq_tagged(cmnd->request)) { | 733 | if (blk_rq_tagged(cmnd->request)) { |
660 | cmdinfo->stream = cmnd->request->tag + 2; | 734 | cmdinfo->stream = cmnd->request->tag + 2; |
661 | } else { | 735 | } else { |
@@ -692,13 +766,10 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
692 | spin_unlock_irqrestore(&devinfo->lock, flags); | 766 | spin_unlock_irqrestore(&devinfo->lock, flags); |
693 | return SCSI_MLQUEUE_DEVICE_BUSY; | 767 | return SCSI_MLQUEUE_DEVICE_BUSY; |
694 | } | 768 | } |
695 | spin_lock(&uas_work_lock); | 769 | uas_add_work(cmdinfo); |
696 | list_add_tail(&cmdinfo->list, &uas_work_list); | ||
697 | cmdinfo->state |= IS_IN_WORK_LIST; | ||
698 | spin_unlock(&uas_work_lock); | ||
699 | schedule_work(&uas_work); | ||
700 | } | 770 | } |
701 | 771 | ||
772 | list_add_tail(&cmdinfo->list, &devinfo->inflight_list); | ||
702 | spin_unlock_irqrestore(&devinfo->lock, flags); | 773 | spin_unlock_irqrestore(&devinfo->lock, flags); |
703 | return 0; | 774 | return 0; |
704 | } | 775 | } |
@@ -709,46 +780,78 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, | |||
709 | const char *fname, u8 function) | 780 | const char *fname, u8 function) |
710 | { | 781 | { |
711 | struct Scsi_Host *shost = cmnd->device->host; | 782 | struct Scsi_Host *shost = cmnd->device->host; |
712 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 783 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; |
713 | u16 tag = devinfo->qdepth - 1; | 784 | u16 tag = devinfo->qdepth; |
714 | unsigned long flags; | 785 | unsigned long flags; |
786 | struct urb *sense_urb; | ||
787 | int result = SUCCESS; | ||
715 | 788 | ||
716 | spin_lock_irqsave(&devinfo->lock, flags); | 789 | spin_lock_irqsave(&devinfo->lock, flags); |
790 | |||
791 | if (devinfo->resetting) { | ||
792 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
793 | return FAILED; | ||
794 | } | ||
795 | |||
796 | if (devinfo->running_task) { | ||
797 | shost_printk(KERN_INFO, shost, | ||
798 | "%s: %s: error already running a task\n", | ||
799 | __func__, fname); | ||
800 | spin_unlock_irqrestore(&devinfo->lock, flags); | ||
801 | return FAILED; | ||
802 | } | ||
803 | |||
804 | devinfo->running_task = 1; | ||
717 | memset(&devinfo->response, 0, sizeof(devinfo->response)); | 805 | memset(&devinfo->response, 0, sizeof(devinfo->response)); |
718 | if (uas_submit_sense_urb(shost, GFP_ATOMIC, tag)) { | 806 | sense_urb = uas_submit_sense_urb(cmnd, GFP_NOIO, |
807 | devinfo->use_streams ? tag : 0); | ||
808 | if (!sense_urb) { | ||
719 | shost_printk(KERN_INFO, shost, | 809 | shost_printk(KERN_INFO, shost, |
720 | "%s: %s: submit sense urb failed\n", | 810 | "%s: %s: submit sense urb failed\n", |
721 | __func__, fname); | 811 | __func__, fname); |
812 | devinfo->running_task = 0; | ||
722 | spin_unlock_irqrestore(&devinfo->lock, flags); | 813 | spin_unlock_irqrestore(&devinfo->lock, flags); |
723 | return FAILED; | 814 | return FAILED; |
724 | } | 815 | } |
725 | if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) { | 816 | if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) { |
726 | shost_printk(KERN_INFO, shost, | 817 | shost_printk(KERN_INFO, shost, |
727 | "%s: %s: submit task mgmt urb failed\n", | 818 | "%s: %s: submit task mgmt urb failed\n", |
728 | __func__, fname); | 819 | __func__, fname); |
820 | devinfo->running_task = 0; | ||
729 | spin_unlock_irqrestore(&devinfo->lock, flags); | 821 | spin_unlock_irqrestore(&devinfo->lock, flags); |
822 | usb_kill_urb(sense_urb); | ||
730 | return FAILED; | 823 | return FAILED; |
731 | } | 824 | } |
732 | spin_unlock_irqrestore(&devinfo->lock, flags); | 825 | spin_unlock_irqrestore(&devinfo->lock, flags); |
733 | 826 | ||
734 | if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000) == 0) { | 827 | if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 3000) == 0) { |
828 | /* | ||
829 | * Note we deliberately do not clear running_task here. If we | ||
830 | * allow new tasks to be submitted, there is no way to figure | ||
831 | * out if a received response_iu is for the failed task or for | ||
832 | * the new one. A bus-reset will eventually clear running_task. | ||
833 | */ | ||
735 | shost_printk(KERN_INFO, shost, | 834 | shost_printk(KERN_INFO, shost, |
736 | "%s: %s timed out\n", __func__, fname); | 835 | "%s: %s timed out\n", __func__, fname); |
737 | return FAILED; | 836 | return FAILED; |
738 | } | 837 | } |
838 | |||
839 | spin_lock_irqsave(&devinfo->lock, flags); | ||
840 | devinfo->running_task = 0; | ||
739 | if (be16_to_cpu(devinfo->response.tag) != tag) { | 841 | if (be16_to_cpu(devinfo->response.tag) != tag) { |
740 | shost_printk(KERN_INFO, shost, | 842 | shost_printk(KERN_INFO, shost, |
741 | "%s: %s failed (wrong tag %d/%d)\n", __func__, | 843 | "%s: %s failed (wrong tag %d/%d)\n", __func__, |
742 | fname, be16_to_cpu(devinfo->response.tag), tag); | 844 | fname, be16_to_cpu(devinfo->response.tag), tag); |
743 | return FAILED; | 845 | result = FAILED; |
744 | } | 846 | } else if (devinfo->response.response_code != RC_TMF_COMPLETE) { |
745 | if (devinfo->response.response_code != RC_TMF_COMPLETE) { | ||
746 | shost_printk(KERN_INFO, shost, | 847 | shost_printk(KERN_INFO, shost, |
747 | "%s: %s failed (rc 0x%x)\n", __func__, | 848 | "%s: %s failed (rc 0x%x)\n", __func__, |
748 | fname, devinfo->response.response_code); | 849 | fname, devinfo->response.response_code); |
749 | return FAILED; | 850 | result = FAILED; |
750 | } | 851 | } |
751 | return SUCCESS; | 852 | spin_unlock_irqrestore(&devinfo->lock, flags); |
853 | |||
854 | return result; | ||
752 | } | 855 | } |
753 | 856 | ||
754 | static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) | 857 | static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) |
@@ -758,22 +861,19 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) | |||
758 | unsigned long flags; | 861 | unsigned long flags; |
759 | int ret; | 862 | int ret; |
760 | 863 | ||
761 | uas_log_cmd_state(cmnd, __func__); | ||
762 | spin_lock_irqsave(&devinfo->lock, flags); | 864 | spin_lock_irqsave(&devinfo->lock, flags); |
763 | cmdinfo->state |= COMMAND_ABORTED; | 865 | |
764 | if (cmdinfo->state & IS_IN_WORK_LIST) { | 866 | if (devinfo->resetting) { |
765 | spin_lock(&uas_work_lock); | 867 | spin_unlock_irqrestore(&devinfo->lock, flags); |
766 | list_del(&cmdinfo->list); | 868 | return FAILED; |
767 | cmdinfo->state &= ~IS_IN_WORK_LIST; | ||
768 | spin_unlock(&uas_work_lock); | ||
769 | } | 869 | } |
870 | |||
871 | uas_mark_cmd_dead(devinfo, cmdinfo, DID_ABORT, __func__); | ||
770 | if (cmdinfo->state & COMMAND_INFLIGHT) { | 872 | if (cmdinfo->state & COMMAND_INFLIGHT) { |
771 | spin_unlock_irqrestore(&devinfo->lock, flags); | 873 | spin_unlock_irqrestore(&devinfo->lock, flags); |
772 | ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); | 874 | ret = uas_eh_task_mgmt(cmnd, "ABORT TASK", TMF_ABORT_TASK); |
773 | } else { | 875 | } else { |
774 | spin_unlock_irqrestore(&devinfo->lock, flags); | 876 | uas_unlink_data_urbs(devinfo, cmdinfo, &flags); |
775 | uas_unlink_data_urbs(devinfo, cmdinfo); | ||
776 | spin_lock_irqsave(&devinfo->lock, flags); | ||
777 | uas_try_complete(cmnd, __func__); | 877 | uas_try_complete(cmnd, __func__); |
778 | spin_unlock_irqrestore(&devinfo->lock, flags); | 878 | spin_unlock_irqrestore(&devinfo->lock, flags); |
779 | ret = SUCCESS; | 879 | ret = SUCCESS; |
@@ -795,14 +895,25 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
795 | struct usb_device *udev = devinfo->udev; | 895 | struct usb_device *udev = devinfo->udev; |
796 | int err; | 896 | int err; |
797 | 897 | ||
898 | err = usb_lock_device_for_reset(udev, devinfo->intf); | ||
899 | if (err) { | ||
900 | shost_printk(KERN_ERR, sdev->host, | ||
901 | "%s FAILED to get lock err %d\n", __func__, err); | ||
902 | return FAILED; | ||
903 | } | ||
904 | |||
905 | shost_printk(KERN_INFO, sdev->host, "%s start\n", __func__); | ||
798 | devinfo->resetting = 1; | 906 | devinfo->resetting = 1; |
799 | uas_abort_work(devinfo); | 907 | uas_abort_inflight(devinfo, DID_RESET, __func__); |
800 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 908 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); |
801 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 909 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
802 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 910 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
911 | uas_zap_dead(devinfo); | ||
803 | err = usb_reset_device(udev); | 912 | err = usb_reset_device(udev); |
804 | devinfo->resetting = 0; | 913 | devinfo->resetting = 0; |
805 | 914 | ||
915 | usb_unlock_device(udev); | ||
916 | |||
806 | if (err) { | 917 | if (err) { |
807 | shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__); | 918 | shost_printk(KERN_INFO, sdev->host, "%s FAILED\n", __func__); |
808 | return FAILED; | 919 | return FAILED; |
@@ -814,7 +925,25 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
814 | 925 | ||
815 | static int uas_slave_alloc(struct scsi_device *sdev) | 926 | static int uas_slave_alloc(struct scsi_device *sdev) |
816 | { | 927 | { |
817 | sdev->hostdata = (void *)sdev->host->hostdata[0]; | 928 | sdev->hostdata = (void *)sdev->host->hostdata; |
929 | |||
930 | /* USB has unusual DMA-alignment requirements: Although the | ||
931 | * starting address of each scatter-gather element doesn't matter, | ||
932 | * the length of each element except the last must be divisible | ||
933 | * by the Bulk maxpacket value. There's currently no way to | ||
934 | * express this by block-layer constraints, so we'll cop out | ||
935 | * and simply require addresses to be aligned at 512-byte | ||
936 | * boundaries. This is okay since most block I/O involves | ||
937 | * hardware sectors that are multiples of 512 bytes in length, | ||
938 | * and since host controllers up through USB 2.0 have maxpacket | ||
939 | * values no larger than 512. | ||
940 | * | ||
941 | * But it doesn't suffice for Wireless USB, where Bulk maxpacket | ||
942 | * values can be as large as 2048. To make that work properly | ||
943 | * will require changes to the block layer. | ||
944 | */ | ||
945 | blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); | ||
946 | |||
818 | return 0; | 947 | return 0; |
819 | } | 948 | } |
820 | 949 | ||
@@ -822,7 +951,7 @@ static int uas_slave_configure(struct scsi_device *sdev) | |||
822 | { | 951 | { |
823 | struct uas_dev_info *devinfo = sdev->hostdata; | 952 | struct uas_dev_info *devinfo = sdev->hostdata; |
824 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); | 953 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); |
825 | scsi_activate_tcq(sdev, devinfo->qdepth - 3); | 954 | scsi_activate_tcq(sdev, devinfo->qdepth - 2); |
826 | return 0; | 955 | return 0; |
827 | } | 956 | } |
828 | 957 | ||
@@ -843,7 +972,14 @@ static struct scsi_host_template uas_host_template = { | |||
843 | .ordered_tag = 1, | 972 | .ordered_tag = 1, |
844 | }; | 973 | }; |
845 | 974 | ||
975 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
976 | vendorName, productName, useProtocol, useTransport, \ | ||
977 | initFunction, flags) \ | ||
978 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
979 | .driver_info = (flags) } | ||
980 | |||
846 | static struct usb_device_id uas_usb_ids[] = { | 981 | static struct usb_device_id uas_usb_ids[] = { |
982 | # include "unusual_uas.h" | ||
847 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) }, | 983 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) }, |
848 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_UAS) }, | 984 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_UAS) }, |
849 | /* 0xaa is a prototype device I happen to have access to */ | 985 | /* 0xaa is a prototype device I happen to have access to */ |
@@ -852,105 +988,55 @@ static struct usb_device_id uas_usb_ids[] = { | |||
852 | }; | 988 | }; |
853 | MODULE_DEVICE_TABLE(usb, uas_usb_ids); | 989 | MODULE_DEVICE_TABLE(usb, uas_usb_ids); |
854 | 990 | ||
855 | static int uas_is_interface(struct usb_host_interface *intf) | 991 | #undef UNUSUAL_DEV |
856 | { | ||
857 | return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE && | ||
858 | intf->desc.bInterfaceSubClass == USB_SC_SCSI && | ||
859 | intf->desc.bInterfaceProtocol == USB_PR_UAS); | ||
860 | } | ||
861 | |||
862 | static int uas_isnt_supported(struct usb_device *udev) | ||
863 | { | ||
864 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
865 | |||
866 | dev_warn(&udev->dev, "The driver for the USB controller %s does not " | ||
867 | "support scatter-gather which is\n", | ||
868 | hcd->driver->description); | ||
869 | dev_warn(&udev->dev, "required by the UAS driver. Please try an" | ||
870 | "alternative USB controller if you wish to use UAS.\n"); | ||
871 | return -ENODEV; | ||
872 | } | ||
873 | 992 | ||
874 | static int uas_switch_interface(struct usb_device *udev, | 993 | static int uas_switch_interface(struct usb_device *udev, |
875 | struct usb_interface *intf) | 994 | struct usb_interface *intf) |
876 | { | 995 | { |
877 | int i; | 996 | int alt; |
878 | int sg_supported = udev->bus->sg_tablesize != 0; | 997 | |
879 | 998 | alt = uas_find_uas_alt_setting(intf); | |
880 | for (i = 0; i < intf->num_altsetting; i++) { | 999 | if (alt < 0) |
881 | struct usb_host_interface *alt = &intf->altsetting[i]; | 1000 | return alt; |
882 | |||
883 | if (uas_is_interface(alt)) { | ||
884 | if (!sg_supported) | ||
885 | return uas_isnt_supported(udev); | ||
886 | return usb_set_interface(udev, | ||
887 | alt->desc.bInterfaceNumber, | ||
888 | alt->desc.bAlternateSetting); | ||
889 | } | ||
890 | } | ||
891 | 1001 | ||
892 | return -ENODEV; | 1002 | return usb_set_interface(udev, |
1003 | intf->altsetting[0].desc.bInterfaceNumber, alt); | ||
893 | } | 1004 | } |
894 | 1005 | ||
895 | static void uas_configure_endpoints(struct uas_dev_info *devinfo) | 1006 | static int uas_configure_endpoints(struct uas_dev_info *devinfo) |
896 | { | 1007 | { |
897 | struct usb_host_endpoint *eps[4] = { }; | 1008 | struct usb_host_endpoint *eps[4] = { }; |
898 | struct usb_interface *intf = devinfo->intf; | ||
899 | struct usb_device *udev = devinfo->udev; | 1009 | struct usb_device *udev = devinfo->udev; |
900 | struct usb_host_endpoint *endpoint = intf->cur_altsetting->endpoint; | 1010 | int r; |
901 | unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; | ||
902 | 1011 | ||
903 | devinfo->uas_sense_old = 0; | 1012 | devinfo->uas_sense_old = 0; |
904 | devinfo->cmnd = NULL; | 1013 | devinfo->cmnd = NULL; |
905 | 1014 | ||
906 | for (i = 0; i < n_endpoints; i++) { | 1015 | r = uas_find_endpoints(devinfo->intf->cur_altsetting, eps); |
907 | unsigned char *extra = endpoint[i].extra; | 1016 | if (r) |
908 | int len = endpoint[i].extralen; | 1017 | return r; |
909 | while (len > 1) { | ||
910 | if (extra[1] == USB_DT_PIPE_USAGE) { | ||
911 | unsigned pipe_id = extra[2]; | ||
912 | if (pipe_id > 0 && pipe_id < 5) | ||
913 | eps[pipe_id - 1] = &endpoint[i]; | ||
914 | break; | ||
915 | } | ||
916 | len -= extra[0]; | ||
917 | extra += extra[0]; | ||
918 | } | ||
919 | } | ||
920 | 1018 | ||
921 | /* | 1019 | devinfo->cmd_pipe = usb_sndbulkpipe(udev, |
922 | * Assume that if we didn't find a control pipe descriptor, we're | 1020 | usb_endpoint_num(&eps[0]->desc)); |
923 | * using a device with old firmware that happens to be set up like | 1021 | devinfo->status_pipe = usb_rcvbulkpipe(udev, |
924 | * this. | 1022 | usb_endpoint_num(&eps[1]->desc)); |
925 | */ | 1023 | devinfo->data_in_pipe = usb_rcvbulkpipe(udev, |
926 | if (!eps[0]) { | 1024 | usb_endpoint_num(&eps[2]->desc)); |
927 | devinfo->cmd_pipe = usb_sndbulkpipe(udev, 1); | 1025 | devinfo->data_out_pipe = usb_sndbulkpipe(udev, |
928 | devinfo->status_pipe = usb_rcvbulkpipe(udev, 1); | 1026 | usb_endpoint_num(&eps[3]->desc)); |
929 | devinfo->data_in_pipe = usb_rcvbulkpipe(udev, 2); | ||
930 | devinfo->data_out_pipe = usb_sndbulkpipe(udev, 2); | ||
931 | |||
932 | eps[1] = usb_pipe_endpoint(udev, devinfo->status_pipe); | ||
933 | eps[2] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); | ||
934 | eps[3] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); | ||
935 | } else { | ||
936 | devinfo->cmd_pipe = usb_sndbulkpipe(udev, | ||
937 | eps[0]->desc.bEndpointAddress); | ||
938 | devinfo->status_pipe = usb_rcvbulkpipe(udev, | ||
939 | eps[1]->desc.bEndpointAddress); | ||
940 | devinfo->data_in_pipe = usb_rcvbulkpipe(udev, | ||
941 | eps[2]->desc.bEndpointAddress); | ||
942 | devinfo->data_out_pipe = usb_sndbulkpipe(udev, | ||
943 | eps[3]->desc.bEndpointAddress); | ||
944 | } | ||
945 | 1027 | ||
946 | devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, 3, 256, | 1028 | if (udev->speed != USB_SPEED_SUPER) { |
947 | GFP_KERNEL); | ||
948 | if (devinfo->qdepth < 0) { | ||
949 | devinfo->qdepth = 256; | 1029 | devinfo->qdepth = 256; |
950 | devinfo->use_streams = 0; | 1030 | devinfo->use_streams = 0; |
951 | } else { | 1031 | } else { |
1032 | devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, | ||
1033 | 3, 256, GFP_KERNEL); | ||
1034 | if (devinfo->qdepth < 0) | ||
1035 | return devinfo->qdepth; | ||
952 | devinfo->use_streams = 1; | 1036 | devinfo->use_streams = 1; |
953 | } | 1037 | } |
1038 | |||
1039 | return 0; | ||
954 | } | 1040 | } |
955 | 1041 | ||
956 | static void uas_free_streams(struct uas_dev_info *devinfo) | 1042 | static void uas_free_streams(struct uas_dev_info *devinfo) |
@@ -964,30 +1050,23 @@ static void uas_free_streams(struct uas_dev_info *devinfo) | |||
964 | usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); | 1050 | usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); |
965 | } | 1051 | } |
966 | 1052 | ||
967 | /* | ||
968 | * XXX: What I'd like to do here is register a SCSI host for each USB host in | ||
969 | * the system. Follow usb-storage's design of registering a SCSI host for | ||
970 | * each USB device for the moment. Can implement this by walking up the | ||
971 | * USB hierarchy until we find a USB host. | ||
972 | */ | ||
973 | static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1053 | static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) |
974 | { | 1054 | { |
975 | int result; | 1055 | int result = -ENOMEM; |
976 | struct Scsi_Host *shost; | 1056 | struct Scsi_Host *shost = NULL; |
977 | struct uas_dev_info *devinfo; | 1057 | struct uas_dev_info *devinfo; |
978 | struct usb_device *udev = interface_to_usbdev(intf); | 1058 | struct usb_device *udev = interface_to_usbdev(intf); |
979 | 1059 | ||
980 | if (uas_switch_interface(udev, intf)) | 1060 | if (!uas_use_uas_driver(intf, id)) |
981 | return -ENODEV; | 1061 | return -ENODEV; |
982 | 1062 | ||
983 | devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL); | 1063 | if (uas_switch_interface(udev, intf)) |
984 | if (!devinfo) | 1064 | return -ENODEV; |
985 | return -ENOMEM; | ||
986 | 1065 | ||
987 | result = -ENOMEM; | 1066 | shost = scsi_host_alloc(&uas_host_template, |
988 | shost = scsi_host_alloc(&uas_host_template, sizeof(void *)); | 1067 | sizeof(struct uas_dev_info)); |
989 | if (!shost) | 1068 | if (!shost) |
990 | goto free; | 1069 | goto set_alt0; |
991 | 1070 | ||
992 | shost->max_cmd_len = 16 + 252; | 1071 | shost->max_cmd_len = 16 + 252; |
993 | shost->max_id = 1; | 1072 | shost->max_id = 1; |
@@ -995,33 +1074,40 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
995 | shost->max_channel = 0; | 1074 | shost->max_channel = 0; |
996 | shost->sg_tablesize = udev->bus->sg_tablesize; | 1075 | shost->sg_tablesize = udev->bus->sg_tablesize; |
997 | 1076 | ||
1077 | devinfo = (struct uas_dev_info *)shost->hostdata; | ||
998 | devinfo->intf = intf; | 1078 | devinfo->intf = intf; |
999 | devinfo->udev = udev; | 1079 | devinfo->udev = udev; |
1000 | devinfo->resetting = 0; | 1080 | devinfo->resetting = 0; |
1081 | devinfo->running_task = 0; | ||
1082 | devinfo->shutdown = 0; | ||
1001 | init_usb_anchor(&devinfo->cmd_urbs); | 1083 | init_usb_anchor(&devinfo->cmd_urbs); |
1002 | init_usb_anchor(&devinfo->sense_urbs); | 1084 | init_usb_anchor(&devinfo->sense_urbs); |
1003 | init_usb_anchor(&devinfo->data_urbs); | 1085 | init_usb_anchor(&devinfo->data_urbs); |
1004 | spin_lock_init(&devinfo->lock); | 1086 | spin_lock_init(&devinfo->lock); |
1005 | uas_configure_endpoints(devinfo); | 1087 | INIT_WORK(&devinfo->work, uas_do_work); |
1088 | INIT_LIST_HEAD(&devinfo->inflight_list); | ||
1089 | INIT_LIST_HEAD(&devinfo->dead_list); | ||
1006 | 1090 | ||
1007 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 3); | 1091 | result = uas_configure_endpoints(devinfo); |
1008 | if (result) | 1092 | if (result) |
1009 | goto free; | 1093 | goto set_alt0; |
1010 | 1094 | ||
1011 | result = scsi_add_host(shost, &intf->dev); | 1095 | result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); |
1012 | if (result) | 1096 | if (result) |
1013 | goto deconfig_eps; | 1097 | goto free_streams; |
1014 | 1098 | ||
1015 | shost->hostdata[0] = (unsigned long)devinfo; | 1099 | result = scsi_add_host(shost, &intf->dev); |
1100 | if (result) | ||
1101 | goto free_streams; | ||
1016 | 1102 | ||
1017 | scsi_scan_host(shost); | 1103 | scsi_scan_host(shost); |
1018 | usb_set_intfdata(intf, shost); | 1104 | usb_set_intfdata(intf, shost); |
1019 | return result; | 1105 | return result; |
1020 | 1106 | ||
1021 | deconfig_eps: | 1107 | free_streams: |
1022 | uas_free_streams(devinfo); | 1108 | uas_free_streams(devinfo); |
1023 | free: | 1109 | set_alt0: |
1024 | kfree(devinfo); | 1110 | usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0); |
1025 | if (shost) | 1111 | if (shost) |
1026 | scsi_host_put(shost); | 1112 | scsi_host_put(shost); |
1027 | return result; | 1113 | return result; |
@@ -1029,45 +1115,146 @@ deconfig_eps: | |||
1029 | 1115 | ||
1030 | static int uas_pre_reset(struct usb_interface *intf) | 1116 | static int uas_pre_reset(struct usb_interface *intf) |
1031 | { | 1117 | { |
1032 | /* XXX: Need to return 1 if it's not our device in error handling */ | 1118 | struct Scsi_Host *shost = usb_get_intfdata(intf); |
1119 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
1120 | unsigned long flags; | ||
1121 | |||
1122 | if (devinfo->shutdown) | ||
1123 | return 0; | ||
1124 | |||
1125 | /* Block new requests */ | ||
1126 | spin_lock_irqsave(shost->host_lock, flags); | ||
1127 | scsi_block_requests(shost); | ||
1128 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1129 | |||
1130 | /* Wait for any pending requests to complete */ | ||
1131 | flush_work(&devinfo->work); | ||
1132 | if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) { | ||
1133 | shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__); | ||
1134 | return 1; | ||
1135 | } | ||
1136 | |||
1137 | uas_free_streams(devinfo); | ||
1138 | |||
1033 | return 0; | 1139 | return 0; |
1034 | } | 1140 | } |
1035 | 1141 | ||
1036 | static int uas_post_reset(struct usb_interface *intf) | 1142 | static int uas_post_reset(struct usb_interface *intf) |
1037 | { | 1143 | { |
1038 | /* XXX: Need to return 1 if it's not our device in error handling */ | 1144 | struct Scsi_Host *shost = usb_get_intfdata(intf); |
1145 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
1146 | unsigned long flags; | ||
1147 | |||
1148 | if (devinfo->shutdown) | ||
1149 | return 0; | ||
1150 | |||
1151 | if (uas_configure_endpoints(devinfo) != 0) { | ||
1152 | shost_printk(KERN_ERR, shost, | ||
1153 | "%s: alloc streams error after reset", __func__); | ||
1154 | return 1; | ||
1155 | } | ||
1156 | |||
1157 | spin_lock_irqsave(shost->host_lock, flags); | ||
1158 | scsi_report_bus_reset(shost, 0); | ||
1159 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1160 | |||
1161 | scsi_unblock_requests(shost); | ||
1162 | |||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | static int uas_suspend(struct usb_interface *intf, pm_message_t message) | ||
1167 | { | ||
1168 | struct Scsi_Host *shost = usb_get_intfdata(intf); | ||
1169 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
1170 | |||
1171 | /* Wait for any pending requests to complete */ | ||
1172 | flush_work(&devinfo->work); | ||
1173 | if (usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000) == 0) { | ||
1174 | shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__); | ||
1175 | return -ETIME; | ||
1176 | } | ||
1177 | |||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1181 | static int uas_resume(struct usb_interface *intf) | ||
1182 | { | ||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int uas_reset_resume(struct usb_interface *intf) | ||
1187 | { | ||
1188 | struct Scsi_Host *shost = usb_get_intfdata(intf); | ||
1189 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
1190 | unsigned long flags; | ||
1191 | |||
1192 | if (uas_configure_endpoints(devinfo) != 0) { | ||
1193 | shost_printk(KERN_ERR, shost, | ||
1194 | "%s: alloc streams error after reset", __func__); | ||
1195 | return -EIO; | ||
1196 | } | ||
1197 | |||
1198 | spin_lock_irqsave(shost->host_lock, flags); | ||
1199 | scsi_report_bus_reset(shost, 0); | ||
1200 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1201 | |||
1039 | return 0; | 1202 | return 0; |
1040 | } | 1203 | } |
1041 | 1204 | ||
1042 | static void uas_disconnect(struct usb_interface *intf) | 1205 | static void uas_disconnect(struct usb_interface *intf) |
1043 | { | 1206 | { |
1044 | struct Scsi_Host *shost = usb_get_intfdata(intf); | 1207 | struct Scsi_Host *shost = usb_get_intfdata(intf); |
1045 | struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; | 1208 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; |
1046 | 1209 | ||
1047 | devinfo->resetting = 1; | 1210 | devinfo->resetting = 1; |
1048 | uas_abort_work(devinfo); | 1211 | cancel_work_sync(&devinfo->work); |
1212 | uas_abort_inflight(devinfo, DID_NO_CONNECT, __func__); | ||
1049 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); | 1213 | usb_kill_anchored_urbs(&devinfo->cmd_urbs); |
1050 | usb_kill_anchored_urbs(&devinfo->sense_urbs); | 1214 | usb_kill_anchored_urbs(&devinfo->sense_urbs); |
1051 | usb_kill_anchored_urbs(&devinfo->data_urbs); | 1215 | usb_kill_anchored_urbs(&devinfo->data_urbs); |
1216 | uas_zap_dead(devinfo); | ||
1052 | scsi_remove_host(shost); | 1217 | scsi_remove_host(shost); |
1053 | uas_free_streams(devinfo); | 1218 | uas_free_streams(devinfo); |
1054 | kfree(devinfo); | 1219 | scsi_host_put(shost); |
1055 | } | 1220 | } |
1056 | 1221 | ||
1057 | /* | 1222 | /* |
1058 | * XXX: Should this plug into libusual so we can auto-upgrade devices from | 1223 | * Put the device back in usb-storage mode on shutdown, as some BIOS-es |
1059 | * Bulk-Only to UAS? | 1224 | * hang on reboot when the device is still in uas mode. Note the reset is |
1225 | * necessary as some devices won't revert to usb-storage mode without it. | ||
1060 | */ | 1226 | */ |
1227 | static void uas_shutdown(struct device *dev) | ||
1228 | { | ||
1229 | struct usb_interface *intf = to_usb_interface(dev); | ||
1230 | struct usb_device *udev = interface_to_usbdev(intf); | ||
1231 | struct Scsi_Host *shost = usb_get_intfdata(intf); | ||
1232 | struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata; | ||
1233 | |||
1234 | if (system_state != SYSTEM_RESTART) | ||
1235 | return; | ||
1236 | |||
1237 | devinfo->shutdown = 1; | ||
1238 | uas_free_streams(devinfo); | ||
1239 | usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0); | ||
1240 | usb_reset_device(udev); | ||
1241 | } | ||
1242 | |||
1061 | static struct usb_driver uas_driver = { | 1243 | static struct usb_driver uas_driver = { |
1062 | .name = "uas", | 1244 | .name = "uas", |
1063 | .probe = uas_probe, | 1245 | .probe = uas_probe, |
1064 | .disconnect = uas_disconnect, | 1246 | .disconnect = uas_disconnect, |
1065 | .pre_reset = uas_pre_reset, | 1247 | .pre_reset = uas_pre_reset, |
1066 | .post_reset = uas_post_reset, | 1248 | .post_reset = uas_post_reset, |
1249 | .suspend = uas_suspend, | ||
1250 | .resume = uas_resume, | ||
1251 | .reset_resume = uas_reset_resume, | ||
1252 | .drvwrap.driver.shutdown = uas_shutdown, | ||
1067 | .id_table = uas_usb_ids, | 1253 | .id_table = uas_usb_ids, |
1068 | }; | 1254 | }; |
1069 | 1255 | ||
1070 | module_usb_driver(uas_driver); | 1256 | module_usb_driver(uas_driver); |
1071 | 1257 | ||
1072 | MODULE_LICENSE("GPL"); | 1258 | MODULE_LICENSE("GPL"); |
1073 | MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp"); | 1259 | MODULE_AUTHOR( |
1260 | "Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp"); | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index adbeb255616a..f4a82291894a 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -2086,6 +2086,11 @@ UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001, | |||
2086 | "Digital MP3 Audio Player", | 2086 | "Digital MP3 Audio Player", |
2087 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 2087 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
2088 | 2088 | ||
2089 | /* Unusual uas devices */ | ||
2090 | #if IS_ENABLED(CONFIG_USB_UAS) | ||
2091 | #include "unusual_uas.h" | ||
2092 | #endif | ||
2093 | |||
2089 | /* Control/Bulk transport for all SubClass values */ | 2094 | /* Control/Bulk transport for all SubClass values */ |
2090 | USUAL_DEV(USB_SC_RBC, USB_PR_CB), | 2095 | USUAL_DEV(USB_SC_RBC, USB_PR_CB), |
2091 | USUAL_DEV(USB_SC_8020, USB_PR_CB), | 2096 | USUAL_DEV(USB_SC_8020, USB_PR_CB), |
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h new file mode 100644 index 000000000000..7244444df8ee --- /dev/null +++ b/drivers/usb/storage/unusual_uas.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* Driver for USB Attached SCSI devices - Unusual Devices File | ||
2 | * | ||
3 | * (c) 2013 Hans de Goede <hdegoede@redhat.com> | ||
4 | * | ||
5 | * Based on the same file for the usb-storage driver, which is: | ||
6 | * (c) 2000-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) | ||
7 | * (c) 2000 Adam J. Richter (adam@yggdrasil.com), Yggdrasil Computing, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * IMPORTANT NOTE: This file must be included in another file which defines | ||
26 | * a UNUSUAL_DEV macro before this file is included. | ||
27 | */ | ||
28 | |||
29 | /* | ||
30 | * If you edit this file, please try to keep it sorted first by VendorID, | ||
31 | * then by ProductID. | ||
32 | * | ||
33 | * If you want to add an entry for this file, be sure to include the | ||
34 | * following information: | ||
35 | * - a patch that adds the entry for your device, including your | ||
36 | * email address right above the entry (plus maybe a brief | ||
37 | * explanation of the reason for the entry), | ||
38 | * - lsusb -v output for the device | ||
39 | * Send your submission to Hans de Goede <hdegoede@redhat.com> | ||
40 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> | ||
41 | */ | ||
42 | |||
43 | /* | ||
44 | * This is an example entry for the US_FL_IGNORE_UAS flag. Once we have an | ||
45 | * actual entry using US_FL_IGNORE_UAS this entry should be removed. | ||
46 | * | ||
47 | * UNUSUAL_DEV( 0xabcd, 0x1234, 0x0100, 0x0100, | ||
48 | * "Example", | ||
49 | * "Storage with broken UAS", | ||
50 | * USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
51 | * US_FL_IGNORE_UAS), | ||
52 | */ | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 1c0b89f2a138..f1c96261a501 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -72,6 +72,10 @@ | |||
72 | #include "sierra_ms.h" | 72 | #include "sierra_ms.h" |
73 | #include "option_ms.h" | 73 | #include "option_ms.h" |
74 | 74 | ||
75 | #if IS_ENABLED(CONFIG_USB_UAS) | ||
76 | #include "uas-detect.h" | ||
77 | #endif | ||
78 | |||
75 | /* Some informational data */ | 79 | /* Some informational data */ |
76 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 80 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
77 | MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); | 81 | MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); |
@@ -459,14 +463,14 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
459 | #define TOLOWER(x) ((x) | 0x20) | 463 | #define TOLOWER(x) ((x) | 0x20) |
460 | 464 | ||
461 | /* Adjust device flags based on the "quirks=" module parameter */ | 465 | /* Adjust device flags based on the "quirks=" module parameter */ |
462 | static void adjust_quirks(struct us_data *us) | 466 | void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) |
463 | { | 467 | { |
464 | char *p; | 468 | char *p; |
465 | u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor); | 469 | u16 vid = le16_to_cpu(udev->descriptor.idVendor); |
466 | u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct); | 470 | u16 pid = le16_to_cpu(udev->descriptor.idProduct); |
467 | unsigned f = 0; | 471 | unsigned f = 0; |
468 | unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE | | 472 | unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE | |
469 | US_FL_FIX_CAPACITY | | 473 | US_FL_FIX_CAPACITY | US_FL_IGNORE_UAS | |
470 | US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE | | 474 | US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE | |
471 | US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | | 475 | US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | |
472 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | | 476 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | |
@@ -537,14 +541,18 @@ static void adjust_quirks(struct us_data *us) | |||
537 | case 's': | 541 | case 's': |
538 | f |= US_FL_SINGLE_LUN; | 542 | f |= US_FL_SINGLE_LUN; |
539 | break; | 543 | break; |
544 | case 'u': | ||
545 | f |= US_FL_IGNORE_UAS; | ||
546 | break; | ||
540 | case 'w': | 547 | case 'w': |
541 | f |= US_FL_NO_WP_DETECT; | 548 | f |= US_FL_NO_WP_DETECT; |
542 | break; | 549 | break; |
543 | /* Ignore unrecognized flag characters */ | 550 | /* Ignore unrecognized flag characters */ |
544 | } | 551 | } |
545 | } | 552 | } |
546 | us->fflags = (us->fflags & ~mask) | f; | 553 | *fflags = (*fflags & ~mask) | f; |
547 | } | 554 | } |
555 | EXPORT_SYMBOL_GPL(usb_stor_adjust_quirks); | ||
548 | 556 | ||
549 | /* Get the unusual_devs entries and the string descriptors */ | 557 | /* Get the unusual_devs entries and the string descriptors */ |
550 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, | 558 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, |
@@ -564,7 +572,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id, | |||
564 | idesc->bInterfaceProtocol : | 572 | idesc->bInterfaceProtocol : |
565 | unusual_dev->useTransport; | 573 | unusual_dev->useTransport; |
566 | us->fflags = id->driver_info; | 574 | us->fflags = id->driver_info; |
567 | adjust_quirks(us); | 575 | usb_stor_adjust_quirks(us->pusb_dev, &us->fflags); |
568 | 576 | ||
569 | if (us->fflags & US_FL_IGNORE_DEVICE) { | 577 | if (us->fflags & US_FL_IGNORE_DEVICE) { |
570 | dev_info(pdev, "device ignored\n"); | 578 | dev_info(pdev, "device ignored\n"); |
@@ -1035,6 +1043,12 @@ static int storage_probe(struct usb_interface *intf, | |||
1035 | int result; | 1043 | int result; |
1036 | int size; | 1044 | int size; |
1037 | 1045 | ||
1046 | /* If uas is enabled and this device can do uas then ignore it. */ | ||
1047 | #if IS_ENABLED(CONFIG_USB_UAS) | ||
1048 | if (uas_use_uas_driver(intf, id)) | ||
1049 | return -ENXIO; | ||
1050 | #endif | ||
1051 | |||
1038 | /* | 1052 | /* |
1039 | * If the device isn't standard (is handled by a subdriver | 1053 | * If the device isn't standard (is handled by a subdriver |
1040 | * module) then don't accept it. | 1054 | * module) then don't accept it. |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 75f70f04f37b..307e339a9478 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -201,4 +201,7 @@ extern int usb_stor_probe1(struct us_data **pus, | |||
201 | extern int usb_stor_probe2(struct us_data *us); | 201 | extern int usb_stor_probe2(struct us_data *us); |
202 | extern void usb_stor_disconnect(struct usb_interface *intf); | 202 | extern void usb_stor_disconnect(struct usb_interface *intf); |
203 | 203 | ||
204 | extern void usb_stor_adjust_quirks(struct usb_device *dev, | ||
205 | unsigned long *fflags); | ||
206 | |||
204 | #endif | 207 | #endif |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 3b959e83b28e..0677139c6065 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -284,7 +284,7 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc, | |||
284 | struct device *dev = wusbhc->dev; | 284 | struct device *dev = wusbhc->dev; |
285 | struct wusb_dev *wusb_dev; | 285 | struct wusb_dev *wusb_dev; |
286 | struct wusb_port *port; | 286 | struct wusb_port *port; |
287 | unsigned idx, devnum; | 287 | unsigned idx; |
288 | 288 | ||
289 | mutex_lock(&wusbhc->mutex); | 289 | mutex_lock(&wusbhc->mutex); |
290 | 290 | ||
@@ -312,8 +312,6 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc, | |||
312 | goto error_unlock; | 312 | goto error_unlock; |
313 | } | 313 | } |
314 | 314 | ||
315 | devnum = idx + 2; | ||
316 | |||
317 | /* Make sure we are using no crypto on that "virtual port" */ | 315 | /* Make sure we are using no crypto on that "virtual port" */ |
318 | wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0); | 316 | wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0); |
319 | 317 | ||
diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c index 368360f9a93a..252c7bd9218a 100644 --- a/drivers/usb/wusbcore/wa-hc.c +++ b/drivers/usb/wusbcore/wa-hc.c | |||
@@ -75,8 +75,6 @@ void __wa_destroy(struct wahc *wa) | |||
75 | if (wa->dti_urb) { | 75 | if (wa->dti_urb) { |
76 | usb_kill_urb(wa->dti_urb); | 76 | usb_kill_urb(wa->dti_urb); |
77 | usb_put_urb(wa->dti_urb); | 77 | usb_put_urb(wa->dti_urb); |
78 | usb_kill_urb(wa->buf_in_urb); | ||
79 | usb_put_urb(wa->buf_in_urb); | ||
80 | } | 78 | } |
81 | kfree(wa->dti_buf); | 79 | kfree(wa->dti_buf); |
82 | wa_nep_destroy(wa); | 80 | wa_nep_destroy(wa); |
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h index a2ef84b8397e..f2a8d29e17b9 100644 --- a/drivers/usb/wusbcore/wa-hc.h +++ b/drivers/usb/wusbcore/wa-hc.h | |||
@@ -125,7 +125,8 @@ struct wa_rpipe { | |||
125 | 125 | ||
126 | enum wa_dti_state { | 126 | enum wa_dti_state { |
127 | WA_DTI_TRANSFER_RESULT_PENDING, | 127 | WA_DTI_TRANSFER_RESULT_PENDING, |
128 | WA_DTI_ISOC_PACKET_STATUS_PENDING | 128 | WA_DTI_ISOC_PACKET_STATUS_PENDING, |
129 | WA_DTI_BUF_IN_DATA_PENDING | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | enum wa_quirks { | 132 | enum wa_quirks { |
@@ -134,8 +135,20 @@ enum wa_quirks { | |||
134 | * requests to be concatenated and not sent as separate packets. | 135 | * requests to be concatenated and not sent as separate packets. |
135 | */ | 136 | */ |
136 | WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC = 0x01, | 137 | WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC = 0x01, |
138 | /* | ||
139 | * The Alereon HWA can be instructed to not send transfer notifications | ||
140 | * as an optimization. | ||
141 | */ | ||
142 | WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS = 0x02, | ||
137 | }; | 143 | }; |
138 | 144 | ||
145 | enum wa_vendor_specific_requests { | ||
146 | WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS = 0x4C, | ||
147 | WA_REQ_ALEREON_FEATURE_SET = 0x01, | ||
148 | WA_REQ_ALEREON_FEATURE_CLEAR = 0x00, | ||
149 | }; | ||
150 | |||
151 | #define WA_MAX_BUF_IN_URBS 4 | ||
139 | /** | 152 | /** |
140 | * Instance of a HWA Host Controller | 153 | * Instance of a HWA Host Controller |
141 | * | 154 | * |
@@ -206,7 +219,9 @@ struct wahc { | |||
206 | u32 dti_isoc_xfer_in_progress; | 219 | u32 dti_isoc_xfer_in_progress; |
207 | u8 dti_isoc_xfer_seg; | 220 | u8 dti_isoc_xfer_seg; |
208 | struct urb *dti_urb; /* URB for reading xfer results */ | 221 | struct urb *dti_urb; /* URB for reading xfer results */ |
209 | struct urb *buf_in_urb; /* URB for reading data in */ | 222 | /* URBs for reading data in */ |
223 | struct urb buf_in_urbs[WA_MAX_BUF_IN_URBS]; | ||
224 | int active_buf_in_urbs; /* number of buf_in_urbs active. */ | ||
210 | struct edc dti_edc; /* DTI error density counter */ | 225 | struct edc dti_edc; /* DTI error density counter */ |
211 | void *dti_buf; | 226 | void *dti_buf; |
212 | size_t dti_buf_size; | 227 | size_t dti_buf_size; |
@@ -234,6 +249,7 @@ struct wahc { | |||
234 | extern int wa_create(struct wahc *wa, struct usb_interface *iface, | 249 | extern int wa_create(struct wahc *wa, struct usb_interface *iface, |
235 | kernel_ulong_t); | 250 | kernel_ulong_t); |
236 | extern void __wa_destroy(struct wahc *wa); | 251 | extern void __wa_destroy(struct wahc *wa); |
252 | extern int wa_dti_start(struct wahc *wa); | ||
237 | void wa_reset_all(struct wahc *wa); | 253 | void wa_reset_all(struct wahc *wa); |
238 | 254 | ||
239 | 255 | ||
@@ -275,6 +291,8 @@ static inline void wa_rpipe_init(struct wahc *wa) | |||
275 | 291 | ||
276 | static inline void wa_init(struct wahc *wa) | 292 | static inline void wa_init(struct wahc *wa) |
277 | { | 293 | { |
294 | int index; | ||
295 | |||
278 | edc_init(&wa->nep_edc); | 296 | edc_init(&wa->nep_edc); |
279 | atomic_set(&wa->notifs_queued, 0); | 297 | atomic_set(&wa->notifs_queued, 0); |
280 | wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; | 298 | wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; |
@@ -288,6 +306,10 @@ static inline void wa_init(struct wahc *wa) | |||
288 | INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run); | 306 | INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run); |
289 | wa->dto_in_use = 0; | 307 | wa->dto_in_use = 0; |
290 | atomic_set(&wa->xfer_id_count, 1); | 308 | atomic_set(&wa->xfer_id_count, 1); |
309 | /* init the buf in URBs */ | ||
310 | for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index) | ||
311 | usb_init_urb(&(wa->buf_in_urbs[index])); | ||
312 | wa->active_buf_in_urbs = 0; | ||
291 | } | 313 | } |
292 | 314 | ||
293 | /** | 315 | /** |
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index 6ca80a4efc1b..6d6da127f6de 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c | |||
@@ -298,7 +298,7 @@ static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find( | |||
298 | break; | 298 | break; |
299 | } | 299 | } |
300 | itr += hdr->bLength; | 300 | itr += hdr->bLength; |
301 | itr_size -= hdr->bDescriptorType; | 301 | itr_size -= hdr->bLength; |
302 | } | 302 | } |
303 | out: | 303 | out: |
304 | return epcd; | 304 | return epcd; |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 3cd96e936d77..c8e2a47d62a7 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -167,6 +167,8 @@ struct wa_xfer { | |||
167 | 167 | ||
168 | static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer, | 168 | static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer, |
169 | struct wa_seg *seg, int curr_iso_frame); | 169 | struct wa_seg *seg, int curr_iso_frame); |
170 | static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | ||
171 | int starting_index, enum wa_seg_status status); | ||
170 | 172 | ||
171 | static inline void wa_xfer_init(struct wa_xfer *xfer) | 173 | static inline void wa_xfer_init(struct wa_xfer *xfer) |
172 | { | 174 | { |
@@ -367,13 +369,13 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) | |||
367 | break; | 369 | break; |
368 | case WA_SEG_ERROR: | 370 | case WA_SEG_ERROR: |
369 | xfer->result = seg->result; | 371 | xfer->result = seg->result; |
370 | dev_dbg(dev, "xfer %p ID %08X#%u: ERROR result %zu(0x%08zX)\n", | 372 | dev_dbg(dev, "xfer %p ID %08X#%u: ERROR result %zi(0x%08zX)\n", |
371 | xfer, wa_xfer_id(xfer), seg->index, seg->result, | 373 | xfer, wa_xfer_id(xfer), seg->index, seg->result, |
372 | seg->result); | 374 | seg->result); |
373 | goto out; | 375 | goto out; |
374 | case WA_SEG_ABORTED: | 376 | case WA_SEG_ABORTED: |
375 | xfer->result = seg->result; | 377 | xfer->result = seg->result; |
376 | dev_dbg(dev, "xfer %p ID %08X#%u: ABORTED result %zu(0x%08zX)\n", | 378 | dev_dbg(dev, "xfer %p ID %08X#%u: ABORTED result %zi(0x%08zX)\n", |
377 | xfer, wa_xfer_id(xfer), seg->index, seg->result, | 379 | xfer, wa_xfer_id(xfer), seg->index, seg->result, |
378 | seg->result); | 380 | seg->result); |
379 | goto out; | 381 | goto out; |
@@ -390,6 +392,24 @@ out: | |||
390 | } | 392 | } |
391 | 393 | ||
392 | /* | 394 | /* |
395 | * Mark the given segment as done. Return true if this completes the xfer. | ||
396 | * This should only be called for segs that have been submitted to an RPIPE. | ||
397 | * Delayed segs are not marked as submitted so they do not need to be marked | ||
398 | * as done when cleaning up. | ||
399 | * | ||
400 | * xfer->lock has to be locked | ||
401 | */ | ||
402 | static unsigned __wa_xfer_mark_seg_as_done(struct wa_xfer *xfer, | ||
403 | struct wa_seg *seg, enum wa_seg_status status) | ||
404 | { | ||
405 | seg->status = status; | ||
406 | xfer->segs_done++; | ||
407 | |||
408 | /* check for done. */ | ||
409 | return __wa_xfer_is_done(xfer); | ||
410 | } | ||
411 | |||
412 | /* | ||
393 | * Search for a transfer list ID on the HCD's URB list | 413 | * Search for a transfer list ID on the HCD's URB list |
394 | * | 414 | * |
395 | * For 32 bit architectures, we use the pointer itself; for 64 bits, a | 415 | * For 32 bit architectures, we use the pointer itself; for 64 bits, a |
@@ -416,12 +436,51 @@ out: | |||
416 | 436 | ||
417 | struct wa_xfer_abort_buffer { | 437 | struct wa_xfer_abort_buffer { |
418 | struct urb urb; | 438 | struct urb urb; |
439 | struct wahc *wa; | ||
419 | struct wa_xfer_abort cmd; | 440 | struct wa_xfer_abort cmd; |
420 | }; | 441 | }; |
421 | 442 | ||
422 | static void __wa_xfer_abort_cb(struct urb *urb) | 443 | static void __wa_xfer_abort_cb(struct urb *urb) |
423 | { | 444 | { |
424 | struct wa_xfer_abort_buffer *b = urb->context; | 445 | struct wa_xfer_abort_buffer *b = urb->context; |
446 | struct wahc *wa = b->wa; | ||
447 | |||
448 | /* | ||
449 | * If the abort request URB failed, then the HWA did not get the abort | ||
450 | * command. Forcibly clean up the xfer without waiting for a Transfer | ||
451 | * Result from the HWA. | ||
452 | */ | ||
453 | if (urb->status < 0) { | ||
454 | struct wa_xfer *xfer; | ||
455 | struct device *dev = &wa->usb_iface->dev; | ||
456 | |||
457 | xfer = wa_xfer_get_by_id(wa, le32_to_cpu(b->cmd.dwTransferID)); | ||
458 | dev_err(dev, "%s: Transfer Abort request failed. result: %d\n", | ||
459 | __func__, urb->status); | ||
460 | if (xfer) { | ||
461 | unsigned long flags; | ||
462 | int done; | ||
463 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; | ||
464 | |||
465 | dev_err(dev, "%s: cleaning up xfer %p ID 0x%08X.\n", | ||
466 | __func__, xfer, wa_xfer_id(xfer)); | ||
467 | spin_lock_irqsave(&xfer->lock, flags); | ||
468 | /* mark all segs as aborted. */ | ||
469 | wa_complete_remaining_xfer_segs(xfer, 0, | ||
470 | WA_SEG_ABORTED); | ||
471 | done = __wa_xfer_is_done(xfer); | ||
472 | spin_unlock_irqrestore(&xfer->lock, flags); | ||
473 | if (done) | ||
474 | wa_xfer_completion(xfer); | ||
475 | wa_xfer_delayed_run(rpipe); | ||
476 | wa_xfer_put(xfer); | ||
477 | } else { | ||
478 | dev_err(dev, "%s: xfer ID 0x%08X already gone.\n", | ||
479 | __func__, le32_to_cpu(b->cmd.dwTransferID)); | ||
480 | } | ||
481 | } | ||
482 | |||
483 | wa_put(wa); /* taken in __wa_xfer_abort */ | ||
425 | usb_put_urb(&b->urb); | 484 | usb_put_urb(&b->urb); |
426 | } | 485 | } |
427 | 486 | ||
@@ -449,6 +508,7 @@ static int __wa_xfer_abort(struct wa_xfer *xfer) | |||
449 | b->cmd.bRequestType = WA_XFER_ABORT; | 508 | b->cmd.bRequestType = WA_XFER_ABORT; |
450 | b->cmd.wRPipe = rpipe->descr.wRPipeIndex; | 509 | b->cmd.wRPipe = rpipe->descr.wRPipeIndex; |
451 | b->cmd.dwTransferID = wa_xfer_id_le32(xfer); | 510 | b->cmd.dwTransferID = wa_xfer_id_le32(xfer); |
511 | b->wa = wa_get(xfer->wa); | ||
452 | 512 | ||
453 | usb_init_urb(&b->urb); | 513 | usb_init_urb(&b->urb); |
454 | usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev, | 514 | usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev, |
@@ -462,6 +522,7 @@ static int __wa_xfer_abort(struct wa_xfer *xfer) | |||
462 | 522 | ||
463 | 523 | ||
464 | error_submit: | 524 | error_submit: |
525 | wa_put(xfer->wa); | ||
465 | if (printk_ratelimit()) | 526 | if (printk_ratelimit()) |
466 | dev_err(dev, "xfer %p: Can't submit abort request: %d\n", | 527 | dev_err(dev, "xfer %p: Can't submit abort request: %d\n", |
467 | xfer, result); | 528 | xfer, result); |
@@ -733,6 +794,8 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
733 | seg->isoc_frame_offset + seg->isoc_frame_index); | 794 | seg->isoc_frame_offset + seg->isoc_frame_index); |
734 | 795 | ||
735 | /* resubmit the URB with the next isoc frame. */ | 796 | /* resubmit the URB with the next isoc frame. */ |
797 | /* take a ref on resubmit. */ | ||
798 | wa_xfer_get(xfer); | ||
736 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); | 799 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); |
737 | if (result < 0) { | 800 | if (result < 0) { |
738 | dev_err(dev, "xfer 0x%08X#%u: DTO submit failed: %d\n", | 801 | dev_err(dev, "xfer 0x%08X#%u: DTO submit failed: %d\n", |
@@ -760,9 +823,13 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
760 | goto error_default; | 823 | goto error_default; |
761 | } | 824 | } |
762 | 825 | ||
826 | /* taken when this URB was submitted. */ | ||
827 | wa_xfer_put(xfer); | ||
763 | return; | 828 | return; |
764 | 829 | ||
765 | error_dto_submit: | 830 | error_dto_submit: |
831 | /* taken on resubmit attempt. */ | ||
832 | wa_xfer_put(xfer); | ||
766 | error_default: | 833 | error_default: |
767 | spin_lock_irqsave(&xfer->lock, flags); | 834 | spin_lock_irqsave(&xfer->lock, flags); |
768 | rpipe = xfer->ep->hcpriv; | 835 | rpipe = xfer->ep->hcpriv; |
@@ -772,12 +839,10 @@ error_default: | |||
772 | wa_reset_all(wa); | 839 | wa_reset_all(wa); |
773 | } | 840 | } |
774 | if (seg->status != WA_SEG_ERROR) { | 841 | if (seg->status != WA_SEG_ERROR) { |
775 | seg->status = WA_SEG_ERROR; | ||
776 | seg->result = urb->status; | 842 | seg->result = urb->status; |
777 | xfer->segs_done++; | ||
778 | __wa_xfer_abort(xfer); | 843 | __wa_xfer_abort(xfer); |
779 | rpipe_ready = rpipe_avail_inc(rpipe); | 844 | rpipe_ready = rpipe_avail_inc(rpipe); |
780 | done = __wa_xfer_is_done(xfer); | 845 | done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR); |
781 | } | 846 | } |
782 | spin_unlock_irqrestore(&xfer->lock, flags); | 847 | spin_unlock_irqrestore(&xfer->lock, flags); |
783 | if (holding_dto) { | 848 | if (holding_dto) { |
@@ -788,7 +853,8 @@ error_default: | |||
788 | wa_xfer_completion(xfer); | 853 | wa_xfer_completion(xfer); |
789 | if (rpipe_ready) | 854 | if (rpipe_ready) |
790 | wa_xfer_delayed_run(rpipe); | 855 | wa_xfer_delayed_run(rpipe); |
791 | 856 | /* taken when this URB was submitted. */ | |
857 | wa_xfer_put(xfer); | ||
792 | } | 858 | } |
793 | 859 | ||
794 | /* | 860 | /* |
@@ -842,12 +908,11 @@ static void wa_seg_iso_pack_desc_cb(struct urb *urb) | |||
842 | } | 908 | } |
843 | if (seg->status != WA_SEG_ERROR) { | 909 | if (seg->status != WA_SEG_ERROR) { |
844 | usb_unlink_urb(seg->dto_urb); | 910 | usb_unlink_urb(seg->dto_urb); |
845 | seg->status = WA_SEG_ERROR; | ||
846 | seg->result = urb->status; | 911 | seg->result = urb->status; |
847 | xfer->segs_done++; | ||
848 | __wa_xfer_abort(xfer); | 912 | __wa_xfer_abort(xfer); |
849 | rpipe_ready = rpipe_avail_inc(rpipe); | 913 | rpipe_ready = rpipe_avail_inc(rpipe); |
850 | done = __wa_xfer_is_done(xfer); | 914 | done = __wa_xfer_mark_seg_as_done(xfer, seg, |
915 | WA_SEG_ERROR); | ||
851 | } | 916 | } |
852 | spin_unlock_irqrestore(&xfer->lock, flags); | 917 | spin_unlock_irqrestore(&xfer->lock, flags); |
853 | if (done) | 918 | if (done) |
@@ -855,6 +920,8 @@ static void wa_seg_iso_pack_desc_cb(struct urb *urb) | |||
855 | if (rpipe_ready) | 920 | if (rpipe_ready) |
856 | wa_xfer_delayed_run(rpipe); | 921 | wa_xfer_delayed_run(rpipe); |
857 | } | 922 | } |
923 | /* taken when this URB was submitted. */ | ||
924 | wa_xfer_put(xfer); | ||
858 | } | 925 | } |
859 | 926 | ||
860 | /* | 927 | /* |
@@ -919,18 +986,18 @@ static void wa_seg_tr_cb(struct urb *urb) | |||
919 | } | 986 | } |
920 | usb_unlink_urb(seg->isoc_pack_desc_urb); | 987 | usb_unlink_urb(seg->isoc_pack_desc_urb); |
921 | usb_unlink_urb(seg->dto_urb); | 988 | usb_unlink_urb(seg->dto_urb); |
922 | seg->status = WA_SEG_ERROR; | ||
923 | seg->result = urb->status; | 989 | seg->result = urb->status; |
924 | xfer->segs_done++; | ||
925 | __wa_xfer_abort(xfer); | 990 | __wa_xfer_abort(xfer); |
926 | rpipe_ready = rpipe_avail_inc(rpipe); | 991 | rpipe_ready = rpipe_avail_inc(rpipe); |
927 | done = __wa_xfer_is_done(xfer); | 992 | done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR); |
928 | spin_unlock_irqrestore(&xfer->lock, flags); | 993 | spin_unlock_irqrestore(&xfer->lock, flags); |
929 | if (done) | 994 | if (done) |
930 | wa_xfer_completion(xfer); | 995 | wa_xfer_completion(xfer); |
931 | if (rpipe_ready) | 996 | if (rpipe_ready) |
932 | wa_xfer_delayed_run(rpipe); | 997 | wa_xfer_delayed_run(rpipe); |
933 | } | 998 | } |
999 | /* taken when this URB was submitted. */ | ||
1000 | wa_xfer_put(xfer); | ||
934 | } | 1001 | } |
935 | 1002 | ||
936 | /* | 1003 | /* |
@@ -940,7 +1007,7 @@ static void wa_seg_tr_cb(struct urb *urb) | |||
940 | */ | 1007 | */ |
941 | static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg, | 1008 | static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg, |
942 | const unsigned int bytes_transferred, | 1009 | const unsigned int bytes_transferred, |
943 | const unsigned int bytes_to_transfer, unsigned int *out_num_sgs) | 1010 | const unsigned int bytes_to_transfer, int *out_num_sgs) |
944 | { | 1011 | { |
945 | struct scatterlist *out_sg; | 1012 | struct scatterlist *out_sg; |
946 | unsigned int bytes_processed = 0, offset_into_current_page_data = 0, | 1013 | unsigned int bytes_processed = 0, offset_into_current_page_data = 0, |
@@ -1094,14 +1161,13 @@ static int __wa_populate_dto_urb(struct wa_xfer *xfer, | |||
1094 | */ | 1161 | */ |
1095 | static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size) | 1162 | static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size) |
1096 | { | 1163 | { |
1097 | int result, cnt, iso_frame_offset; | 1164 | int result, cnt, isoc_frame_offset = 0; |
1098 | size_t alloc_size = sizeof(*xfer->seg[0]) | 1165 | size_t alloc_size = sizeof(*xfer->seg[0]) |
1099 | - sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size; | 1166 | - sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size; |
1100 | struct usb_device *usb_dev = xfer->wa->usb_dev; | 1167 | struct usb_device *usb_dev = xfer->wa->usb_dev; |
1101 | const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd; | 1168 | const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd; |
1102 | struct wa_seg *seg; | 1169 | struct wa_seg *seg; |
1103 | size_t buf_itr, buf_size, buf_itr_size; | 1170 | size_t buf_itr, buf_size, buf_itr_size; |
1104 | int isoc_frame_offset = 0; | ||
1105 | 1171 | ||
1106 | result = -ENOMEM; | 1172 | result = -ENOMEM; |
1107 | xfer->seg = kcalloc(xfer->segs, sizeof(xfer->seg[0]), GFP_ATOMIC); | 1173 | xfer->seg = kcalloc(xfer->segs, sizeof(xfer->seg[0]), GFP_ATOMIC); |
@@ -1109,7 +1175,6 @@ static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size) | |||
1109 | goto error_segs_kzalloc; | 1175 | goto error_segs_kzalloc; |
1110 | buf_itr = 0; | 1176 | buf_itr = 0; |
1111 | buf_size = xfer->urb->transfer_buffer_length; | 1177 | buf_size = xfer->urb->transfer_buffer_length; |
1112 | iso_frame_offset = 0; | ||
1113 | for (cnt = 0; cnt < xfer->segs; cnt++) { | 1178 | for (cnt = 0; cnt < xfer->segs; cnt++) { |
1114 | size_t iso_pkt_descr_size = 0; | 1179 | size_t iso_pkt_descr_size = 0; |
1115 | int seg_isoc_frame_count = 0, seg_isoc_size = 0; | 1180 | int seg_isoc_frame_count = 0, seg_isoc_size = 0; |
@@ -1318,30 +1383,41 @@ static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer, | |||
1318 | /* default to done unless we encounter a multi-frame isoc segment. */ | 1383 | /* default to done unless we encounter a multi-frame isoc segment. */ |
1319 | *dto_done = 1; | 1384 | *dto_done = 1; |
1320 | 1385 | ||
1386 | /* | ||
1387 | * Take a ref for each segment urb so the xfer cannot disappear until | ||
1388 | * all of the callbacks run. | ||
1389 | */ | ||
1390 | wa_xfer_get(xfer); | ||
1321 | /* submit the transfer request. */ | 1391 | /* submit the transfer request. */ |
1392 | seg->status = WA_SEG_SUBMITTED; | ||
1322 | result = usb_submit_urb(&seg->tr_urb, GFP_ATOMIC); | 1393 | result = usb_submit_urb(&seg->tr_urb, GFP_ATOMIC); |
1323 | if (result < 0) { | 1394 | if (result < 0) { |
1324 | pr_err("%s: xfer %p#%u: REQ submit failed: %d\n", | 1395 | pr_err("%s: xfer %p#%u: REQ submit failed: %d\n", |
1325 | __func__, xfer, seg->index, result); | 1396 | __func__, xfer, seg->index, result); |
1326 | goto error_seg_submit; | 1397 | wa_xfer_put(xfer); |
1398 | goto error_tr_submit; | ||
1327 | } | 1399 | } |
1328 | /* submit the isoc packet descriptor if present. */ | 1400 | /* submit the isoc packet descriptor if present. */ |
1329 | if (seg->isoc_pack_desc_urb) { | 1401 | if (seg->isoc_pack_desc_urb) { |
1402 | wa_xfer_get(xfer); | ||
1330 | result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC); | 1403 | result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC); |
1331 | seg->isoc_frame_index = 0; | 1404 | seg->isoc_frame_index = 0; |
1332 | if (result < 0) { | 1405 | if (result < 0) { |
1333 | pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n", | 1406 | pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n", |
1334 | __func__, xfer, seg->index, result); | 1407 | __func__, xfer, seg->index, result); |
1408 | wa_xfer_put(xfer); | ||
1335 | goto error_iso_pack_desc_submit; | 1409 | goto error_iso_pack_desc_submit; |
1336 | } | 1410 | } |
1337 | } | 1411 | } |
1338 | /* submit the out data if this is an out request. */ | 1412 | /* submit the out data if this is an out request. */ |
1339 | if (seg->dto_urb) { | 1413 | if (seg->dto_urb) { |
1340 | struct wahc *wa = xfer->wa; | 1414 | struct wahc *wa = xfer->wa; |
1415 | wa_xfer_get(xfer); | ||
1341 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); | 1416 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); |
1342 | if (result < 0) { | 1417 | if (result < 0) { |
1343 | pr_err("%s: xfer %p#%u: DTO submit failed: %d\n", | 1418 | pr_err("%s: xfer %p#%u: DTO submit failed: %d\n", |
1344 | __func__, xfer, seg->index, result); | 1419 | __func__, xfer, seg->index, result); |
1420 | wa_xfer_put(xfer); | ||
1345 | goto error_dto_submit; | 1421 | goto error_dto_submit; |
1346 | } | 1422 | } |
1347 | /* | 1423 | /* |
@@ -1353,7 +1429,6 @@ static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer, | |||
1353 | && (seg->isoc_frame_count > 1)) | 1429 | && (seg->isoc_frame_count > 1)) |
1354 | *dto_done = 0; | 1430 | *dto_done = 0; |
1355 | } | 1431 | } |
1356 | seg->status = WA_SEG_SUBMITTED; | ||
1357 | rpipe_avail_dec(rpipe); | 1432 | rpipe_avail_dec(rpipe); |
1358 | return 0; | 1433 | return 0; |
1359 | 1434 | ||
@@ -1361,7 +1436,7 @@ error_dto_submit: | |||
1361 | usb_unlink_urb(seg->isoc_pack_desc_urb); | 1436 | usb_unlink_urb(seg->isoc_pack_desc_urb); |
1362 | error_iso_pack_desc_submit: | 1437 | error_iso_pack_desc_submit: |
1363 | usb_unlink_urb(&seg->tr_urb); | 1438 | usb_unlink_urb(&seg->tr_urb); |
1364 | error_seg_submit: | 1439 | error_tr_submit: |
1365 | seg->status = WA_SEG_ERROR; | 1440 | seg->status = WA_SEG_ERROR; |
1366 | seg->result = result; | 1441 | seg->result = result; |
1367 | *dto_done = 1; | 1442 | *dto_done = 1; |
@@ -1393,6 +1468,12 @@ static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting) | |||
1393 | list_node); | 1468 | list_node); |
1394 | list_del(&seg->list_node); | 1469 | list_del(&seg->list_node); |
1395 | xfer = seg->xfer; | 1470 | xfer = seg->xfer; |
1471 | /* | ||
1472 | * Get a reference to the xfer in case the callbacks for the | ||
1473 | * URBs submitted by __wa_seg_submit attempt to complete | ||
1474 | * the xfer before this function completes. | ||
1475 | */ | ||
1476 | wa_xfer_get(xfer); | ||
1396 | result = __wa_seg_submit(rpipe, xfer, seg, &dto_done); | 1477 | result = __wa_seg_submit(rpipe, xfer, seg, &dto_done); |
1397 | /* release the dto resource if this RPIPE is done with it. */ | 1478 | /* release the dto resource if this RPIPE is done with it. */ |
1398 | if (dto_done) | 1479 | if (dto_done) |
@@ -1401,13 +1482,23 @@ static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting) | |||
1401 | xfer, wa_xfer_id(xfer), seg->index, | 1482 | xfer, wa_xfer_id(xfer), seg->index, |
1402 | atomic_read(&rpipe->segs_available), result); | 1483 | atomic_read(&rpipe->segs_available), result); |
1403 | if (unlikely(result < 0)) { | 1484 | if (unlikely(result < 0)) { |
1485 | int done; | ||
1486 | |||
1404 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); | 1487 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); |
1405 | spin_lock_irqsave(&xfer->lock, flags); | 1488 | spin_lock_irqsave(&xfer->lock, flags); |
1406 | __wa_xfer_abort(xfer); | 1489 | __wa_xfer_abort(xfer); |
1490 | /* | ||
1491 | * This seg was marked as submitted when it was put on | ||
1492 | * the RPIPE seg_list. Mark it done. | ||
1493 | */ | ||
1407 | xfer->segs_done++; | 1494 | xfer->segs_done++; |
1495 | done = __wa_xfer_is_done(xfer); | ||
1408 | spin_unlock_irqrestore(&xfer->lock, flags); | 1496 | spin_unlock_irqrestore(&xfer->lock, flags); |
1497 | if (done) | ||
1498 | wa_xfer_completion(xfer); | ||
1409 | spin_lock_irqsave(&rpipe->seg_lock, flags); | 1499 | spin_lock_irqsave(&rpipe->seg_lock, flags); |
1410 | } | 1500 | } |
1501 | wa_xfer_put(xfer); | ||
1411 | } | 1502 | } |
1412 | /* | 1503 | /* |
1413 | * Mark this RPIPE as waiting if dto was not acquired, there are | 1504 | * Mark this RPIPE as waiting if dto was not acquired, there are |
@@ -1592,12 +1683,19 @@ static int wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
1592 | dev_err(&(urb->dev->dev), "%s: error_xfer_setup\n", __func__); | 1683 | dev_err(&(urb->dev->dev), "%s: error_xfer_setup\n", __func__); |
1593 | goto error_xfer_setup; | 1684 | goto error_xfer_setup; |
1594 | } | 1685 | } |
1686 | /* | ||
1687 | * Get a xfer reference since __wa_xfer_submit starts asynchronous | ||
1688 | * operations that may try to complete the xfer before this function | ||
1689 | * exits. | ||
1690 | */ | ||
1691 | wa_xfer_get(xfer); | ||
1595 | result = __wa_xfer_submit(xfer); | 1692 | result = __wa_xfer_submit(xfer); |
1596 | if (result < 0) { | 1693 | if (result < 0) { |
1597 | dev_err(&(urb->dev->dev), "%s: error_xfer_submit\n", __func__); | 1694 | dev_err(&(urb->dev->dev), "%s: error_xfer_submit\n", __func__); |
1598 | goto error_xfer_submit; | 1695 | goto error_xfer_submit; |
1599 | } | 1696 | } |
1600 | spin_unlock_irqrestore(&xfer->lock, flags); | 1697 | spin_unlock_irqrestore(&xfer->lock, flags); |
1698 | wa_xfer_put(xfer); | ||
1601 | return 0; | 1699 | return 0; |
1602 | 1700 | ||
1603 | /* | 1701 | /* |
@@ -1623,6 +1721,7 @@ error_xfer_submit: | |||
1623 | spin_unlock_irqrestore(&xfer->lock, flags); | 1721 | spin_unlock_irqrestore(&xfer->lock, flags); |
1624 | if (done) | 1722 | if (done) |
1625 | wa_xfer_completion(xfer); | 1723 | wa_xfer_completion(xfer); |
1724 | wa_xfer_put(xfer); | ||
1626 | /* return success since the completion routine will run. */ | 1725 | /* return success since the completion routine will run. */ |
1627 | return 0; | 1726 | return 0; |
1628 | } | 1727 | } |
@@ -1832,20 +1931,20 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1832 | /* check if it is safe to unlink. */ | 1931 | /* check if it is safe to unlink. */ |
1833 | spin_lock_irqsave(&wa->xfer_list_lock, flags); | 1932 | spin_lock_irqsave(&wa->xfer_list_lock, flags); |
1834 | result = usb_hcd_check_unlink_urb(&(wa->wusb->usb_hcd), urb, status); | 1933 | result = usb_hcd_check_unlink_urb(&(wa->wusb->usb_hcd), urb, status); |
1934 | if ((result == 0) && urb->hcpriv) { | ||
1935 | /* | ||
1936 | * Get a xfer ref to prevent a race with wa_xfer_giveback | ||
1937 | * cleaning up the xfer while we are working with it. | ||
1938 | */ | ||
1939 | wa_xfer_get(urb->hcpriv); | ||
1940 | } | ||
1835 | spin_unlock_irqrestore(&wa->xfer_list_lock, flags); | 1941 | spin_unlock_irqrestore(&wa->xfer_list_lock, flags); |
1836 | if (result) | 1942 | if (result) |
1837 | return result; | 1943 | return result; |
1838 | 1944 | ||
1839 | xfer = urb->hcpriv; | 1945 | xfer = urb->hcpriv; |
1840 | if (xfer == NULL) { | 1946 | if (xfer == NULL) |
1841 | /* | 1947 | return -ENOENT; |
1842 | * Nothing setup yet enqueue will see urb->status != | ||
1843 | * -EINPROGRESS (by hcd layer) and bail out with | ||
1844 | * error, no need to do completion | ||
1845 | */ | ||
1846 | BUG_ON(urb->status == -EINPROGRESS); | ||
1847 | goto out; | ||
1848 | } | ||
1849 | spin_lock_irqsave(&xfer->lock, flags); | 1948 | spin_lock_irqsave(&xfer->lock, flags); |
1850 | pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer)); | 1949 | pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer)); |
1851 | rpipe = xfer->ep->hcpriv; | 1950 | rpipe = xfer->ep->hcpriv; |
@@ -1856,6 +1955,16 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1856 | result = -ENOENT; | 1955 | result = -ENOENT; |
1857 | goto out_unlock; | 1956 | goto out_unlock; |
1858 | } | 1957 | } |
1958 | /* | ||
1959 | * Check for done to avoid racing with wa_xfer_giveback and completing | ||
1960 | * twice. | ||
1961 | */ | ||
1962 | if (__wa_xfer_is_done(xfer)) { | ||
1963 | pr_debug("%s: xfer %p id 0x%08X already done.\n", __func__, | ||
1964 | xfer, wa_xfer_id(xfer)); | ||
1965 | result = -ENOENT; | ||
1966 | goto out_unlock; | ||
1967 | } | ||
1859 | /* Check the delayed list -> if there, release and complete */ | 1968 | /* Check the delayed list -> if there, release and complete */ |
1860 | spin_lock_irqsave(&wa->xfer_list_lock, flags2); | 1969 | spin_lock_irqsave(&wa->xfer_list_lock, flags2); |
1861 | if (!list_empty(&xfer->list_node) && xfer->seg == NULL) | 1970 | if (!list_empty(&xfer->list_node) && xfer->seg == NULL) |
@@ -1865,6 +1974,11 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1865 | goto out_unlock; /* setup(), enqueue_b() completes */ | 1974 | goto out_unlock; /* setup(), enqueue_b() completes */ |
1866 | /* Ok, the xfer is in flight already, it's been setup and submitted.*/ | 1975 | /* Ok, the xfer is in flight already, it's been setup and submitted.*/ |
1867 | xfer_abort_pending = __wa_xfer_abort(xfer) >= 0; | 1976 | xfer_abort_pending = __wa_xfer_abort(xfer) >= 0; |
1977 | /* | ||
1978 | * grab the rpipe->seg_lock here to prevent racing with | ||
1979 | * __wa_xfer_delayed_run. | ||
1980 | */ | ||
1981 | spin_lock(&rpipe->seg_lock); | ||
1868 | for (cnt = 0; cnt < xfer->segs; cnt++) { | 1982 | for (cnt = 0; cnt < xfer->segs; cnt++) { |
1869 | seg = xfer->seg[cnt]; | 1983 | seg = xfer->seg[cnt]; |
1870 | pr_debug("%s: xfer id 0x%08X#%d status = %d\n", | 1984 | pr_debug("%s: xfer id 0x%08X#%d status = %d\n", |
@@ -1885,16 +1999,24 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1885 | */ | 1999 | */ |
1886 | seg->status = WA_SEG_ABORTED; | 2000 | seg->status = WA_SEG_ABORTED; |
1887 | seg->result = -ENOENT; | 2001 | seg->result = -ENOENT; |
1888 | spin_lock_irqsave(&rpipe->seg_lock, flags2); | ||
1889 | list_del(&seg->list_node); | 2002 | list_del(&seg->list_node); |
1890 | xfer->segs_done++; | 2003 | xfer->segs_done++; |
1891 | spin_unlock_irqrestore(&rpipe->seg_lock, flags2); | ||
1892 | break; | 2004 | break; |
1893 | case WA_SEG_DONE: | 2005 | case WA_SEG_DONE: |
1894 | case WA_SEG_ERROR: | 2006 | case WA_SEG_ERROR: |
1895 | case WA_SEG_ABORTED: | 2007 | case WA_SEG_ABORTED: |
1896 | break; | 2008 | break; |
1897 | /* | 2009 | /* |
2010 | * The buf_in data for a segment in the | ||
2011 | * WA_SEG_DTI_PENDING state is actively being read. | ||
2012 | * Let wa_buf_in_cb handle it since it will be called | ||
2013 | * and will increment xfer->segs_done. Cleaning up | ||
2014 | * here could cause wa_buf_in_cb to access the xfer | ||
2015 | * after it has been completed/freed. | ||
2016 | */ | ||
2017 | case WA_SEG_DTI_PENDING: | ||
2018 | break; | ||
2019 | /* | ||
1898 | * In the states below, the HWA device already knows | 2020 | * In the states below, the HWA device already knows |
1899 | * about the transfer. If an abort request was sent, | 2021 | * about the transfer. If an abort request was sent, |
1900 | * allow the HWA to process it and wait for the | 2022 | * allow the HWA to process it and wait for the |
@@ -1903,7 +2025,6 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1903 | */ | 2025 | */ |
1904 | case WA_SEG_SUBMITTED: | 2026 | case WA_SEG_SUBMITTED: |
1905 | case WA_SEG_PENDING: | 2027 | case WA_SEG_PENDING: |
1906 | case WA_SEG_DTI_PENDING: | ||
1907 | /* | 2028 | /* |
1908 | * Check if the abort was successfully sent. This could | 2029 | * Check if the abort was successfully sent. This could |
1909 | * be false if the HWA has been removed but we haven't | 2030 | * be false if the HWA has been removed but we haven't |
@@ -1917,6 +2038,7 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1917 | break; | 2038 | break; |
1918 | } | 2039 | } |
1919 | } | 2040 | } |
2041 | spin_unlock(&rpipe->seg_lock); | ||
1920 | xfer->result = urb->status; /* -ENOENT or -ECONNRESET */ | 2042 | xfer->result = urb->status; /* -ENOENT or -ECONNRESET */ |
1921 | done = __wa_xfer_is_done(xfer); | 2043 | done = __wa_xfer_is_done(xfer); |
1922 | spin_unlock_irqrestore(&xfer->lock, flags); | 2044 | spin_unlock_irqrestore(&xfer->lock, flags); |
@@ -1924,11 +2046,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) | |||
1924 | wa_xfer_completion(xfer); | 2046 | wa_xfer_completion(xfer); |
1925 | if (rpipe_ready) | 2047 | if (rpipe_ready) |
1926 | wa_xfer_delayed_run(rpipe); | 2048 | wa_xfer_delayed_run(rpipe); |
2049 | wa_xfer_put(xfer); | ||
1927 | return result; | 2050 | return result; |
1928 | 2051 | ||
1929 | out_unlock: | 2052 | out_unlock: |
1930 | spin_unlock_irqrestore(&xfer->lock, flags); | 2053 | spin_unlock_irqrestore(&xfer->lock, flags); |
1931 | out: | 2054 | wa_xfer_put(xfer); |
1932 | return result; | 2055 | return result; |
1933 | 2056 | ||
1934 | dequeue_delayed: | 2057 | dequeue_delayed: |
@@ -1937,6 +2060,7 @@ dequeue_delayed: | |||
1937 | xfer->result = urb->status; | 2060 | xfer->result = urb->status; |
1938 | spin_unlock_irqrestore(&xfer->lock, flags); | 2061 | spin_unlock_irqrestore(&xfer->lock, flags); |
1939 | wa_xfer_giveback(xfer); | 2062 | wa_xfer_giveback(xfer); |
2063 | wa_xfer_put(xfer); | ||
1940 | usb_put_urb(urb); /* we got a ref in enqueue() */ | 2064 | usb_put_urb(urb); /* we got a ref in enqueue() */ |
1941 | return 0; | 2065 | return 0; |
1942 | } | 2066 | } |
@@ -1996,15 +2120,17 @@ static int wa_xfer_status_to_errno(u8 status) | |||
1996 | * no other segment transfer results will be returned from the device. | 2120 | * no other segment transfer results will be returned from the device. |
1997 | * Mark the remaining submitted or pending xfers as completed so that | 2121 | * Mark the remaining submitted or pending xfers as completed so that |
1998 | * the xfer will complete cleanly. | 2122 | * the xfer will complete cleanly. |
2123 | * | ||
2124 | * xfer->lock must be held | ||
2125 | * | ||
1999 | */ | 2126 | */ |
2000 | static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | 2127 | static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, |
2001 | struct wa_seg *incoming_seg, enum wa_seg_status status) | 2128 | int starting_index, enum wa_seg_status status) |
2002 | { | 2129 | { |
2003 | int index; | 2130 | int index; |
2004 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; | 2131 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; |
2005 | 2132 | ||
2006 | for (index = incoming_seg->index + 1; index < xfer->segs_submitted; | 2133 | for (index = starting_index; index < xfer->segs_submitted; index++) { |
2007 | index++) { | ||
2008 | struct wa_seg *current_seg = xfer->seg[index]; | 2134 | struct wa_seg *current_seg = xfer->seg[index]; |
2009 | 2135 | ||
2010 | BUG_ON(current_seg == NULL); | 2136 | BUG_ON(current_seg == NULL); |
@@ -2033,73 +2159,110 @@ static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | |||
2033 | } | 2159 | } |
2034 | } | 2160 | } |
2035 | 2161 | ||
2036 | /* Populate the wa->buf_in_urb based on the current isoc transfer state. */ | 2162 | /* Populate the given urb based on the current isoc transfer state. */ |
2037 | static void __wa_populate_buf_in_urb_isoc(struct wahc *wa, struct wa_xfer *xfer, | 2163 | static int __wa_populate_buf_in_urb_isoc(struct wahc *wa, |
2038 | struct wa_seg *seg, int curr_iso_frame) | 2164 | struct urb *buf_in_urb, struct wa_xfer *xfer, struct wa_seg *seg) |
2039 | { | 2165 | { |
2040 | BUG_ON(wa->buf_in_urb->status == -EINPROGRESS); | 2166 | int urb_start_frame = seg->isoc_frame_index + seg->isoc_frame_offset; |
2167 | int seg_index, total_len = 0, urb_frame_index = urb_start_frame; | ||
2168 | struct usb_iso_packet_descriptor *iso_frame_desc = | ||
2169 | xfer->urb->iso_frame_desc; | ||
2170 | const int dti_packet_size = usb_endpoint_maxp(wa->dti_epd); | ||
2171 | int next_frame_contiguous; | ||
2172 | struct usb_iso_packet_descriptor *iso_frame; | ||
2173 | |||
2174 | BUG_ON(buf_in_urb->status == -EINPROGRESS); | ||
2175 | |||
2176 | /* | ||
2177 | * If the current frame actual_length is contiguous with the next frame | ||
2178 | * and actual_length is a multiple of the DTI endpoint max packet size, | ||
2179 | * combine the current frame with the next frame in a single URB. This | ||
2180 | * reduces the number of URBs that must be submitted in that case. | ||
2181 | */ | ||
2182 | seg_index = seg->isoc_frame_index; | ||
2183 | do { | ||
2184 | next_frame_contiguous = 0; | ||
2185 | |||
2186 | iso_frame = &iso_frame_desc[urb_frame_index]; | ||
2187 | total_len += iso_frame->actual_length; | ||
2188 | ++urb_frame_index; | ||
2189 | ++seg_index; | ||
2190 | |||
2191 | if (seg_index < seg->isoc_frame_count) { | ||
2192 | struct usb_iso_packet_descriptor *next_iso_frame; | ||
2193 | |||
2194 | next_iso_frame = &iso_frame_desc[urb_frame_index]; | ||
2195 | |||
2196 | if ((iso_frame->offset + iso_frame->actual_length) == | ||
2197 | next_iso_frame->offset) | ||
2198 | next_frame_contiguous = 1; | ||
2199 | } | ||
2200 | } while (next_frame_contiguous | ||
2201 | && ((iso_frame->actual_length % dti_packet_size) == 0)); | ||
2041 | 2202 | ||
2042 | /* this should always be 0 before a resubmit. */ | 2203 | /* this should always be 0 before a resubmit. */ |
2043 | wa->buf_in_urb->num_mapped_sgs = 0; | 2204 | buf_in_urb->num_mapped_sgs = 0; |
2044 | wa->buf_in_urb->transfer_dma = xfer->urb->transfer_dma + | 2205 | buf_in_urb->transfer_dma = xfer->urb->transfer_dma + |
2045 | xfer->urb->iso_frame_desc[curr_iso_frame].offset; | 2206 | iso_frame_desc[urb_start_frame].offset; |
2046 | wa->buf_in_urb->transfer_buffer_length = | 2207 | buf_in_urb->transfer_buffer_length = total_len; |
2047 | xfer->urb->iso_frame_desc[curr_iso_frame].length; | 2208 | buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
2048 | wa->buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 2209 | buf_in_urb->transfer_buffer = NULL; |
2049 | wa->buf_in_urb->transfer_buffer = NULL; | 2210 | buf_in_urb->sg = NULL; |
2050 | wa->buf_in_urb->sg = NULL; | 2211 | buf_in_urb->num_sgs = 0; |
2051 | wa->buf_in_urb->num_sgs = 0; | 2212 | buf_in_urb->context = seg; |
2052 | wa->buf_in_urb->context = seg; | 2213 | |
2214 | /* return the number of frames included in this URB. */ | ||
2215 | return seg_index - seg->isoc_frame_index; | ||
2053 | } | 2216 | } |
2054 | 2217 | ||
2055 | /* Populate the wa->buf_in_urb based on the current transfer state. */ | 2218 | /* Populate the given urb based on the current transfer state. */ |
2056 | static int wa_populate_buf_in_urb(struct wahc *wa, struct wa_xfer *xfer, | 2219 | static int wa_populate_buf_in_urb(struct urb *buf_in_urb, struct wa_xfer *xfer, |
2057 | unsigned int seg_idx, unsigned int bytes_transferred) | 2220 | unsigned int seg_idx, unsigned int bytes_transferred) |
2058 | { | 2221 | { |
2059 | int result = 0; | 2222 | int result = 0; |
2060 | struct wa_seg *seg = xfer->seg[seg_idx]; | 2223 | struct wa_seg *seg = xfer->seg[seg_idx]; |
2061 | 2224 | ||
2062 | BUG_ON(wa->buf_in_urb->status == -EINPROGRESS); | 2225 | BUG_ON(buf_in_urb->status == -EINPROGRESS); |
2063 | /* this should always be 0 before a resubmit. */ | 2226 | /* this should always be 0 before a resubmit. */ |
2064 | wa->buf_in_urb->num_mapped_sgs = 0; | 2227 | buf_in_urb->num_mapped_sgs = 0; |
2065 | 2228 | ||
2066 | if (xfer->is_dma) { | 2229 | if (xfer->is_dma) { |
2067 | wa->buf_in_urb->transfer_dma = xfer->urb->transfer_dma | 2230 | buf_in_urb->transfer_dma = xfer->urb->transfer_dma |
2068 | + (seg_idx * xfer->seg_size); | 2231 | + (seg_idx * xfer->seg_size); |
2069 | wa->buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 2232 | buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
2070 | wa->buf_in_urb->transfer_buffer = NULL; | 2233 | buf_in_urb->transfer_buffer = NULL; |
2071 | wa->buf_in_urb->sg = NULL; | 2234 | buf_in_urb->sg = NULL; |
2072 | wa->buf_in_urb->num_sgs = 0; | 2235 | buf_in_urb->num_sgs = 0; |
2073 | } else { | 2236 | } else { |
2074 | /* do buffer or SG processing. */ | 2237 | /* do buffer or SG processing. */ |
2075 | wa->buf_in_urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP; | 2238 | buf_in_urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP; |
2076 | 2239 | ||
2077 | if (xfer->urb->transfer_buffer) { | 2240 | if (xfer->urb->transfer_buffer) { |
2078 | wa->buf_in_urb->transfer_buffer = | 2241 | buf_in_urb->transfer_buffer = |
2079 | xfer->urb->transfer_buffer | 2242 | xfer->urb->transfer_buffer |
2080 | + (seg_idx * xfer->seg_size); | 2243 | + (seg_idx * xfer->seg_size); |
2081 | wa->buf_in_urb->sg = NULL; | 2244 | buf_in_urb->sg = NULL; |
2082 | wa->buf_in_urb->num_sgs = 0; | 2245 | buf_in_urb->num_sgs = 0; |
2083 | } else { | 2246 | } else { |
2084 | /* allocate an SG list to store seg_size bytes | 2247 | /* allocate an SG list to store seg_size bytes |
2085 | and copy the subset of the xfer->urb->sg | 2248 | and copy the subset of the xfer->urb->sg |
2086 | that matches the buffer subset we are | 2249 | that matches the buffer subset we are |
2087 | about to read. */ | 2250 | about to read. */ |
2088 | wa->buf_in_urb->sg = wa_xfer_create_subset_sg( | 2251 | buf_in_urb->sg = wa_xfer_create_subset_sg( |
2089 | xfer->urb->sg, | 2252 | xfer->urb->sg, |
2090 | seg_idx * xfer->seg_size, | 2253 | seg_idx * xfer->seg_size, |
2091 | bytes_transferred, | 2254 | bytes_transferred, |
2092 | &(wa->buf_in_urb->num_sgs)); | 2255 | &(buf_in_urb->num_sgs)); |
2093 | 2256 | ||
2094 | if (!(wa->buf_in_urb->sg)) { | 2257 | if (!(buf_in_urb->sg)) { |
2095 | wa->buf_in_urb->num_sgs = 0; | 2258 | buf_in_urb->num_sgs = 0; |
2096 | result = -ENOMEM; | 2259 | result = -ENOMEM; |
2097 | } | 2260 | } |
2098 | wa->buf_in_urb->transfer_buffer = NULL; | 2261 | buf_in_urb->transfer_buffer = NULL; |
2099 | } | 2262 | } |
2100 | } | 2263 | } |
2101 | wa->buf_in_urb->transfer_buffer_length = bytes_transferred; | 2264 | buf_in_urb->transfer_buffer_length = bytes_transferred; |
2102 | wa->buf_in_urb->context = seg; | 2265 | buf_in_urb->context = seg; |
2103 | 2266 | ||
2104 | return result; | 2267 | return result; |
2105 | } | 2268 | } |
@@ -2124,6 +2287,7 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2124 | u8 usb_status; | 2287 | u8 usb_status; |
2125 | unsigned rpipe_ready = 0; | 2288 | unsigned rpipe_ready = 0; |
2126 | unsigned bytes_transferred = le32_to_cpu(xfer_result->dwTransferLength); | 2289 | unsigned bytes_transferred = le32_to_cpu(xfer_result->dwTransferLength); |
2290 | struct urb *buf_in_urb = &(wa->buf_in_urbs[0]); | ||
2127 | 2291 | ||
2128 | spin_lock_irqsave(&xfer->lock, flags); | 2292 | spin_lock_irqsave(&xfer->lock, flags); |
2129 | seg_idx = xfer_result->bTransferSegment & 0x7f; | 2293 | seg_idx = xfer_result->bTransferSegment & 0x7f; |
@@ -2147,7 +2311,7 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2147 | } | 2311 | } |
2148 | if (usb_status & 0x80) { | 2312 | if (usb_status & 0x80) { |
2149 | seg->result = wa_xfer_status_to_errno(usb_status); | 2313 | seg->result = wa_xfer_status_to_errno(usb_status); |
2150 | dev_err(dev, "DTI: xfer %p#:%08X:%u failed (0x%02x)\n", | 2314 | dev_err(dev, "DTI: xfer %p 0x%08X:#%u failed (0x%02x)\n", |
2151 | xfer, xfer->id, seg->index, usb_status); | 2315 | xfer, xfer->id, seg->index, usb_status); |
2152 | seg->status = ((usb_status & 0x7F) == WA_XFER_STATUS_ABORTED) ? | 2316 | seg->status = ((usb_status & 0x7F) == WA_XFER_STATUS_ABORTED) ? |
2153 | WA_SEG_ABORTED : WA_SEG_ERROR; | 2317 | WA_SEG_ABORTED : WA_SEG_ERROR; |
@@ -2162,7 +2326,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2162 | * transfers with data or below for no data, the xfer will complete. | 2326 | * transfers with data or below for no data, the xfer will complete. |
2163 | */ | 2327 | */ |
2164 | if (xfer_result->bTransferSegment & 0x80) | 2328 | if (xfer_result->bTransferSegment & 0x80) |
2165 | wa_complete_remaining_xfer_segs(xfer, seg, WA_SEG_DONE); | 2329 | wa_complete_remaining_xfer_segs(xfer, seg->index + 1, |
2330 | WA_SEG_DONE); | ||
2166 | if (usb_pipeisoc(xfer->urb->pipe) | 2331 | if (usb_pipeisoc(xfer->urb->pipe) |
2167 | && (le32_to_cpu(xfer_result->dwNumOfPackets) > 0)) { | 2332 | && (le32_to_cpu(xfer_result->dwNumOfPackets) > 0)) { |
2168 | /* set up WA state to read the isoc packet status next. */ | 2333 | /* set up WA state to read the isoc packet status next. */ |
@@ -2173,20 +2338,21 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2173 | && (bytes_transferred > 0)) { | 2338 | && (bytes_transferred > 0)) { |
2174 | /* IN data phase: read to buffer */ | 2339 | /* IN data phase: read to buffer */ |
2175 | seg->status = WA_SEG_DTI_PENDING; | 2340 | seg->status = WA_SEG_DTI_PENDING; |
2176 | result = wa_populate_buf_in_urb(wa, xfer, seg_idx, | 2341 | result = wa_populate_buf_in_urb(buf_in_urb, xfer, seg_idx, |
2177 | bytes_transferred); | 2342 | bytes_transferred); |
2178 | if (result < 0) | 2343 | if (result < 0) |
2179 | goto error_buf_in_populate; | 2344 | goto error_buf_in_populate; |
2180 | result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC); | 2345 | ++(wa->active_buf_in_urbs); |
2181 | if (result < 0) | 2346 | result = usb_submit_urb(buf_in_urb, GFP_ATOMIC); |
2347 | if (result < 0) { | ||
2348 | --(wa->active_buf_in_urbs); | ||
2182 | goto error_submit_buf_in; | 2349 | goto error_submit_buf_in; |
2350 | } | ||
2183 | } else { | 2351 | } else { |
2184 | /* OUT data phase or no data, complete it -- */ | 2352 | /* OUT data phase or no data, complete it -- */ |
2185 | seg->status = WA_SEG_DONE; | ||
2186 | seg->result = bytes_transferred; | 2353 | seg->result = bytes_transferred; |
2187 | xfer->segs_done++; | ||
2188 | rpipe_ready = rpipe_avail_inc(rpipe); | 2354 | rpipe_ready = rpipe_avail_inc(rpipe); |
2189 | done = __wa_xfer_is_done(xfer); | 2355 | done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE); |
2190 | } | 2356 | } |
2191 | spin_unlock_irqrestore(&xfer->lock, flags); | 2357 | spin_unlock_irqrestore(&xfer->lock, flags); |
2192 | if (done) | 2358 | if (done) |
@@ -2205,15 +2371,15 @@ error_submit_buf_in: | |||
2205 | dev_err(dev, "xfer %p#%u: can't submit DTI data phase: %d\n", | 2371 | dev_err(dev, "xfer %p#%u: can't submit DTI data phase: %d\n", |
2206 | xfer, seg_idx, result); | 2372 | xfer, seg_idx, result); |
2207 | seg->result = result; | 2373 | seg->result = result; |
2208 | kfree(wa->buf_in_urb->sg); | 2374 | kfree(buf_in_urb->sg); |
2209 | wa->buf_in_urb->sg = NULL; | 2375 | buf_in_urb->sg = NULL; |
2210 | error_buf_in_populate: | 2376 | error_buf_in_populate: |
2211 | __wa_xfer_abort(xfer); | 2377 | __wa_xfer_abort(xfer); |
2212 | seg->status = WA_SEG_ERROR; | 2378 | seg->status = WA_SEG_ERROR; |
2213 | error_complete: | 2379 | error_complete: |
2214 | xfer->segs_done++; | 2380 | xfer->segs_done++; |
2215 | rpipe_ready = rpipe_avail_inc(rpipe); | 2381 | rpipe_ready = rpipe_avail_inc(rpipe); |
2216 | wa_complete_remaining_xfer_segs(xfer, seg, seg->status); | 2382 | wa_complete_remaining_xfer_segs(xfer, seg->index + 1, seg->status); |
2217 | done = __wa_xfer_is_done(xfer); | 2383 | done = __wa_xfer_is_done(xfer); |
2218 | /* | 2384 | /* |
2219 | * queue work item to clear STALL for control endpoints. | 2385 | * queue work item to clear STALL for control endpoints. |
@@ -2315,16 +2481,16 @@ static int wa_process_iso_packet_status(struct wahc *wa, struct urb *urb) | |||
2315 | for (seg_index = 0; seg_index < seg->isoc_frame_count; ++seg_index) { | 2481 | for (seg_index = 0; seg_index < seg->isoc_frame_count; ++seg_index) { |
2316 | struct usb_iso_packet_descriptor *iso_frame_desc = | 2482 | struct usb_iso_packet_descriptor *iso_frame_desc = |
2317 | xfer->urb->iso_frame_desc; | 2483 | xfer->urb->iso_frame_desc; |
2318 | const int urb_frame_index = | 2484 | const int xfer_frame_index = |
2319 | seg->isoc_frame_offset + seg_index; | 2485 | seg->isoc_frame_offset + seg_index; |
2320 | 2486 | ||
2321 | iso_frame_desc[urb_frame_index].status = | 2487 | iso_frame_desc[xfer_frame_index].status = |
2322 | wa_xfer_status_to_errno( | 2488 | wa_xfer_status_to_errno( |
2323 | le16_to_cpu(status_array[seg_index].PacketStatus)); | 2489 | le16_to_cpu(status_array[seg_index].PacketStatus)); |
2324 | iso_frame_desc[urb_frame_index].actual_length = | 2490 | iso_frame_desc[xfer_frame_index].actual_length = |
2325 | le16_to_cpu(status_array[seg_index].PacketLength); | 2491 | le16_to_cpu(status_array[seg_index].PacketLength); |
2326 | /* track the number of frames successfully transferred. */ | 2492 | /* track the number of frames successfully transferred. */ |
2327 | if (iso_frame_desc[urb_frame_index].actual_length > 0) { | 2493 | if (iso_frame_desc[xfer_frame_index].actual_length > 0) { |
2328 | /* save the starting frame index for buf_in_urb. */ | 2494 | /* save the starting frame index for buf_in_urb. */ |
2329 | if (!data_frame_count) | 2495 | if (!data_frame_count) |
2330 | first_frame_index = seg_index; | 2496 | first_frame_index = seg_index; |
@@ -2333,30 +2499,64 @@ static int wa_process_iso_packet_status(struct wahc *wa, struct urb *urb) | |||
2333 | } | 2499 | } |
2334 | 2500 | ||
2335 | if (xfer->is_inbound && data_frame_count) { | 2501 | if (xfer->is_inbound && data_frame_count) { |
2336 | int result; | 2502 | int result, total_frames_read = 0, urb_index = 0; |
2503 | struct urb *buf_in_urb; | ||
2337 | 2504 | ||
2505 | /* IN data phase: read to buffer */ | ||
2506 | seg->status = WA_SEG_DTI_PENDING; | ||
2507 | |||
2508 | /* start with the first frame with data. */ | ||
2338 | seg->isoc_frame_index = first_frame_index; | 2509 | seg->isoc_frame_index = first_frame_index; |
2339 | /* submit a read URB for the first frame with data. */ | 2510 | /* submit up to WA_MAX_BUF_IN_URBS read URBs. */ |
2340 | __wa_populate_buf_in_urb_isoc(wa, xfer, seg, | 2511 | do { |
2341 | seg->isoc_frame_index + seg->isoc_frame_offset); | 2512 | int urb_frame_index, urb_frame_count; |
2513 | struct usb_iso_packet_descriptor *iso_frame_desc; | ||
2514 | |||
2515 | buf_in_urb = &(wa->buf_in_urbs[urb_index]); | ||
2516 | urb_frame_count = __wa_populate_buf_in_urb_isoc(wa, | ||
2517 | buf_in_urb, xfer, seg); | ||
2518 | /* advance frame index to start of next read URB. */ | ||
2519 | seg->isoc_frame_index += urb_frame_count; | ||
2520 | total_frames_read += urb_frame_count; | ||
2521 | |||
2522 | ++(wa->active_buf_in_urbs); | ||
2523 | result = usb_submit_urb(buf_in_urb, GFP_ATOMIC); | ||
2524 | |||
2525 | /* skip 0-byte frames. */ | ||
2526 | urb_frame_index = | ||
2527 | seg->isoc_frame_offset + seg->isoc_frame_index; | ||
2528 | iso_frame_desc = | ||
2529 | &(xfer->urb->iso_frame_desc[urb_frame_index]); | ||
2530 | while ((seg->isoc_frame_index < | ||
2531 | seg->isoc_frame_count) && | ||
2532 | (iso_frame_desc->actual_length == 0)) { | ||
2533 | ++(seg->isoc_frame_index); | ||
2534 | ++iso_frame_desc; | ||
2535 | } | ||
2536 | ++urb_index; | ||
2537 | |||
2538 | } while ((result == 0) && (urb_index < WA_MAX_BUF_IN_URBS) | ||
2539 | && (seg->isoc_frame_index < | ||
2540 | seg->isoc_frame_count)); | ||
2342 | 2541 | ||
2343 | result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC); | ||
2344 | if (result < 0) { | 2542 | if (result < 0) { |
2543 | --(wa->active_buf_in_urbs); | ||
2345 | dev_err(dev, "DTI Error: Could not submit buf in URB (%d)", | 2544 | dev_err(dev, "DTI Error: Could not submit buf in URB (%d)", |
2346 | result); | 2545 | result); |
2347 | wa_reset_all(wa); | 2546 | wa_reset_all(wa); |
2348 | } else if (data_frame_count > 1) | 2547 | } else if (data_frame_count > total_frames_read) |
2349 | /* If we need to read multiple frames, set DTI busy. */ | 2548 | /* If we need to read more frames, set DTI busy. */ |
2350 | dti_busy = 1; | 2549 | dti_busy = 1; |
2351 | } else { | 2550 | } else { |
2352 | /* OUT transfer or no more IN data, complete it -- */ | 2551 | /* OUT transfer or no more IN data, complete it -- */ |
2353 | seg->status = WA_SEG_DONE; | ||
2354 | xfer->segs_done++; | ||
2355 | rpipe_ready = rpipe_avail_inc(rpipe); | 2552 | rpipe_ready = rpipe_avail_inc(rpipe); |
2356 | done = __wa_xfer_is_done(xfer); | 2553 | done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE); |
2357 | } | 2554 | } |
2358 | spin_unlock_irqrestore(&xfer->lock, flags); | 2555 | spin_unlock_irqrestore(&xfer->lock, flags); |
2359 | wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; | 2556 | if (dti_busy) |
2557 | wa->dti_state = WA_DTI_BUF_IN_DATA_PENDING; | ||
2558 | else | ||
2559 | wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; | ||
2360 | if (done) | 2560 | if (done) |
2361 | wa_xfer_completion(xfer); | 2561 | wa_xfer_completion(xfer); |
2362 | if (rpipe_ready) | 2562 | if (rpipe_ready) |
@@ -2388,8 +2588,9 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2388 | struct wahc *wa; | 2588 | struct wahc *wa; |
2389 | struct device *dev; | 2589 | struct device *dev; |
2390 | struct wa_rpipe *rpipe; | 2590 | struct wa_rpipe *rpipe; |
2391 | unsigned rpipe_ready = 0, seg_index, isoc_data_frame_count = 0; | 2591 | unsigned rpipe_ready = 0, isoc_data_frame_count = 0; |
2392 | unsigned long flags; | 2592 | unsigned long flags; |
2593 | int resubmit_dti = 0, active_buf_in_urbs; | ||
2393 | u8 done = 0; | 2594 | u8 done = 0; |
2394 | 2595 | ||
2395 | /* free the sg if it was used. */ | 2596 | /* free the sg if it was used. */ |
@@ -2399,19 +2600,20 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2399 | spin_lock_irqsave(&xfer->lock, flags); | 2600 | spin_lock_irqsave(&xfer->lock, flags); |
2400 | wa = xfer->wa; | 2601 | wa = xfer->wa; |
2401 | dev = &wa->usb_iface->dev; | 2602 | dev = &wa->usb_iface->dev; |
2603 | --(wa->active_buf_in_urbs); | ||
2604 | active_buf_in_urbs = wa->active_buf_in_urbs; | ||
2402 | 2605 | ||
2403 | if (usb_pipeisoc(xfer->urb->pipe)) { | 2606 | if (usb_pipeisoc(xfer->urb->pipe)) { |
2607 | struct usb_iso_packet_descriptor *iso_frame_desc = | ||
2608 | xfer->urb->iso_frame_desc; | ||
2609 | int seg_index; | ||
2610 | |||
2404 | /* | 2611 | /* |
2405 | * Find the next isoc frame with data. Bail out after | 2612 | * Find the next isoc frame with data and count how many |
2406 | * isoc_data_frame_count > 1 since there is no need to walk | 2613 | * frames with data remain. |
2407 | * the entire frame array. We just need to know if | ||
2408 | * isoc_data_frame_count is 0, 1, or >1. | ||
2409 | */ | 2614 | */ |
2410 | seg_index = seg->isoc_frame_index + 1; | 2615 | seg_index = seg->isoc_frame_index; |
2411 | while ((seg_index < seg->isoc_frame_count) | 2616 | while (seg_index < seg->isoc_frame_count) { |
2412 | && (isoc_data_frame_count <= 1)) { | ||
2413 | struct usb_iso_packet_descriptor *iso_frame_desc = | ||
2414 | xfer->urb->iso_frame_desc; | ||
2415 | const int urb_frame_index = | 2617 | const int urb_frame_index = |
2416 | seg->isoc_frame_offset + seg_index; | 2618 | seg->isoc_frame_offset + seg_index; |
2417 | 2619 | ||
@@ -2432,24 +2634,39 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2432 | 2634 | ||
2433 | seg->result += urb->actual_length; | 2635 | seg->result += urb->actual_length; |
2434 | if (isoc_data_frame_count > 0) { | 2636 | if (isoc_data_frame_count > 0) { |
2435 | int result; | 2637 | int result, urb_frame_count; |
2436 | /* submit a read URB for the first frame with data. */ | 2638 | |
2437 | __wa_populate_buf_in_urb_isoc(wa, xfer, seg, | 2639 | /* submit a read URB for the next frame with data. */ |
2438 | seg->isoc_frame_index + seg->isoc_frame_offset); | 2640 | urb_frame_count = __wa_populate_buf_in_urb_isoc(wa, urb, |
2439 | result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC); | 2641 | xfer, seg); |
2642 | /* advance index to start of next read URB. */ | ||
2643 | seg->isoc_frame_index += urb_frame_count; | ||
2644 | ++(wa->active_buf_in_urbs); | ||
2645 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
2440 | if (result < 0) { | 2646 | if (result < 0) { |
2647 | --(wa->active_buf_in_urbs); | ||
2441 | dev_err(dev, "DTI Error: Could not submit buf in URB (%d)", | 2648 | dev_err(dev, "DTI Error: Could not submit buf in URB (%d)", |
2442 | result); | 2649 | result); |
2443 | wa_reset_all(wa); | 2650 | wa_reset_all(wa); |
2444 | } | 2651 | } |
2445 | } else { | 2652 | /* |
2653 | * If we are in this callback and | ||
2654 | * isoc_data_frame_count > 0, it means that the dti_urb | ||
2655 | * submission was delayed in wa_dti_cb. Once | ||
2656 | * we submit the last buf_in_urb, we can submit the | ||
2657 | * delayed dti_urb. | ||
2658 | */ | ||
2659 | resubmit_dti = (isoc_data_frame_count == | ||
2660 | urb_frame_count); | ||
2661 | } else if (active_buf_in_urbs == 0) { | ||
2446 | rpipe = xfer->ep->hcpriv; | 2662 | rpipe = xfer->ep->hcpriv; |
2447 | seg->status = WA_SEG_DONE; | 2663 | dev_dbg(dev, |
2448 | dev_dbg(dev, "xfer %p#%u: data in done (%zu bytes)\n", | 2664 | "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", |
2449 | xfer, seg->index, seg->result); | 2665 | xfer, wa_xfer_id(xfer), seg->index, |
2450 | xfer->segs_done++; | 2666 | seg->result); |
2451 | rpipe_ready = rpipe_avail_inc(rpipe); | 2667 | rpipe_ready = rpipe_avail_inc(rpipe); |
2452 | done = __wa_xfer_is_done(xfer); | 2668 | done = __wa_xfer_mark_seg_as_done(xfer, seg, |
2669 | WA_SEG_DONE); | ||
2453 | } | 2670 | } |
2454 | spin_unlock_irqrestore(&xfer->lock, flags); | 2671 | spin_unlock_irqrestore(&xfer->lock, flags); |
2455 | if (done) | 2672 | if (done) |
@@ -2461,37 +2678,44 @@ static void wa_buf_in_cb(struct urb *urb) | |||
2461 | case -ENOENT: /* as it was done by the who unlinked us */ | 2678 | case -ENOENT: /* as it was done by the who unlinked us */ |
2462 | break; | 2679 | break; |
2463 | default: /* Other errors ... */ | 2680 | default: /* Other errors ... */ |
2681 | /* | ||
2682 | * Error on data buf read. Only resubmit DTI if it hasn't | ||
2683 | * already been done by previously hitting this error or by a | ||
2684 | * successful completion of the previous buf_in_urb. | ||
2685 | */ | ||
2686 | resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; | ||
2464 | spin_lock_irqsave(&xfer->lock, flags); | 2687 | spin_lock_irqsave(&xfer->lock, flags); |
2465 | rpipe = xfer->ep->hcpriv; | 2688 | rpipe = xfer->ep->hcpriv; |
2466 | if (printk_ratelimit()) | 2689 | if (printk_ratelimit()) |
2467 | dev_err(dev, "xfer %p#%u: data in error %d\n", | 2690 | dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", |
2468 | xfer, seg->index, urb->status); | 2691 | xfer, wa_xfer_id(xfer), seg->index, |
2692 | urb->status); | ||
2469 | if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS, | 2693 | if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS, |
2470 | EDC_ERROR_TIMEFRAME)){ | 2694 | EDC_ERROR_TIMEFRAME)){ |
2471 | dev_err(dev, "DTO: URB max acceptable errors " | 2695 | dev_err(dev, "DTO: URB max acceptable errors " |
2472 | "exceeded, resetting device\n"); | 2696 | "exceeded, resetting device\n"); |
2473 | wa_reset_all(wa); | 2697 | wa_reset_all(wa); |
2474 | } | 2698 | } |
2475 | seg->status = WA_SEG_ERROR; | ||
2476 | seg->result = urb->status; | 2699 | seg->result = urb->status; |
2477 | xfer->segs_done++; | ||
2478 | rpipe_ready = rpipe_avail_inc(rpipe); | 2700 | rpipe_ready = rpipe_avail_inc(rpipe); |
2479 | __wa_xfer_abort(xfer); | 2701 | if (active_buf_in_urbs == 0) |
2480 | done = __wa_xfer_is_done(xfer); | 2702 | done = __wa_xfer_mark_seg_as_done(xfer, seg, |
2703 | WA_SEG_ERROR); | ||
2704 | else | ||
2705 | __wa_xfer_abort(xfer); | ||
2481 | spin_unlock_irqrestore(&xfer->lock, flags); | 2706 | spin_unlock_irqrestore(&xfer->lock, flags); |
2482 | if (done) | 2707 | if (done) |
2483 | wa_xfer_completion(xfer); | 2708 | wa_xfer_completion(xfer); |
2484 | if (rpipe_ready) | 2709 | if (rpipe_ready) |
2485 | wa_xfer_delayed_run(rpipe); | 2710 | wa_xfer_delayed_run(rpipe); |
2486 | } | 2711 | } |
2487 | /* | 2712 | |
2488 | * If we are in this callback and isoc_data_frame_count > 0, it means | 2713 | if (resubmit_dti) { |
2489 | * that the dti_urb submission was delayed in wa_dti_cb. Once | 2714 | int result; |
2490 | * isoc_data_frame_count gets to 1, we can submit the deferred URB | 2715 | |
2491 | * since the last buf_in_urb was just submitted. | 2716 | wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; |
2492 | */ | 2717 | |
2493 | if (isoc_data_frame_count == 1) { | 2718 | result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC); |
2494 | int result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC); | ||
2495 | if (result < 0) { | 2719 | if (result < 0) { |
2496 | dev_err(dev, "DTI Error: Could not submit DTI URB (%d)\n", | 2720 | dev_err(dev, "DTI Error: Could not submit DTI URB (%d)\n", |
2497 | result); | 2721 | result); |
@@ -2561,11 +2785,15 @@ static void wa_dti_cb(struct urb *urb) | |||
2561 | xfer_result->hdr.bNotifyType); | 2785 | xfer_result->hdr.bNotifyType); |
2562 | break; | 2786 | break; |
2563 | } | 2787 | } |
2788 | xfer_id = le32_to_cpu(xfer_result->dwTransferID); | ||
2564 | usb_status = xfer_result->bTransferStatus & 0x3f; | 2789 | usb_status = xfer_result->bTransferStatus & 0x3f; |
2565 | if (usb_status == WA_XFER_STATUS_NOT_FOUND) | 2790 | if (usb_status == WA_XFER_STATUS_NOT_FOUND) { |
2566 | /* taken care of already */ | 2791 | /* taken care of already */ |
2792 | dev_dbg(dev, "%s: xfer 0x%08X#%u not found.\n", | ||
2793 | __func__, xfer_id, | ||
2794 | xfer_result->bTransferSegment & 0x7f); | ||
2567 | break; | 2795 | break; |
2568 | xfer_id = le32_to_cpu(xfer_result->dwTransferID); | 2796 | } |
2569 | xfer = wa_xfer_get_by_id(wa, xfer_id); | 2797 | xfer = wa_xfer_get_by_id(wa, xfer_id); |
2570 | if (xfer == NULL) { | 2798 | if (xfer == NULL) { |
2571 | /* FIXME: transaction not found. */ | 2799 | /* FIXME: transaction not found. */ |
@@ -2614,6 +2842,54 @@ out: | |||
2614 | } | 2842 | } |
2615 | 2843 | ||
2616 | /* | 2844 | /* |
2845 | * Initialize the DTI URB for reading transfer result notifications and also | ||
2846 | * the buffer-in URB, for reading buffers. Then we just submit the DTI URB. | ||
2847 | */ | ||
2848 | int wa_dti_start(struct wahc *wa) | ||
2849 | { | ||
2850 | const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; | ||
2851 | struct device *dev = &wa->usb_iface->dev; | ||
2852 | int result = -ENOMEM, index; | ||
2853 | |||
2854 | if (wa->dti_urb != NULL) /* DTI URB already started */ | ||
2855 | goto out; | ||
2856 | |||
2857 | wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2858 | if (wa->dti_urb == NULL) { | ||
2859 | dev_err(dev, "Can't allocate DTI URB\n"); | ||
2860 | goto error_dti_urb_alloc; | ||
2861 | } | ||
2862 | usb_fill_bulk_urb( | ||
2863 | wa->dti_urb, wa->usb_dev, | ||
2864 | usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress), | ||
2865 | wa->dti_buf, wa->dti_buf_size, | ||
2866 | wa_dti_cb, wa); | ||
2867 | |||
2868 | /* init the buf in URBs */ | ||
2869 | for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index) { | ||
2870 | usb_fill_bulk_urb( | ||
2871 | &(wa->buf_in_urbs[index]), wa->usb_dev, | ||
2872 | usb_rcvbulkpipe(wa->usb_dev, | ||
2873 | 0x80 | dti_epd->bEndpointAddress), | ||
2874 | NULL, 0, wa_buf_in_cb, wa); | ||
2875 | } | ||
2876 | result = usb_submit_urb(wa->dti_urb, GFP_KERNEL); | ||
2877 | if (result < 0) { | ||
2878 | dev_err(dev, "DTI Error: Could not submit DTI URB (%d) resetting\n", | ||
2879 | result); | ||
2880 | goto error_dti_urb_submit; | ||
2881 | } | ||
2882 | out: | ||
2883 | return 0; | ||
2884 | |||
2885 | error_dti_urb_submit: | ||
2886 | usb_put_urb(wa->dti_urb); | ||
2887 | wa->dti_urb = NULL; | ||
2888 | error_dti_urb_alloc: | ||
2889 | return result; | ||
2890 | } | ||
2891 | EXPORT_SYMBOL_GPL(wa_dti_start); | ||
2892 | /* | ||
2617 | * Transfer complete notification | 2893 | * Transfer complete notification |
2618 | * | 2894 | * |
2619 | * Called from the notif.c code. We get a notification on EP2 saying | 2895 | * Called from the notif.c code. We get a notification on EP2 saying |
@@ -2627,15 +2903,10 @@ out: | |||
2627 | * Follow up in wa_dti_cb(), as that's where the whole state | 2903 | * Follow up in wa_dti_cb(), as that's where the whole state |
2628 | * machine starts. | 2904 | * machine starts. |
2629 | * | 2905 | * |
2630 | * So here we just initialize the DTI URB for reading transfer result | ||
2631 | * notifications and also the buffer-in URB, for reading buffers. Then | ||
2632 | * we just submit the DTI URB. | ||
2633 | * | ||
2634 | * @wa shall be referenced | 2906 | * @wa shall be referenced |
2635 | */ | 2907 | */ |
2636 | void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr) | 2908 | void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr) |
2637 | { | 2909 | { |
2638 | int result; | ||
2639 | struct device *dev = &wa->usb_iface->dev; | 2910 | struct device *dev = &wa->usb_iface->dev; |
2640 | struct wa_notif_xfer *notif_xfer; | 2911 | struct wa_notif_xfer *notif_xfer; |
2641 | const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; | 2912 | const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; |
@@ -2649,45 +2920,13 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr) | |||
2649 | notif_xfer->bEndpoint, dti_epd->bEndpointAddress); | 2920 | notif_xfer->bEndpoint, dti_epd->bEndpointAddress); |
2650 | goto error; | 2921 | goto error; |
2651 | } | 2922 | } |
2652 | if (wa->dti_urb != NULL) /* DTI URB already started */ | ||
2653 | goto out; | ||
2654 | 2923 | ||
2655 | wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL); | 2924 | /* attempt to start the DTI ep processing. */ |
2656 | if (wa->dti_urb == NULL) { | 2925 | if (wa_dti_start(wa) < 0) |
2657 | dev_err(dev, "Can't allocate DTI URB\n"); | 2926 | goto error; |
2658 | goto error_dti_urb_alloc; | ||
2659 | } | ||
2660 | usb_fill_bulk_urb( | ||
2661 | wa->dti_urb, wa->usb_dev, | ||
2662 | usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint), | ||
2663 | wa->dti_buf, wa->dti_buf_size, | ||
2664 | wa_dti_cb, wa); | ||
2665 | 2927 | ||
2666 | wa->buf_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2667 | if (wa->buf_in_urb == NULL) { | ||
2668 | dev_err(dev, "Can't allocate BUF-IN URB\n"); | ||
2669 | goto error_buf_in_urb_alloc; | ||
2670 | } | ||
2671 | usb_fill_bulk_urb( | ||
2672 | wa->buf_in_urb, wa->usb_dev, | ||
2673 | usb_rcvbulkpipe(wa->usb_dev, 0x80 | notif_xfer->bEndpoint), | ||
2674 | NULL, 0, wa_buf_in_cb, wa); | ||
2675 | result = usb_submit_urb(wa->dti_urb, GFP_KERNEL); | ||
2676 | if (result < 0) { | ||
2677 | dev_err(dev, "DTI Error: Could not submit DTI URB (%d) resetting\n", | ||
2678 | result); | ||
2679 | goto error_dti_urb_submit; | ||
2680 | } | ||
2681 | out: | ||
2682 | return; | 2928 | return; |
2683 | 2929 | ||
2684 | error_dti_urb_submit: | ||
2685 | usb_put_urb(wa->buf_in_urb); | ||
2686 | wa->buf_in_urb = NULL; | ||
2687 | error_buf_in_urb_alloc: | ||
2688 | usb_put_urb(wa->dti_urb); | ||
2689 | wa->dti_urb = NULL; | ||
2690 | error_dti_urb_alloc: | ||
2691 | error: | 2930 | error: |
2692 | wa_reset_all(wa); | 2931 | wa_reset_all(wa); |
2693 | } | 2932 | } |
diff --git a/include/linux/usb/omap_control_usb.h b/include/linux/phy/omap_control_phy.h index 69ae383ee3cc..5450403c7546 100644 --- a/include/linux/usb/omap_control_usb.h +++ b/include/linux/phy/omap_control_phy.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * omap_control_usb.h - Header file for the USB part of control module. | 2 | * omap_control_phy.h - Header file for the PHY part of control module. |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | 4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
@@ -16,10 +16,10 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #ifndef __OMAP_CONTROL_USB_H__ | 19 | #ifndef __OMAP_CONTROL_PHY_H__ |
20 | #define __OMAP_CONTROL_USB_H__ | 20 | #define __OMAP_CONTROL_PHY_H__ |
21 | 21 | ||
22 | enum omap_control_usb_type { | 22 | enum omap_control_phy_type { |
23 | OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */ | 23 | OMAP_CTRL_TYPE_OTGHS = 1, /* Mailbox OTGHS_CONTROL */ |
24 | OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ | 24 | OMAP_CTRL_TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ |
25 | OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */ | 25 | OMAP_CTRL_TYPE_PIPE3, /* PIPE3 PHY, DPLL & seperate Rx/Tx power */ |
@@ -27,7 +27,7 @@ enum omap_control_usb_type { | |||
27 | OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ | 27 | OMAP_CTRL_TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ |
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct omap_control_usb { | 30 | struct omap_control_phy { |
31 | struct device *dev; | 31 | struct device *dev; |
32 | 32 | ||
33 | u32 __iomem *otghs_control; | 33 | u32 __iomem *otghs_control; |
@@ -36,7 +36,7 @@ struct omap_control_usb { | |||
36 | 36 | ||
37 | struct clk *sys_clk; | 37 | struct clk *sys_clk; |
38 | 38 | ||
39 | enum omap_control_usb_type type; | 39 | enum omap_control_phy_type type; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | enum omap_control_usb_mode { | 42 | enum omap_control_usb_mode { |
@@ -54,14 +54,14 @@ enum omap_control_usb_mode { | |||
54 | #define OMAP_CTRL_DEV_SESSEND BIT(3) | 54 | #define OMAP_CTRL_DEV_SESSEND BIT(3) |
55 | #define OMAP_CTRL_DEV_IDDIG BIT(4) | 55 | #define OMAP_CTRL_DEV_IDDIG BIT(4) |
56 | 56 | ||
57 | #define OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK 0x003FC000 | 57 | #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 |
58 | #define OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT 0xE | 58 | #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE |
59 | 59 | ||
60 | #define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK 0xFFC00000 | 60 | #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 |
61 | #define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT 0x16 | 61 | #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 |
62 | 62 | ||
63 | #define OMAP_CTRL_USB3_PHY_TX_RX_POWERON 0x3 | 63 | #define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 |
64 | #define OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF 0x0 | 64 | #define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 |
65 | 65 | ||
66 | #define OMAP_CTRL_USB2_PHY_PD BIT(28) | 66 | #define OMAP_CTRL_USB2_PHY_PD BIT(28) |
67 | 67 | ||
@@ -70,13 +70,13 @@ enum omap_control_usb_mode { | |||
70 | #define AM437X_CTRL_USB2_OTGVDET_EN BIT(19) | 70 | #define AM437X_CTRL_USB2_OTGVDET_EN BIT(19) |
71 | #define AM437X_CTRL_USB2_OTGSESSEND_EN BIT(20) | 71 | #define AM437X_CTRL_USB2_OTGSESSEND_EN BIT(20) |
72 | 72 | ||
73 | #if IS_ENABLED(CONFIG_OMAP_CONTROL_USB) | 73 | #if IS_ENABLED(CONFIG_OMAP_CONTROL_PHY) |
74 | extern void omap_control_usb_phy_power(struct device *dev, int on); | 74 | void omap_control_phy_power(struct device *dev, int on); |
75 | extern void omap_control_usb_set_mode(struct device *dev, | 75 | void omap_control_usb_set_mode(struct device *dev, |
76 | enum omap_control_usb_mode mode); | 76 | enum omap_control_usb_mode mode); |
77 | #else | 77 | #else |
78 | 78 | ||
79 | static inline void omap_control_usb_phy_power(struct device *dev, int on) | 79 | static inline void omap_control_phy_power(struct device *dev, int on) |
80 | { | 80 | { |
81 | } | 81 | } |
82 | 82 | ||
@@ -86,4 +86,4 @@ static inline void omap_control_usb_set_mode(struct device *dev, | |||
86 | } | 86 | } |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | #endif /* __OMAP_CONTROL_USB_H__ */ | 89 | #endif /* __OMAP_CONTROL_PHY_H__ */ |
diff --git a/include/linux/usb/omap_usb.h b/include/linux/phy/omap_usb.h index 6ae29360e1d2..dc2c541a619b 100644 --- a/include/linux/usb/omap_usb.h +++ b/include/linux/phy/omap_usb.h | |||
@@ -34,14 +34,24 @@ struct omap_usb { | |||
34 | struct usb_phy phy; | 34 | struct usb_phy phy; |
35 | struct phy_companion *comparator; | 35 | struct phy_companion *comparator; |
36 | void __iomem *pll_ctrl_base; | 36 | void __iomem *pll_ctrl_base; |
37 | void __iomem *phy_base; | ||
37 | struct device *dev; | 38 | struct device *dev; |
38 | struct device *control_dev; | 39 | struct device *control_dev; |
39 | struct clk *wkupclk; | 40 | struct clk *wkupclk; |
40 | struct clk *sys_clk; | ||
41 | struct clk *optclk; | 41 | struct clk *optclk; |
42 | u8 is_suspended:1; | 42 | u8 flags; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct usb_phy_data { | ||
46 | const char *label; | ||
47 | u8 flags; | ||
48 | }; | ||
49 | |||
50 | /* Driver Flags */ | ||
51 | #define OMAP_USB2_HAS_START_SRP (1 << 0) | ||
52 | #define OMAP_USB2_HAS_SET_VBUS (1 << 1) | ||
53 | #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT (1 << 2) | ||
54 | |||
45 | #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) | 55 | #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) |
46 | 56 | ||
47 | #if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) | 57 | #if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) |
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 3f83459dbb20..e2f5ca96cddc 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h | |||
@@ -149,8 +149,11 @@ struct phy *phy_get(struct device *dev, const char *string); | |||
149 | struct phy *phy_optional_get(struct device *dev, const char *string); | 149 | struct phy *phy_optional_get(struct device *dev, const char *string); |
150 | struct phy *devm_phy_get(struct device *dev, const char *string); | 150 | struct phy *devm_phy_get(struct device *dev, const char *string); |
151 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); | 151 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); |
152 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, | ||
153 | const char *con_id); | ||
152 | void phy_put(struct phy *phy); | 154 | void phy_put(struct phy *phy); |
153 | void devm_phy_put(struct device *dev, struct phy *phy); | 155 | void devm_phy_put(struct device *dev, struct phy *phy); |
156 | struct phy *of_phy_get(struct device_node *np, const char *con_id); | ||
154 | struct phy *of_phy_simple_xlate(struct device *dev, | 157 | struct phy *of_phy_simple_xlate(struct device *dev, |
155 | struct of_phandle_args *args); | 158 | struct of_phandle_args *args); |
156 | struct phy *phy_create(struct device *dev, const struct phy_ops *ops, | 159 | struct phy *phy_create(struct device *dev, const struct phy_ops *ops, |
@@ -251,6 +254,13 @@ static inline struct phy *devm_phy_optional_get(struct device *dev, | |||
251 | return ERR_PTR(-ENOSYS); | 254 | return ERR_PTR(-ENOSYS); |
252 | } | 255 | } |
253 | 256 | ||
257 | static inline struct phy *devm_of_phy_get(struct device *dev, | ||
258 | struct device_node *np, | ||
259 | const char *con_id) | ||
260 | { | ||
261 | return ERR_PTR(-ENOSYS); | ||
262 | } | ||
263 | |||
254 | static inline void phy_put(struct phy *phy) | 264 | static inline void phy_put(struct phy *phy) |
255 | { | 265 | { |
256 | } | 266 | } |
@@ -259,6 +269,11 @@ static inline void devm_phy_put(struct device *dev, struct phy *phy) | |||
259 | { | 269 | { |
260 | } | 270 | } |
261 | 271 | ||
272 | static inline struct phy *of_phy_get(struct device_node *np, const char *con_id) | ||
273 | { | ||
274 | return ERR_PTR(-ENOSYS); | ||
275 | } | ||
276 | |||
262 | static inline struct phy *of_phy_simple_xlate(struct device *dev, | 277 | static inline struct phy *of_phy_simple_xlate(struct device *dev, |
263 | struct of_phandle_args *args) | 278 | struct of_phandle_args *args) |
264 | { | 279 | { |
diff --git a/include/linux/usb.h b/include/linux/usb.h index b55600a1edc3..6b7ec376fb4d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -57,6 +57,7 @@ struct ep_device; | |||
57 | * @extra: descriptors following this endpoint in the configuration | 57 | * @extra: descriptors following this endpoint in the configuration |
58 | * @extralen: how many bytes of "extra" are valid | 58 | * @extralen: how many bytes of "extra" are valid |
59 | * @enabled: URBs may be submitted to this endpoint | 59 | * @enabled: URBs may be submitted to this endpoint |
60 | * @streams: number of USB-3 streams allocated on the endpoint | ||
60 | * | 61 | * |
61 | * USB requests are always queued to a given endpoint, identified by a | 62 | * USB requests are always queued to a given endpoint, identified by a |
62 | * descriptor within an active interface in a given USB configuration. | 63 | * descriptor within an active interface in a given USB configuration. |
@@ -71,6 +72,7 @@ struct usb_host_endpoint { | |||
71 | unsigned char *extra; /* Extra descriptors */ | 72 | unsigned char *extra; /* Extra descriptors */ |
72 | int extralen; | 73 | int extralen; |
73 | int enabled; | 74 | int enabled; |
75 | int streams; | ||
74 | }; | 76 | }; |
75 | 77 | ||
76 | /* host-side wrapper for one interface setting's parsed descriptors */ | 78 | /* host-side wrapper for one interface setting's parsed descriptors */ |
@@ -202,6 +204,8 @@ static inline void usb_set_intfdata(struct usb_interface *intf, void *data) | |||
202 | struct usb_interface *usb_get_intf(struct usb_interface *intf); | 204 | struct usb_interface *usb_get_intf(struct usb_interface *intf); |
203 | void usb_put_intf(struct usb_interface *intf); | 205 | void usb_put_intf(struct usb_interface *intf); |
204 | 206 | ||
207 | /* Hard limit */ | ||
208 | #define USB_MAXENDPOINTS 30 | ||
205 | /* this maximum is arbitrary */ | 209 | /* this maximum is arbitrary */ |
206 | #define USB_MAXINTERFACES 32 | 210 | #define USB_MAXINTERFACES 32 |
207 | #define USB_MAXIADS (USB_MAXINTERFACES/2) | 211 | #define USB_MAXIADS (USB_MAXINTERFACES/2) |
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 708bd119627f..bbe779f640be 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h | |||
@@ -25,6 +25,7 @@ struct ci_hdrc_platform_data { | |||
25 | */ | 25 | */ |
26 | #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4) | 26 | #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4) |
27 | #define CI_HDRC_IMX28_WRITE_FIX BIT(5) | 27 | #define CI_HDRC_IMX28_WRITE_FIX BIT(5) |
28 | #define CI_HDRC_FORCE_FULLSPEED BIT(6) | ||
28 | enum usb_dr_mode dr_mode; | 29 | enum usb_dr_mode dr_mode; |
29 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 | 30 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 |
30 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 | 31 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index efe8d8a7c7ad..485cd5e2100c 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -143,6 +143,7 @@ struct usb_hcd { | |||
143 | unsigned authorized_default:1; | 143 | unsigned authorized_default:1; |
144 | unsigned has_tt:1; /* Integrated TT in root hub */ | 144 | unsigned has_tt:1; /* Integrated TT in root hub */ |
145 | unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ | 145 | unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ |
146 | unsigned can_do_streams:1; /* HC supports streams */ | ||
146 | 147 | ||
147 | unsigned int irq; /* irq allocated */ | 148 | unsigned int irq; /* irq allocated */ |
148 | void __iomem *regs; /* device memory/io */ | 149 | void __iomem *regs; /* device memory/io */ |
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 6c0b1c513db7..353053a33f21 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h | |||
@@ -111,6 +111,13 @@ struct usb_phy { | |||
111 | int (*set_suspend)(struct usb_phy *x, | 111 | int (*set_suspend)(struct usb_phy *x, |
112 | int suspend); | 112 | int suspend); |
113 | 113 | ||
114 | /* | ||
115 | * Set wakeup enable for PHY, in that case, the PHY can be | ||
116 | * woken up from suspend status due to external events, | ||
117 | * like vbus change, dp/dm change and id. | ||
118 | */ | ||
119 | int (*set_wakeup)(struct usb_phy *x, bool enabled); | ||
120 | |||
114 | /* notify phy connect status change */ | 121 | /* notify phy connect status change */ |
115 | int (*notify_connect)(struct usb_phy *x, | 122 | int (*notify_connect)(struct usb_phy *x, |
116 | enum usb_device_speed speed); | 123 | enum usb_device_speed speed); |
@@ -265,6 +272,15 @@ usb_phy_set_suspend(struct usb_phy *x, int suspend) | |||
265 | } | 272 | } |
266 | 273 | ||
267 | static inline int | 274 | static inline int |
275 | usb_phy_set_wakeup(struct usb_phy *x, bool enabled) | ||
276 | { | ||
277 | if (x && x->set_wakeup) | ||
278 | return x->set_wakeup(x, enabled); | ||
279 | else | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static inline int | ||
268 | usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) | 284 | usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) |
269 | { | 285 | { |
270 | if (x && x->notify_connect) | 286 | if (x && x->notify_connect) |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 704a1ab8240c..9bb547c7bce7 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -190,7 +190,8 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) | |||
190 | * @num_ports: the number of different ports this device will have. | 190 | * @num_ports: the number of different ports this device will have. |
191 | * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer | 191 | * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer |
192 | * (0 = end-point size) | 192 | * (0 = end-point size) |
193 | * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) | 193 | * @bulk_out_size: minimum number of bytes to allocate for bulk-out buffer |
194 | * (0 = end-point size) | ||
194 | * @calc_num_ports: pointer to a function to determine how many ports this | 195 | * @calc_num_ports: pointer to a function to determine how many ports this |
195 | * device has dynamically. It will be called after the probe() | 196 | * device has dynamically. It will be called after the probe() |
196 | * callback is called, but before attach() | 197 | * callback is called, but before attach() |
diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h index 5499ab5c94bd..3fc8e8b9f043 100644 --- a/include/linux/usb/uas.h +++ b/include/linux/usb/uas.h | |||
@@ -9,7 +9,7 @@ struct iu { | |||
9 | __u8 iu_id; | 9 | __u8 iu_id; |
10 | __u8 rsvd1; | 10 | __u8 rsvd1; |
11 | __be16 tag; | 11 | __be16 tag; |
12 | }; | 12 | } __attribute__((__packed__)); |
13 | 13 | ||
14 | enum { | 14 | enum { |
15 | IU_ID_COMMAND = 0x01, | 15 | IU_ID_COMMAND = 0x01, |
@@ -52,7 +52,7 @@ struct command_iu { | |||
52 | __u8 rsvd7; | 52 | __u8 rsvd7; |
53 | struct scsi_lun lun; | 53 | struct scsi_lun lun; |
54 | __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ | 54 | __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ |
55 | }; | 55 | } __attribute__((__packed__)); |
56 | 56 | ||
57 | struct task_mgmt_iu { | 57 | struct task_mgmt_iu { |
58 | __u8 iu_id; | 58 | __u8 iu_id; |
@@ -62,7 +62,7 @@ struct task_mgmt_iu { | |||
62 | __u8 rsvd2; | 62 | __u8 rsvd2; |
63 | __be16 task_tag; | 63 | __be16 task_tag; |
64 | struct scsi_lun lun; | 64 | struct scsi_lun lun; |
65 | }; | 65 | } __attribute__((__packed__)); |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * Also used for the Read Ready and Write Ready IUs since they have the | 68 | * Also used for the Read Ready and Write Ready IUs since they have the |
@@ -77,15 +77,15 @@ struct sense_iu { | |||
77 | __u8 rsvd7[7]; | 77 | __u8 rsvd7[7]; |
78 | __be16 len; | 78 | __be16 len; |
79 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; | 79 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; |
80 | }; | 80 | } __attribute__((__packed__)); |
81 | 81 | ||
82 | struct response_ui { | 82 | struct response_iu { |
83 | __u8 iu_id; | 83 | __u8 iu_id; |
84 | __u8 rsvd1; | 84 | __u8 rsvd1; |
85 | __be16 tag; | 85 | __be16 tag; |
86 | __be16 add_response_info; | 86 | __u8 add_response_info[3]; |
87 | __u8 response_code; | 87 | __u8 response_code; |
88 | }; | 88 | } __attribute__((__packed__)); |
89 | 89 | ||
90 | struct usb_pipe_usage_descriptor { | 90 | struct usb_pipe_usage_descriptor { |
91 | __u8 bLength; | 91 | __u8 bLength; |
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 630356866030..1a64b26046ed 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h | |||
@@ -67,8 +67,10 @@ | |||
67 | /* Initial READ(10) (and others) must be retried */ \ | 67 | /* Initial READ(10) (and others) must be retried */ \ |
68 | US_FLAG(WRITE_CACHE, 0x00200000) \ | 68 | US_FLAG(WRITE_CACHE, 0x00200000) \ |
69 | /* Write Cache status is not available */ \ | 69 | /* Write Cache status is not available */ \ |
70 | US_FLAG(NEEDS_CAP16, 0x00400000) | 70 | US_FLAG(NEEDS_CAP16, 0x00400000) \ |
71 | /* cannot handle READ_CAPACITY_10 */ | 71 | /* cannot handle READ_CAPACITY_10 */ \ |
72 | US_FLAG(IGNORE_UAS, 0x00800000) \ | ||
73 | /* Device advertises UAS but it is broken */ | ||
72 | 74 | ||
73 | #define US_FLAG(name, value) US_FL_##name = value , | 75 | #define US_FLAG(name, value) US_FL_##name = value , |
74 | enum { US_DO_ALL_FLAGS }; | 76 | enum { US_DO_ALL_FLAGS }; |
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h index d6b01283f85c..2a4b4a72a4f9 100644 --- a/include/uapi/linux/usb/functionfs.h +++ b/include/uapi/linux/usb/functionfs.h | |||
@@ -10,9 +10,15 @@ | |||
10 | 10 | ||
11 | enum { | 11 | enum { |
12 | FUNCTIONFS_DESCRIPTORS_MAGIC = 1, | 12 | FUNCTIONFS_DESCRIPTORS_MAGIC = 1, |
13 | FUNCTIONFS_STRINGS_MAGIC = 2 | 13 | FUNCTIONFS_STRINGS_MAGIC = 2, |
14 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 = 3, | ||
14 | }; | 15 | }; |
15 | 16 | ||
17 | enum functionfs_flags { | ||
18 | FUNCTIONFS_HAS_FS_DESC = 1, | ||
19 | FUNCTIONFS_HAS_HS_DESC = 2, | ||
20 | FUNCTIONFS_HAS_SS_DESC = 4, | ||
21 | }; | ||
16 | 22 | ||
17 | #ifndef __KERNEL__ | 23 | #ifndef __KERNEL__ |
18 | 24 | ||
@@ -29,29 +35,39 @@ struct usb_endpoint_descriptor_no_audio { | |||
29 | 35 | ||
30 | 36 | ||
31 | /* | 37 | /* |
32 | * All numbers must be in little endian order. | ||
33 | */ | ||
34 | |||
35 | struct usb_functionfs_descs_head { | ||
36 | __le32 magic; | ||
37 | __le32 length; | ||
38 | __le32 fs_count; | ||
39 | __le32 hs_count; | ||
40 | } __attribute__((packed)); | ||
41 | |||
42 | /* | ||
43 | * Descriptors format: | 38 | * Descriptors format: |
44 | * | 39 | * |
45 | * | off | name | type | description | | 40 | * | off | name | type | description | |
46 | * |-----+-----------+--------------+--------------------------------------| | 41 | * |-----+-----------+--------------+--------------------------------------| |
47 | * | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC | | 42 | * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 | |
43 | * | 4 | length | LE32 | length of the whole data chunk | | ||
44 | * | 8 | flags | LE32 | combination of functionfs_flags | | ||
45 | * | | fs_count | LE32 | number of full-speed descriptors | | ||
46 | * | | hs_count | LE32 | number of high-speed descriptors | | ||
47 | * | | ss_count | LE32 | number of super-speed descriptors | | ||
48 | * | | fs_descrs | Descriptor[] | list of full-speed descriptors | | ||
49 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | | ||
50 | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | | ||
51 | * | ||
52 | * Depending on which flags are set, various fields may be missing in the | ||
53 | * structure. Any flags that are not recognised cause the whole block to be | ||
54 | * rejected with -ENOSYS. | ||
55 | * | ||
56 | * Legacy descriptors format: | ||
57 | * | ||
58 | * | off | name | type | description | | ||
59 | * |-----+-----------+--------------+--------------------------------------| | ||
60 | * | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC | | ||
48 | * | 4 | length | LE32 | length of the whole data chunk | | 61 | * | 4 | length | LE32 | length of the whole data chunk | |
49 | * | 8 | fs_count | LE32 | number of full-speed descriptors | | 62 | * | 8 | fs_count | LE32 | number of full-speed descriptors | |
50 | * | 12 | hs_count | LE32 | number of high-speed descriptors | | 63 | * | 12 | hs_count | LE32 | number of high-speed descriptors | |
51 | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | | 64 | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | |
52 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | | 65 | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | |
53 | * | 66 | * |
54 | * descs are just valid USB descriptors and have the following format: | 67 | * All numbers must be in little endian order. |
68 | * | ||
69 | * Descriptor[] is an array of valid USB descriptors which have the following | ||
70 | * format: | ||
55 | * | 71 | * |
56 | * | off | name | type | description | | 72 | * | off | name | type | description | |
57 | * |-----+-----------------+------+--------------------------| | 73 | * |-----+-----------------+------+--------------------------| |
diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h index 0c65e4b12617..abe5f4bd4d82 100644 --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h | |||
@@ -102,7 +102,10 @@ struct usbdevfs_urb { | |||
102 | int buffer_length; | 102 | int buffer_length; |
103 | int actual_length; | 103 | int actual_length; |
104 | int start_frame; | 104 | int start_frame; |
105 | int number_of_packets; | 105 | union { |
106 | int number_of_packets; /* Only used for isoc urbs */ | ||
107 | unsigned int stream_id; /* Only used with bulk streams */ | ||
108 | }; | ||
106 | int error_count; | 109 | int error_count; |
107 | unsigned int signr; /* signal to be sent on completion, | 110 | unsigned int signr; /* signal to be sent on completion, |
108 | or 0 if none should be sent. */ | 111 | or 0 if none should be sent. */ |
@@ -144,6 +147,11 @@ struct usbdevfs_disconnect_claim { | |||
144 | char driver[USBDEVFS_MAXDRIVERNAME + 1]; | 147 | char driver[USBDEVFS_MAXDRIVERNAME + 1]; |
145 | }; | 148 | }; |
146 | 149 | ||
150 | struct usbdevfs_streams { | ||
151 | unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */ | ||
152 | unsigned int num_eps; | ||
153 | unsigned char eps[0]; | ||
154 | }; | ||
147 | 155 | ||
148 | #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) | 156 | #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) |
149 | #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) | 157 | #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) |
@@ -176,5 +184,7 @@ struct usbdevfs_disconnect_claim { | |||
176 | #define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int) | 184 | #define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int) |
177 | #define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32) | 185 | #define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32) |
178 | #define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim) | 186 | #define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim) |
187 | #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams) | ||
188 | #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams) | ||
179 | 189 | ||
180 | #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ | 190 | #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ |