diff options
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 */ |
