diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:59:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:59:26 -0400 |
commit | 2a298679b41199ae742a77ce69766385dffe816f (patch) | |
tree | 93a23c0d828ccca7053f604dbfcdd4d3278972b3 | |
parent | 8c7febe83915332276cab49e89f6580bb963fb9a (diff) | |
parent | 50641056d833813b71b0ad51823f7ded8dd62e7f (diff) |
Merge tag 'usb-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH:
"Here's the big USB patchset for 4.2-rc1. As is normal these days, the
majority of changes are in the gadget drivers, with a bunch of other
small driver changes.
All of these have been in linux-next with no reported issues"
* tag 'usb-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (175 commits)
usb: dwc3: Use ASCII space in Kconfig
usb: chipidea: add work-around for Marvell HSIC PHY startup
usb: chipidea: allow multiple instances to use default ci_default_pdata
dt-bindings: Consolidate ChipIdea USB ci13xxx bindings
phy: add Marvell HSIC 28nm PHY
phy: Add Marvell USB 2.0 OTG 28nm PHY
dt-bindings: Add Marvell PXA1928 USB and HSIC PHY bindings
USB: ssb: use devm_kzalloc
USB: ssb: fix error handling in ssb_hcd_create_pdev()
usb: isp1760: check for null return from kzalloc
cdc-acm: Add support of ATOL FPrint fiscal printers
usb: chipidea: usbmisc_imx: Remove unneeded semicolon
USB: usbtmc: add device quirk for Rigol DS6104
USB: serial: mos7840: Use setup_timer
phy: twl4030-usb: add ABI documentation
phy: twl4030-usb: remove incorrect pm_runtime_get_sync() in probe function.
phy: twl4030-usb: remove pointless 'suspended' test in 'suspend' callback.
phy: twl4030-usb: make runtime pm more reliable.
drivers:usb:fsl: Fix compilation error for fsl ehci drv
usb: renesas_usbhs: Don't disable the pipe if Control write status stage
...
180 files changed, 5630 insertions, 2330 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-twl4030-usb b/Documentation/ABI/testing/sysfs-platform-twl4030-usb new file mode 100644 index 000000000000..512c51be64ae --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-twl4030-usb | |||
@@ -0,0 +1,8 @@ | |||
1 | What: /sys/bus/platform/devices/*twl4030-usb/vbus | ||
2 | Description: | ||
3 | Read-only status reporting if VBUS (approx 5V) | ||
4 | is being supplied by the USB bus. | ||
5 | |||
6 | Possible values: "on", "off". | ||
7 | |||
8 | Changes are notified via select/poll. | ||
diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt new file mode 100644 index 000000000000..7f81ef90146a --- /dev/null +++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | * Broadcom SATA3 PHY for STB | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be one or more of | ||
5 | "brcm,bcm7445-sata-phy" | ||
6 | "brcm,phy-sata3" | ||
7 | - address-cells: should be 1 | ||
8 | - size-cells: should be 0 | ||
9 | - reg: register range for the PHY PCB interface | ||
10 | - reg-names: should be "phy" | ||
11 | |||
12 | Sub-nodes: | ||
13 | Each port's PHY should be represented as a sub-node. | ||
14 | |||
15 | Sub-nodes required properties: | ||
16 | - reg: the PHY number | ||
17 | - phy-cells: generic PHY binding; must be 0 | ||
18 | Optional: | ||
19 | - brcm,enable-ssc: use spread spectrum clocking (SSC) on this port | ||
20 | |||
21 | |||
22 | Example: | ||
23 | |||
24 | sata-phy@f0458100 { | ||
25 | compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3"; | ||
26 | reg = <0xf0458100 0x1e00>, <0xf045804c 0x10>; | ||
27 | reg-names = "phy"; | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <0>; | ||
30 | |||
31 | sata-phy@0 { | ||
32 | reg = <0>; | ||
33 | #phy-cells = <0>; | ||
34 | }; | ||
35 | |||
36 | sata-phy@1 { | ||
37 | reg = <1>; | ||
38 | #phy-cells = <0>; | ||
39 | }; | ||
40 | }; | ||
diff --git a/Documentation/devicetree/bindings/phy/pxa1928-usb-phy.txt b/Documentation/devicetree/bindings/phy/pxa1928-usb-phy.txt new file mode 100644 index 000000000000..660a13ca90b3 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/pxa1928-usb-phy.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Marvell PXA1928 USB and HSIC PHYs | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "marvell,pxa1928-usb-phy" or "marvell,pxa1928-hsic-phy" | ||
5 | - reg: base address and length of the registers | ||
6 | - clocks - A single clock. From common clock binding. | ||
7 | - #phys-cells: should be 0. From commmon phy binding. | ||
8 | - resets: reference to the reset controller | ||
9 | |||
10 | Example: | ||
11 | |||
12 | usbphy: phy@7000 { | ||
13 | compatible = "marvell,pxa1928-usb-phy"; | ||
14 | reg = <0x7000 0xe0>; | ||
15 | clocks = <&apmu_clocks PXA1928_CLK_USB>; | ||
16 | #phy-cells = <0>; | ||
17 | }; | ||
18 | |||
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt index 00fc52a034b7..d564ba4f1cf6 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt | |||
@@ -6,6 +6,7 @@ This file provides information on what the device node for the R-Car generation | |||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC. | 7 | - compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC. |
8 | "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC. | 8 | "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC. |
9 | "renesas,usb-phy-r8a7794" if the device is a part of R8A7794 SoC. | ||
9 | - reg: offset and length of the register block. | 10 | - reg: offset and length of the register block. |
10 | - #address-cells: number of address cells for the USB channel subnodes, must | 11 | - #address-cells: number of address cells for the USB channel subnodes, must |
11 | be <1>. | 12 | be <1>. |
diff --git a/Documentation/devicetree/bindings/power/twl-charger.txt b/Documentation/devicetree/bindings/power/twl-charger.txt index d5c706216df5..3b4ea1b73b38 100644 --- a/Documentation/devicetree/bindings/power/twl-charger.txt +++ b/Documentation/devicetree/bindings/power/twl-charger.txt | |||
@@ -1,5 +1,15 @@ | |||
1 | TWL BCI (Battery Charger Interface) | 1 | TWL BCI (Battery Charger Interface) |
2 | 2 | ||
3 | The battery charger needs to interact with the USB phy in order | ||
4 | to know when charging is permissible, and when there is a connection | ||
5 | or disconnection. | ||
6 | |||
7 | The choice of phy cannot be configured at a hardware level, so there | ||
8 | is no value in explicit configuration in device-tree. Rather | ||
9 | if there is a sibling of the BCI node which is compatible with | ||
10 | "ti,twl4030-usb", then that is used to determine when and how | ||
11 | use USB power for charging. | ||
12 | |||
3 | Required properties: | 13 | Required properties: |
4 | - compatible: | 14 | - compatible: |
5 | - "ti,twl4030-bci" | 15 | - "ti,twl4030-bci" |
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt deleted file mode 100644 index 38a548001e3a..000000000000 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | * Freescale i.MX ci13xxx usb controllers | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "fsl,imx27-usb" | ||
5 | - reg: Should contain registers location and length | ||
6 | - interrupts: Should contain controller interrupt | ||
7 | - fsl,usbphy: phandle of usb phy that connects to the port | ||
8 | |||
9 | Recommended properies: | ||
10 | - phy_type: the type of the phy connected to the core. Should be one | ||
11 | of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this | ||
12 | property the PORTSC register won't be touched | ||
13 | - dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg" | ||
14 | |||
15 | Optional properties: | ||
16 | - fsl,usbmisc: phandler of non-core register device, with one argument | ||
17 | that indicate usb controller index | ||
18 | - vbus-supply: regulator for vbus | ||
19 | - disable-over-current: disable over current detect | ||
20 | - external-vbus-divider: enables off-chip resistor divider for Vbus | ||
21 | - maximum-speed: limit the maximum connection speed to "full-speed". | ||
22 | - tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts | ||
23 | |||
24 | Examples: | ||
25 | usb@02184000 { /* USB OTG */ | ||
26 | compatible = "fsl,imx6q-usb", "fsl,imx27-usb"; | ||
27 | reg = <0x02184000 0x200>; | ||
28 | interrupts = <0 43 0x04>; | ||
29 | fsl,usbphy = <&usbphy1>; | ||
30 | fsl,usbmisc = <&usbmisc 0>; | ||
31 | disable-over-current; | ||
32 | external-vbus-divider; | ||
33 | maximum-speed = "full-speed"; | ||
34 | tpl-support; | ||
35 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt deleted file mode 100644 index f2899b550939..000000000000 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-qcom.txt +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | Qualcomm CI13xxx (Chipidea) USB controllers | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should contain "qcom,ci-hdrc" | ||
5 | - reg: offset and length of the register set in the memory map | ||
6 | - interrupts: interrupt-specifier for the controller interrupt. | ||
7 | - usb-phy: phandle for the PHY device | ||
8 | - dr_mode: Should be "peripheral" | ||
9 | |||
10 | Examples: | ||
11 | gadget@f9a55000 { | ||
12 | compatible = "qcom,ci-hdrc"; | ||
13 | reg = <0xf9a55000 0x400>; | ||
14 | dr_mode = "peripheral"; | ||
15 | interrupts = <0 134 0>; | ||
16 | usb-phy = <&usbphy0>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt index 27f8b1e5ee46..553e2fae3a76 100644 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | |||
@@ -1,15 +1,35 @@ | |||
1 | * USB2 ChipIdea USB controller for ci13xxx | 1 | * USB2 ChipIdea USB controller for ci13xxx |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: should be "chipidea,usb2" | 4 | - compatible: should be one of: |
5 | "fsl,imx27-usb" | ||
6 | "lsi,zevio-usb" | ||
7 | "qcom,ci-hdrc" | ||
8 | "chipidea,usb2" | ||
5 | - reg: base address and length of the registers | 9 | - reg: base address and length of the registers |
6 | - interrupts: interrupt for the USB controller | 10 | - interrupts: interrupt for the USB controller |
7 | 11 | ||
12 | Recommended properies: | ||
13 | - phy_type: the type of the phy connected to the core. Should be one | ||
14 | of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this | ||
15 | property the PORTSC register won't be touched. | ||
16 | - dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg" | ||
17 | |||
18 | Deprecated properties: | ||
19 | - usb-phy: phandle for the PHY device. Use "phys" instead. | ||
20 | - fsl,usbphy: phandle of usb phy that connects to the port. Use "phys" instead. | ||
21 | |||
8 | Optional properties: | 22 | Optional properties: |
9 | - clocks: reference to the USB clock | 23 | - clocks: reference to the USB clock |
10 | - phys: reference to the USB PHY | 24 | - phys: reference to the USB PHY |
11 | - phy-names: should be "usb-phy" | 25 | - phy-names: should be "usb-phy" |
12 | - vbus-supply: reference to the VBUS regulator | 26 | - vbus-supply: reference to the VBUS regulator |
27 | - maximum-speed: limit the maximum connection speed to "full-speed". | ||
28 | - tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts | ||
29 | - fsl,usbmisc: (FSL only) phandler of non-core register device, with one | ||
30 | argument that indicate usb controller index | ||
31 | - disable-over-current: (FSL only) disable over current detect | ||
32 | - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus | ||
13 | 33 | ||
14 | Example: | 34 | Example: |
15 | 35 | ||
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt deleted file mode 100644 index abbcb2aea38c..000000000000 --- a/Documentation/devicetree/bindings/usb/ci-hdrc-zevio.txt +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
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-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index f9d70252bbb2..01c71b1258f4 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt | |||
@@ -49,8 +49,7 @@ st_dwc3: dwc3@8f94000 { | |||
49 | st,syscfg = <&syscfg_core>; | 49 | st,syscfg = <&syscfg_core>; |
50 | resets = <&powerdown STIH407_USB3_POWERDOWN>, | 50 | resets = <&powerdown STIH407_USB3_POWERDOWN>, |
51 | <&softreset STIH407_MIPHY2_SOFTRESET>; | 51 | <&softreset STIH407_MIPHY2_SOFTRESET>; |
52 | reset-names = "powerdown", | 52 | reset-names = "powerdown", "softreset"; |
53 | "softreset"; | ||
54 | #address-cells = <1>; | 53 | #address-cells = <1>; |
55 | #size-cells = <1>; | 54 | #size-cells = <1>; |
56 | pinctrl-names = "default"; | 55 | pinctrl-names = "default"; |
@@ -62,7 +61,7 @@ st_dwc3: dwc3@8f94000 { | |||
62 | reg = <0x09900000 0x100000>; | 61 | reg = <0x09900000 0x100000>; |
63 | interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>; | 62 | interrupts = <GIC_SPI 155 IRQ_TYPE_NONE>; |
64 | dr_mode = "host"; | 63 | dr_mode = "host"; |
65 | phys-names = "usb2-phy", "usb3-phy"; | 64 | phy-names = "usb2-phy", "usb3-phy"; |
66 | phys = <&usb2_picophy2>, <&phy_port2 MIPHY_TYPE_USB>; | 65 | phys = <&usb2_picophy2>, <&phy_port2 PHY_TYPE_USB3>; |
67 | }; | 66 | }; |
68 | }; | 67 | }; |
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 5cc364309edb..0815eac5b185 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt | |||
@@ -38,6 +38,8 @@ Optional properties: | |||
38 | - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal | 38 | - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal |
39 | utmi_l1_suspend_n, false when asserts utmi_sleep_n | 39 | utmi_l1_suspend_n, false when asserts utmi_sleep_n |
40 | - snps,hird-threshold: HIRD threshold | 40 | - snps,hird-threshold: HIRD threshold |
41 | - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for | ||
42 | UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3. | ||
41 | 43 | ||
42 | This is usually a subnode to DWC3 glue to which it is connected. | 44 | This is usually a subnode to DWC3 glue to which it is connected. |
43 | 45 | ||
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index 2826f2af503a..bd8d9e753029 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt | |||
@@ -69,6 +69,17 @@ Optional properties: | |||
69 | (no, min, max) where each value represents either a voltage | 69 | (no, min, max) where each value represents either a voltage |
70 | in microvolts or a value corresponding to voltage corner. | 70 | in microvolts or a value corresponding to voltage corner. |
71 | 71 | ||
72 | - qcom,manual-pullup: If present, vbus is not routed to USB controller/phy | ||
73 | and controller driver therefore enables pull-up explicitly | ||
74 | before starting controller using usbcmd run/stop bit. | ||
75 | |||
76 | - extcon: phandles to external connector devices. First phandle | ||
77 | should point to external connector, which provide "USB" | ||
78 | cable events, the second should point to external connector | ||
79 | device, which provide "USB-HOST" cable events. If one of | ||
80 | the external connector devices is not required empty <0> | ||
81 | phandle should be specified. | ||
82 | |||
72 | Example HSUSB OTG controller device node: | 83 | Example HSUSB OTG controller device node: |
73 | 84 | ||
74 | usb@f9a55000 { | 85 | usb@f9a55000 { |
diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index ddbe304beb21..64a4ca6cf96f 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt | |||
@@ -4,6 +4,7 @@ Required properties: | |||
4 | - compatible: Must contain one of the following: | 4 | - compatible: Must contain one of the following: |
5 | - "renesas,usbhs-r8a7790" | 5 | - "renesas,usbhs-r8a7790" |
6 | - "renesas,usbhs-r8a7791" | 6 | - "renesas,usbhs-r8a7791" |
7 | - "renesas,usbhs-r8a7794" | ||
7 | - reg: Base address and length of the register for the USBHS | 8 | - reg: Base address and length of the register for the USBHS |
8 | - interrupts: Interrupt specifier for the USBHS | 9 | - interrupts: Interrupt specifier for the USBHS |
9 | - clocks: A list of phandle + clock specifier pairs | 10 | - clocks: A list of phandle + clock specifier pairs |
diff --git a/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt b/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt index 0aee0ad3f035..17327a296110 100644 --- a/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt +++ b/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt | |||
@@ -30,6 +30,9 @@ TWL4030 USB PHY AND COMPARATOR | |||
30 | - usb_mode : The mode used by the phy to connect to the controller. "1" | 30 | - usb_mode : The mode used by the phy to connect to the controller. "1" |
31 | specifies "ULPI" mode and "2" specifies "CEA2011_3PIN" mode. | 31 | specifies "ULPI" mode and "2" specifies "CEA2011_3PIN" mode. |
32 | 32 | ||
33 | If a sibling node is compatible "ti,twl4030-bci", then it will find | ||
34 | this device and query it for USB power status. | ||
35 | |||
33 | twl4030-usb { | 36 | twl4030-usb { |
34 | compatible = "ti,twl4030-usb"; | 37 | compatible = "ti,twl4030-usb"; |
35 | interrupts = < 10 4 >; | 38 | interrupts = < 10 4 >; |
diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index 0b04fdff9d5a..a12d6012a40f 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt | |||
@@ -13,6 +13,8 @@ Optional properties: | |||
13 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors | 13 | - big-endian-desc : boolean, set this for hcds with big-endian descriptors |
14 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc | 14 | - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc |
15 | - needs-reset-on-resume : boolean, set this to force EHCI reset after resume | 15 | - needs-reset-on-resume : boolean, set this to force EHCI reset after resume |
16 | - has-transaction-translator : boolean, set this if EHCI have a Transaction | ||
17 | Translator built into the root hub. | ||
16 | - clocks : a list of phandle + clock specifier pairs | 18 | - clocks : a list of phandle + clock specifier pairs |
17 | - phys : phandle + phy specifier pair | 19 | - phys : phandle + phy specifier pair |
18 | - phy-names : "usb" | 20 | - phy-names : "usb" |
diff --git a/Documentation/phy.txt b/Documentation/phy.txt index 371361c69a4b..b388c5af9e72 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt | |||
@@ -76,6 +76,8 @@ struct phy *phy_get(struct device *dev, const char *string); | |||
76 | struct phy *phy_optional_get(struct device *dev, const char *string); | 76 | struct phy *phy_optional_get(struct device *dev, const char *string); |
77 | struct phy *devm_phy_get(struct device *dev, const char *string); | 77 | struct phy *devm_phy_get(struct device *dev, const char *string); |
78 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); | 78 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); |
79 | struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, | ||
80 | int index); | ||
79 | 81 | ||
80 | phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can | 82 | phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can |
81 | be used to get the PHY. In the case of dt boot, the string arguments | 83 | be used to get the PHY. In the case of dt boot, the string arguments |
@@ -86,7 +88,10 @@ successful PHY get. On driver detach, release function is invoked on | |||
86 | the the devres data and devres data is freed. phy_optional_get and | 88 | the the devres data and devres data is freed. phy_optional_get and |
87 | devm_phy_optional_get should be used when the phy is optional. These | 89 | devm_phy_optional_get should be used when the phy is optional. These |
88 | two functions will never return -ENODEV, but instead returns NULL when | 90 | two functions will never return -ENODEV, but instead returns NULL when |
89 | the phy cannot be found. | 91 | the phy cannot be found.Some generic drivers, such as ehci, may use multiple |
92 | phys and for such drivers referencing phy(s) by name(s) does not make sense. In | ||
93 | this case, devm_of_phy_get_by_index can be used to get a phy reference based on | ||
94 | the index. | ||
90 | 95 | ||
91 | It should be noted that NULL is a valid phy reference. All phy | 96 | It should be noted that NULL is a valid phy reference. All phy |
92 | consumer calls on the NULL phy become NOPs. That is the release calls, | 97 | consumer calls on the NULL phy become NOPs. That is the release calls, |
diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index f45b2bf4b41d..592678009c15 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt | |||
@@ -526,8 +526,6 @@ Except for ifname they can be written to until the function is linked to a | |||
526 | configuration. The ifname is read-only and contains the name of the interface | 526 | configuration. The ifname is read-only and contains the name of the interface |
527 | which was assigned by the net core, e. g. usb0. | 527 | which was assigned by the net core, e. g. usb0. |
528 | 528 | ||
529 | By default there can be only 1 RNDIS interface in the system. | ||
530 | |||
531 | Testing the RNDIS function | 529 | Testing the RNDIS function |
532 | -------------------------- | 530 | -------------------------- |
533 | 531 | ||
@@ -629,7 +627,7 @@ Function-specific configfs interface | |||
629 | The function name to use when creating the function directory is "uac2". | 627 | The function name to use when creating the function directory is "uac2". |
630 | The uac2 function provides these attributes in its function directory: | 628 | The uac2 function provides these attributes in its function directory: |
631 | 629 | ||
632 | chmask - capture channel mask | 630 | c_chmask - capture channel mask |
633 | c_srate - capture sampling rate | 631 | c_srate - capture sampling rate |
634 | c_ssize - capture sample size (bytes) | 632 | c_ssize - capture sample size (bytes) |
635 | p_chmask - playback channel mask | 633 | p_chmask - playback channel mask |
diff --git a/MAINTAINERS b/MAINTAINERS index df6007824715..68457d869b61 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -10712,6 +10712,13 @@ S: Maintained | |||
10712 | F: Documentation/video4linux/zr364xx.txt | 10712 | F: Documentation/video4linux/zr364xx.txt |
10713 | F: drivers/media/usb/zr364xx/ | 10713 | F: drivers/media/usb/zr364xx/ |
10714 | 10714 | ||
10715 | ULPI BUS | ||
10716 | M: Heikki Krogerus <heikki.krogerus@linux.intel.com> | ||
10717 | L: linux-usb@vger.kernel.org | ||
10718 | S: Maintained | ||
10719 | F: drivers/usb/common/ulpi.c | ||
10720 | F: include/linux/ulpi/ | ||
10721 | |||
10715 | USER-MODE LINUX (UML) | 10722 | USER-MODE LINUX (UML) |
10716 | M: Jeff Dike <jdike@addtoit.com> | 10723 | M: Jeff Dike <jdike@addtoit.com> |
10717 | M: Richard Weinberger <richard@nod.at> | 10724 | M: Richard Weinberger <richard@nod.at> |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index fc9b9f0ea91e..487d057431cc 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -54,6 +54,26 @@ config PHY_EXYNOS_MIPI_VIDEO | |||
54 | Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P | 54 | Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P |
55 | and EXYNOS SoCs. | 55 | and EXYNOS SoCs. |
56 | 56 | ||
57 | config PHY_PXA_28NM_HSIC | ||
58 | tristate "Marvell USB HSIC 28nm PHY Driver" | ||
59 | select GENERIC_PHY | ||
60 | help | ||
61 | Enable this to support Marvell USB HSIC PHY driver for Marvell | ||
62 | SoC. This driver will do the PHY initialization and shutdown. | ||
63 | The PHY driver will be used by Marvell ehci driver. | ||
64 | |||
65 | To compile this driver as a module, choose M here. | ||
66 | |||
67 | config PHY_PXA_28NM_USB2 | ||
68 | tristate "Marvell USB 2.0 28nm PHY Driver" | ||
69 | select GENERIC_PHY | ||
70 | help | ||
71 | Enable this to support Marvell USB 2.0 PHY driver for Marvell | ||
72 | SoC. This driver will do the PHY initialization and shutdown. | ||
73 | The PHY driver will be used by Marvell udc/ehci/otg driver. | ||
74 | |||
75 | To compile this driver as a module, choose M here. | ||
76 | |||
57 | config PHY_MVEBU_SATA | 77 | config PHY_MVEBU_SATA |
58 | def_bool y | 78 | def_bool y |
59 | depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD | 79 | depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD |
@@ -313,4 +333,20 @@ config PHY_QCOM_UFS | |||
313 | help | 333 | help |
314 | Support for UFS PHY on QCOM chipsets. | 334 | Support for UFS PHY on QCOM chipsets. |
315 | 335 | ||
336 | config PHY_TUSB1210 | ||
337 | tristate "TI TUSB1210 ULPI PHY module" | ||
338 | depends on USB_ULPI_BUS | ||
339 | select GENERIC_PHY | ||
340 | help | ||
341 | Support for TI TUSB1210 USB ULPI PHY. | ||
342 | |||
343 | config PHY_BRCMSTB_SATA | ||
344 | tristate "Broadcom STB SATA PHY driver" | ||
345 | depends on ARCH_BRCMSTB | ||
346 | depends on OF | ||
347 | select GENERIC_PHY | ||
348 | help | ||
349 | Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs. | ||
350 | Likely useful only with CONFIG_SATA_BRCMSTB enabled. | ||
351 | |||
316 | endmenu | 352 | endmenu |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index f12625178780..42f58e95aff0 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -10,6 +10,8 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o | |||
10 | obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o | 10 | obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o |
11 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o | 11 | obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o |
12 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o | 12 | obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o |
13 | obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o | ||
14 | obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o | ||
13 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o | 15 | obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o |
14 | obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o | 16 | obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o |
15 | obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o | 17 | obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o |
@@ -40,3 +42,5 @@ obj-$(CONFIG_PHY_STIH41X_USB) += phy-stih41x-usb.o | |||
40 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o | 42 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o |
41 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o | 43 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o |
42 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o | 44 | obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o |
45 | obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o | ||
46 | obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.o | ||
diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c new file mode 100644 index 000000000000..b7e303d28caf --- /dev/null +++ b/drivers/phy/phy-brcmstb-sata.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * Broadcom SATA3 AHCI Controller PHY Driver | ||
3 | * | ||
4 | * Copyright © 2009-2015 Broadcom Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/phy/phy.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #define SATA_MDIO_BANK_OFFSET 0x23c | ||
28 | #define SATA_MDIO_REG_OFFSET(ofs) ((ofs) * 4) | ||
29 | #define SATA_MDIO_REG_SPACE_SIZE 0x1000 | ||
30 | #define SATA_MDIO_REG_LENGTH 0x1f00 | ||
31 | |||
32 | #define MAX_PORTS 2 | ||
33 | |||
34 | /* Register offset between PHYs in PCB space */ | ||
35 | #define SATA_MDIO_REG_SPACE_SIZE 0x1000 | ||
36 | |||
37 | struct brcm_sata_port { | ||
38 | int portnum; | ||
39 | struct phy *phy; | ||
40 | struct brcm_sata_phy *phy_priv; | ||
41 | bool ssc_en; | ||
42 | }; | ||
43 | |||
44 | struct brcm_sata_phy { | ||
45 | struct device *dev; | ||
46 | void __iomem *phy_base; | ||
47 | |||
48 | struct brcm_sata_port phys[MAX_PORTS]; | ||
49 | }; | ||
50 | |||
51 | enum sata_mdio_phy_regs_28nm { | ||
52 | PLL_REG_BANK_0 = 0x50, | ||
53 | PLL_REG_BANK_0_PLLCONTROL_0 = 0x81, | ||
54 | |||
55 | TXPMD_REG_BANK = 0x1a0, | ||
56 | TXPMD_CONTROL1 = 0x81, | ||
57 | TXPMD_CONTROL1_TX_SSC_EN_FRC = BIT(0), | ||
58 | TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL = BIT(1), | ||
59 | TXPMD_TX_FREQ_CTRL_CONTROL1 = 0x82, | ||
60 | TXPMD_TX_FREQ_CTRL_CONTROL2 = 0x83, | ||
61 | TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK = 0x3ff, | ||
62 | TXPMD_TX_FREQ_CTRL_CONTROL3 = 0x84, | ||
63 | TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK = 0x3ff, | ||
64 | }; | ||
65 | |||
66 | static inline void __iomem *brcm_sata_phy_base(struct brcm_sata_port *port) | ||
67 | { | ||
68 | struct brcm_sata_phy *priv = port->phy_priv; | ||
69 | |||
70 | return priv->phy_base + (port->portnum * SATA_MDIO_REG_SPACE_SIZE); | ||
71 | } | ||
72 | |||
73 | static void brcm_sata_mdio_wr(void __iomem *addr, u32 bank, u32 ofs, | ||
74 | u32 msk, u32 value) | ||
75 | { | ||
76 | u32 tmp; | ||
77 | |||
78 | writel(bank, addr + SATA_MDIO_BANK_OFFSET); | ||
79 | tmp = readl(addr + SATA_MDIO_REG_OFFSET(ofs)); | ||
80 | tmp = (tmp & msk) | value; | ||
81 | writel(tmp, addr + SATA_MDIO_REG_OFFSET(ofs)); | ||
82 | } | ||
83 | |||
84 | /* These defaults were characterized by H/W group */ | ||
85 | #define FMIN_VAL_DEFAULT 0x3df | ||
86 | #define FMAX_VAL_DEFAULT 0x3df | ||
87 | #define FMAX_VAL_SSC 0x83 | ||
88 | |||
89 | static void brcm_sata_cfg_ssc_28nm(struct brcm_sata_port *port) | ||
90 | { | ||
91 | void __iomem *base = brcm_sata_phy_base(port); | ||
92 | struct brcm_sata_phy *priv = port->phy_priv; | ||
93 | u32 tmp; | ||
94 | |||
95 | /* override the TX spread spectrum setting */ | ||
96 | tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC; | ||
97 | brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp); | ||
98 | |||
99 | /* set fixed min freq */ | ||
100 | brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2, | ||
101 | ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK, | ||
102 | FMIN_VAL_DEFAULT); | ||
103 | |||
104 | /* set fixed max freq depending on SSC config */ | ||
105 | if (port->ssc_en) { | ||
106 | dev_info(priv->dev, "enabling SSC on port %d\n", port->portnum); | ||
107 | tmp = FMAX_VAL_SSC; | ||
108 | } else { | ||
109 | tmp = FMAX_VAL_DEFAULT; | ||
110 | } | ||
111 | |||
112 | brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3, | ||
113 | ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp); | ||
114 | } | ||
115 | |||
116 | static int brcm_sata_phy_init(struct phy *phy) | ||
117 | { | ||
118 | struct brcm_sata_port *port = phy_get_drvdata(phy); | ||
119 | |||
120 | brcm_sata_cfg_ssc_28nm(port); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static struct phy_ops phy_ops_28nm = { | ||
126 | .init = brcm_sata_phy_init, | ||
127 | .owner = THIS_MODULE, | ||
128 | }; | ||
129 | |||
130 | static const struct of_device_id brcm_sata_phy_of_match[] = { | ||
131 | { .compatible = "brcm,bcm7445-sata-phy" }, | ||
132 | {}, | ||
133 | }; | ||
134 | MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match); | ||
135 | |||
136 | static int brcm_sata_phy_probe(struct platform_device *pdev) | ||
137 | { | ||
138 | struct device *dev = &pdev->dev; | ||
139 | struct device_node *dn = dev->of_node, *child; | ||
140 | struct brcm_sata_phy *priv; | ||
141 | struct resource *res; | ||
142 | struct phy_provider *provider; | ||
143 | int count = 0; | ||
144 | |||
145 | if (of_get_child_count(dn) == 0) | ||
146 | return -ENODEV; | ||
147 | |||
148 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
149 | if (!priv) | ||
150 | return -ENOMEM; | ||
151 | dev_set_drvdata(dev, priv); | ||
152 | priv->dev = dev; | ||
153 | |||
154 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); | ||
155 | priv->phy_base = devm_ioremap_resource(dev, res); | ||
156 | if (IS_ERR(priv->phy_base)) | ||
157 | return PTR_ERR(priv->phy_base); | ||
158 | |||
159 | for_each_available_child_of_node(dn, child) { | ||
160 | unsigned int id; | ||
161 | struct brcm_sata_port *port; | ||
162 | |||
163 | if (of_property_read_u32(child, "reg", &id)) { | ||
164 | dev_err(dev, "missing reg property in node %s\n", | ||
165 | child->name); | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | |||
169 | if (id >= MAX_PORTS) { | ||
170 | dev_err(dev, "invalid reg: %u\n", id); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | if (priv->phys[id].phy) { | ||
174 | dev_err(dev, "already registered port %u\n", id); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | port = &priv->phys[id]; | ||
179 | port->portnum = id; | ||
180 | port->phy_priv = priv; | ||
181 | port->phy = devm_phy_create(dev, child, &phy_ops_28nm); | ||
182 | port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc"); | ||
183 | if (IS_ERR(port->phy)) { | ||
184 | dev_err(dev, "failed to create PHY\n"); | ||
185 | return PTR_ERR(port->phy); | ||
186 | } | ||
187 | |||
188 | phy_set_drvdata(port->phy, port); | ||
189 | count++; | ||
190 | } | ||
191 | |||
192 | provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
193 | if (IS_ERR(provider)) { | ||
194 | dev_err(dev, "could not register PHY provider\n"); | ||
195 | return PTR_ERR(provider); | ||
196 | } | ||
197 | |||
198 | dev_info(dev, "registered %d port(s)\n", count); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static struct platform_driver brcm_sata_phy_driver = { | ||
204 | .probe = brcm_sata_phy_probe, | ||
205 | .driver = { | ||
206 | .of_match_table = brcm_sata_phy_of_match, | ||
207 | .name = "brcmstb-sata-phy", | ||
208 | } | ||
209 | }; | ||
210 | module_platform_driver(brcm_sata_phy_driver); | ||
211 | |||
212 | MODULE_DESCRIPTION("Broadcom STB SATA PHY driver"); | ||
213 | MODULE_LICENSE("GPL"); | ||
214 | MODULE_AUTHOR("Marc Carino"); | ||
215 | MODULE_AUTHOR("Brian Norris"); | ||
216 | MODULE_ALIAS("platform:phy-brcmstb-sata"); | ||
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 63bc12d7a73e..fc48fac003a6 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -367,13 +367,21 @@ static struct phy *_of_phy_get(struct device_node *np, int index) | |||
367 | phy_provider = of_phy_provider_lookup(args.np); | 367 | phy_provider = of_phy_provider_lookup(args.np); |
368 | if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { | 368 | if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { |
369 | phy = ERR_PTR(-EPROBE_DEFER); | 369 | phy = ERR_PTR(-EPROBE_DEFER); |
370 | goto err0; | 370 | goto out_unlock; |
371 | } | ||
372 | |||
373 | if (!of_device_is_available(args.np)) { | ||
374 | dev_warn(phy_provider->dev, "Requested PHY is disabled\n"); | ||
375 | phy = ERR_PTR(-ENODEV); | ||
376 | goto out_put_module; | ||
371 | } | 377 | } |
372 | 378 | ||
373 | phy = phy_provider->of_xlate(phy_provider->dev, &args); | 379 | phy = phy_provider->of_xlate(phy_provider->dev, &args); |
380 | |||
381 | out_put_module: | ||
374 | module_put(phy_provider->owner); | 382 | module_put(phy_provider->owner); |
375 | 383 | ||
376 | err0: | 384 | out_unlock: |
377 | mutex_unlock(&phy_provider_mutex); | 385 | mutex_unlock(&phy_provider_mutex); |
378 | of_node_put(args.np); | 386 | of_node_put(args.np); |
379 | 387 | ||
@@ -623,6 +631,38 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, | |||
623 | EXPORT_SYMBOL_GPL(devm_of_phy_get); | 631 | EXPORT_SYMBOL_GPL(devm_of_phy_get); |
624 | 632 | ||
625 | /** | 633 | /** |
634 | * devm_of_phy_get_by_index() - lookup and obtain a reference to a phy by index. | ||
635 | * @dev: device that requests this phy | ||
636 | * @np: node containing the phy | ||
637 | * @index: index of the phy | ||
638 | * | ||
639 | * Gets the phy using _of_phy_get(), and associates a device with it using | ||
640 | * devres. On driver detach, release function is invoked on the devres data, | ||
641 | * then, devres data is freed. | ||
642 | * | ||
643 | */ | ||
644 | struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, | ||
645 | int index) | ||
646 | { | ||
647 | struct phy **ptr, *phy; | ||
648 | |||
649 | ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
650 | if (!ptr) | ||
651 | return ERR_PTR(-ENOMEM); | ||
652 | |||
653 | phy = _of_phy_get(np, index); | ||
654 | if (!IS_ERR(phy)) { | ||
655 | *ptr = phy; | ||
656 | devres_add(dev, ptr); | ||
657 | } else { | ||
658 | devres_free(ptr); | ||
659 | } | ||
660 | |||
661 | return phy; | ||
662 | } | ||
663 | EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index); | ||
664 | |||
665 | /** | ||
626 | * phy_create() - create a new phy | 666 | * phy_create() - create a new phy |
627 | * @dev: device that is creating the new phy | 667 | * @dev: device that is creating the new phy |
628 | * @node: device node of the phy | 668 | * @node: device node of the phy |
@@ -651,16 +691,6 @@ struct phy *phy_create(struct device *dev, struct device_node *node, | |||
651 | goto free_phy; | 691 | goto free_phy; |
652 | } | 692 | } |
653 | 693 | ||
654 | /* phy-supply */ | ||
655 | phy->pwr = regulator_get_optional(dev, "phy"); | ||
656 | if (IS_ERR(phy->pwr)) { | ||
657 | if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) { | ||
658 | ret = -EPROBE_DEFER; | ||
659 | goto free_ida; | ||
660 | } | ||
661 | phy->pwr = NULL; | ||
662 | } | ||
663 | |||
664 | device_initialize(&phy->dev); | 694 | device_initialize(&phy->dev); |
665 | mutex_init(&phy->mutex); | 695 | mutex_init(&phy->mutex); |
666 | 696 | ||
@@ -674,6 +704,16 @@ struct phy *phy_create(struct device *dev, struct device_node *node, | |||
674 | if (ret) | 704 | if (ret) |
675 | goto put_dev; | 705 | goto put_dev; |
676 | 706 | ||
707 | /* phy-supply */ | ||
708 | phy->pwr = regulator_get_optional(&phy->dev, "phy"); | ||
709 | if (IS_ERR(phy->pwr)) { | ||
710 | ret = PTR_ERR(phy->pwr); | ||
711 | if (ret == -EPROBE_DEFER) | ||
712 | goto put_dev; | ||
713 | |||
714 | phy->pwr = NULL; | ||
715 | } | ||
716 | |||
677 | ret = device_add(&phy->dev); | 717 | ret = device_add(&phy->dev); |
678 | if (ret) | 718 | if (ret) |
679 | goto put_dev; | 719 | goto put_dev; |
@@ -689,9 +729,6 @@ put_dev: | |||
689 | put_device(&phy->dev); /* calls phy_release() which frees resources */ | 729 | put_device(&phy->dev); /* calls phy_release() which frees resources */ |
690 | return ERR_PTR(ret); | 730 | return ERR_PTR(ret); |
691 | 731 | ||
692 | free_ida: | ||
693 | ida_simple_remove(&phy_ida, phy->id); | ||
694 | |||
695 | free_phy: | 732 | free_phy: |
696 | kfree(phy); | 733 | kfree(phy); |
697 | return ERR_PTR(ret); | 734 | return ERR_PTR(ret); |
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index c4cc11dcb2a2..5e257ef7ac05 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
@@ -367,7 +367,7 @@ static struct miphy28lp_pll_gen pcie_pll_gen[] = { | |||
367 | 367 | ||
368 | static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy) | 368 | static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy) |
369 | { | 369 | { |
370 | void *base = miphy_phy->base; | 370 | void __iomem *base = miphy_phy->base; |
371 | u8 val; | 371 | u8 val; |
372 | 372 | ||
373 | /* Putting Macro in reset */ | 373 | /* Putting Macro in reset */ |
@@ -391,7 +391,7 @@ static inline void miphy28lp_set_reset(struct miphy28lp_phy *miphy_phy) | |||
391 | static inline void miphy28lp_pll_calibration(struct miphy28lp_phy *miphy_phy, | 391 | static inline void miphy28lp_pll_calibration(struct miphy28lp_phy *miphy_phy, |
392 | struct pll_ratio *pll_ratio) | 392 | struct pll_ratio *pll_ratio) |
393 | { | 393 | { |
394 | void *base = miphy_phy->base; | 394 | void __iomem *base = miphy_phy->base; |
395 | u8 val; | 395 | u8 val; |
396 | 396 | ||
397 | /* Applying PLL Settings */ | 397 | /* Applying PLL Settings */ |
@@ -1107,11 +1107,6 @@ static struct phy *miphy28lp_xlate(struct device *dev, | |||
1107 | struct device_node *phynode = args->np; | 1107 | struct device_node *phynode = args->np; |
1108 | int ret, index = 0; | 1108 | int ret, index = 0; |
1109 | 1109 | ||
1110 | if (!of_device_is_available(phynode)) { | ||
1111 | dev_warn(dev, "Requested PHY is disabled\n"); | ||
1112 | return ERR_PTR(-ENODEV); | ||
1113 | } | ||
1114 | |||
1115 | if (args->args_count != 1) { | 1110 | if (args->args_count != 1) { |
1116 | dev_err(dev, "Invalid number of cells in 'phy' property\n"); | 1111 | dev_err(dev, "Invalid number of cells in 'phy' property\n"); |
1117 | return ERR_PTR(-EINVAL); | 1112 | return ERR_PTR(-EINVAL); |
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c index 019c2d75344e..0ff354d6e183 100644 --- a/drivers/phy/phy-miphy365x.c +++ b/drivers/phy/phy-miphy365x.c | |||
@@ -441,8 +441,8 @@ static int miphy365x_init(struct phy *phy) | |||
441 | return ret; | 441 | return ret; |
442 | } | 442 | } |
443 | 443 | ||
444 | int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy, | 444 | static int miphy365x_get_addr(struct device *dev, |
445 | int index) | 445 | struct miphy365x_phy *miphy_phy, int index) |
446 | { | 446 | { |
447 | struct device_node *phynode = miphy_phy->phy->dev.of_node; | 447 | struct device_node *phynode = miphy_phy->phy->dev.of_node; |
448 | const char *name; | 448 | const char *name; |
@@ -476,11 +476,6 @@ static struct phy *miphy365x_xlate(struct device *dev, | |||
476 | struct device_node *phynode = args->np; | 476 | struct device_node *phynode = args->np; |
477 | int ret, index; | 477 | int ret, index; |
478 | 478 | ||
479 | if (!of_device_is_available(phynode)) { | ||
480 | dev_warn(dev, "Requested PHY is disabled\n"); | ||
481 | return ERR_PTR(-ENODEV); | ||
482 | } | ||
483 | |||
484 | if (args->args_count != 1) { | 479 | if (args->args_count != 1) { |
485 | dev_err(dev, "Invalid number of cells in 'phy' property\n"); | 480 | dev_err(dev, "Invalid number of cells in 'phy' property\n"); |
486 | return ERR_PTR(-EINVAL); | 481 | return ERR_PTR(-EINVAL); |
diff --git a/drivers/phy/phy-pxa-28nm-hsic.c b/drivers/phy/phy-pxa-28nm-hsic.c new file mode 100644 index 000000000000..234aacf4db20 --- /dev/null +++ b/drivers/phy/phy-pxa-28nm-hsic.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Linaro, Ltd. | ||
3 | * Rob Herring <robh@kernel.org> | ||
4 | * | ||
5 | * Based on vendor driver: | ||
6 | * Copyright (C) 2013 Marvell Inc. | ||
7 | * Author: Chao Xie <xiechao.mail@gmail.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/phy/phy.h> | ||
29 | |||
30 | #define PHY_28NM_HSIC_CTRL 0x08 | ||
31 | #define PHY_28NM_HSIC_IMPCAL_CAL 0x18 | ||
32 | #define PHY_28NM_HSIC_PLL_CTRL01 0x1c | ||
33 | #define PHY_28NM_HSIC_PLL_CTRL2 0x20 | ||
34 | #define PHY_28NM_HSIC_INT 0x28 | ||
35 | |||
36 | #define PHY_28NM_HSIC_PLL_SELLPFR_SHIFT 26 | ||
37 | #define PHY_28NM_HSIC_PLL_FBDIV_SHIFT 0 | ||
38 | #define PHY_28NM_HSIC_PLL_REFDIV_SHIFT 9 | ||
39 | |||
40 | #define PHY_28NM_HSIC_S2H_PU_PLL BIT(10) | ||
41 | #define PHY_28NM_HSIC_H2S_PLL_LOCK BIT(15) | ||
42 | #define PHY_28NM_HSIC_S2H_HSIC_EN BIT(7) | ||
43 | #define S2H_DRV_SE0_4RESUME BIT(14) | ||
44 | #define PHY_28NM_HSIC_H2S_IMPCAL_DONE BIT(27) | ||
45 | |||
46 | #define PHY_28NM_HSIC_CONNECT_INT BIT(1) | ||
47 | #define PHY_28NM_HSIC_HS_READY_INT BIT(2) | ||
48 | |||
49 | struct mv_hsic_phy { | ||
50 | struct phy *phy; | ||
51 | struct platform_device *pdev; | ||
52 | void __iomem *base; | ||
53 | struct clk *clk; | ||
54 | }; | ||
55 | |||
56 | static bool wait_for_reg(void __iomem *reg, u32 mask, unsigned long timeout) | ||
57 | { | ||
58 | timeout += jiffies; | ||
59 | while (time_is_after_eq_jiffies(timeout)) { | ||
60 | if ((readl(reg) & mask) == mask) | ||
61 | return true; | ||
62 | msleep(1); | ||
63 | } | ||
64 | return false; | ||
65 | } | ||
66 | |||
67 | static int mv_hsic_phy_init(struct phy *phy) | ||
68 | { | ||
69 | struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); | ||
70 | struct platform_device *pdev = mv_phy->pdev; | ||
71 | void __iomem *base = mv_phy->base; | ||
72 | |||
73 | clk_prepare_enable(mv_phy->clk); | ||
74 | |||
75 | /* Set reference clock */ | ||
76 | writel(0x1 << PHY_28NM_HSIC_PLL_SELLPFR_SHIFT | | ||
77 | 0xf0 << PHY_28NM_HSIC_PLL_FBDIV_SHIFT | | ||
78 | 0xd << PHY_28NM_HSIC_PLL_REFDIV_SHIFT, | ||
79 | base + PHY_28NM_HSIC_PLL_CTRL01); | ||
80 | |||
81 | /* Turn on PLL */ | ||
82 | writel(readl(base + PHY_28NM_HSIC_PLL_CTRL2) | | ||
83 | PHY_28NM_HSIC_S2H_PU_PLL, | ||
84 | base + PHY_28NM_HSIC_PLL_CTRL2); | ||
85 | |||
86 | /* Make sure PHY PLL is locked */ | ||
87 | if (!wait_for_reg(base + PHY_28NM_HSIC_PLL_CTRL2, | ||
88 | PHY_28NM_HSIC_H2S_PLL_LOCK, HZ / 10)) { | ||
89 | dev_err(&pdev->dev, "HSIC PHY PLL not locked after 100mS."); | ||
90 | clk_disable_unprepare(mv_phy->clk); | ||
91 | return -ETIMEDOUT; | ||
92 | } | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int mv_hsic_phy_power_on(struct phy *phy) | ||
98 | { | ||
99 | struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); | ||
100 | struct platform_device *pdev = mv_phy->pdev; | ||
101 | void __iomem *base = mv_phy->base; | ||
102 | u32 reg; | ||
103 | |||
104 | reg = readl(base + PHY_28NM_HSIC_CTRL); | ||
105 | /* Avoid SE0 state when resume for some device will take it as reset */ | ||
106 | reg &= ~S2H_DRV_SE0_4RESUME; | ||
107 | reg |= PHY_28NM_HSIC_S2H_HSIC_EN; /* Enable HSIC PHY */ | ||
108 | writel(reg, base + PHY_28NM_HSIC_CTRL); | ||
109 | |||
110 | /* | ||
111 | * Calibration Timing | ||
112 | * ____________________________ | ||
113 | * CAL START ___| | ||
114 | * ____________________ | ||
115 | * CAL_DONE ___________| | ||
116 | * | 400us | | ||
117 | */ | ||
118 | |||
119 | /* Make sure PHY Calibration is ready */ | ||
120 | if (!wait_for_reg(base + PHY_28NM_HSIC_IMPCAL_CAL, | ||
121 | PHY_28NM_HSIC_H2S_IMPCAL_DONE, HZ / 10)) { | ||
122 | dev_warn(&pdev->dev, "HSIC PHY READY not set after 100mS."); | ||
123 | return -ETIMEDOUT; | ||
124 | } | ||
125 | |||
126 | /* Waiting for HSIC connect int*/ | ||
127 | if (!wait_for_reg(base + PHY_28NM_HSIC_INT, | ||
128 | PHY_28NM_HSIC_CONNECT_INT, HZ / 5)) { | ||
129 | dev_warn(&pdev->dev, "HSIC wait for connect interrupt timeout."); | ||
130 | return -ETIMEDOUT; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int mv_hsic_phy_power_off(struct phy *phy) | ||
137 | { | ||
138 | struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); | ||
139 | void __iomem *base = mv_phy->base; | ||
140 | |||
141 | writel(readl(base + PHY_28NM_HSIC_CTRL) & ~PHY_28NM_HSIC_S2H_HSIC_EN, | ||
142 | base + PHY_28NM_HSIC_CTRL); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int mv_hsic_phy_exit(struct phy *phy) | ||
148 | { | ||
149 | struct mv_hsic_phy *mv_phy = phy_get_drvdata(phy); | ||
150 | void __iomem *base = mv_phy->base; | ||
151 | |||
152 | /* Turn off PLL */ | ||
153 | writel(readl(base + PHY_28NM_HSIC_PLL_CTRL2) & | ||
154 | ~PHY_28NM_HSIC_S2H_PU_PLL, | ||
155 | base + PHY_28NM_HSIC_PLL_CTRL2); | ||
156 | |||
157 | clk_disable_unprepare(mv_phy->clk); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | |||
162 | static const struct phy_ops hsic_ops = { | ||
163 | .init = mv_hsic_phy_init, | ||
164 | .power_on = mv_hsic_phy_power_on, | ||
165 | .power_off = mv_hsic_phy_power_off, | ||
166 | .exit = mv_hsic_phy_exit, | ||
167 | .owner = THIS_MODULE, | ||
168 | }; | ||
169 | |||
170 | static int mv_hsic_phy_probe(struct platform_device *pdev) | ||
171 | { | ||
172 | struct phy_provider *phy_provider; | ||
173 | struct mv_hsic_phy *mv_phy; | ||
174 | struct resource *r; | ||
175 | |||
176 | mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL); | ||
177 | if (!mv_phy) | ||
178 | return -ENOMEM; | ||
179 | |||
180 | mv_phy->pdev = pdev; | ||
181 | |||
182 | mv_phy->clk = devm_clk_get(&pdev->dev, NULL); | ||
183 | if (IS_ERR(mv_phy->clk)) { | ||
184 | dev_err(&pdev->dev, "failed to get clock.\n"); | ||
185 | return PTR_ERR(mv_phy->clk); | ||
186 | } | ||
187 | |||
188 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
189 | mv_phy->base = devm_ioremap_resource(&pdev->dev, r); | ||
190 | if (IS_ERR(mv_phy->base)) | ||
191 | return PTR_ERR(mv_phy->base); | ||
192 | |||
193 | mv_phy->phy = devm_phy_create(&pdev->dev, pdev->dev.of_node, &hsic_ops); | ||
194 | if (IS_ERR(mv_phy->phy)) | ||
195 | return PTR_ERR(mv_phy->phy); | ||
196 | |||
197 | phy_set_drvdata(mv_phy->phy, mv_phy); | ||
198 | |||
199 | phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); | ||
200 | return PTR_ERR_OR_ZERO(phy_provider); | ||
201 | } | ||
202 | |||
203 | static const struct of_device_id mv_hsic_phy_dt_match[] = { | ||
204 | { .compatible = "marvell,pxa1928-hsic-phy", }, | ||
205 | {}, | ||
206 | }; | ||
207 | MODULE_DEVICE_TABLE(of, mv_hsic_phy_dt_match); | ||
208 | |||
209 | static struct platform_driver mv_hsic_phy_driver = { | ||
210 | .probe = mv_hsic_phy_probe, | ||
211 | .driver = { | ||
212 | .name = "mv-hsic-phy", | ||
213 | .of_match_table = of_match_ptr(mv_hsic_phy_dt_match), | ||
214 | }, | ||
215 | }; | ||
216 | module_platform_driver(mv_hsic_phy_driver); | ||
217 | |||
218 | MODULE_AUTHOR("Rob Herring <robh@kernel.org>"); | ||
219 | MODULE_DESCRIPTION("Marvell HSIC phy driver"); | ||
220 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-pxa-28nm-usb2.c b/drivers/phy/phy-pxa-28nm-usb2.c new file mode 100644 index 000000000000..37e9c8ca4983 --- /dev/null +++ b/drivers/phy/phy-pxa-28nm-usb2.c | |||
@@ -0,0 +1,355 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Linaro, Ltd. | ||
3 | * Rob Herring <robh@kernel.org> | ||
4 | * | ||
5 | * Based on vendor driver: | ||
6 | * Copyright (C) 2013 Marvell Inc. | ||
7 | * Author: Chao Xie <xiechao.mail@gmail.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/phy/phy.h> | ||
30 | |||
31 | /* USB PXA1928 PHY mapping */ | ||
32 | #define PHY_28NM_PLL_REG0 0x0 | ||
33 | #define PHY_28NM_PLL_REG1 0x4 | ||
34 | #define PHY_28NM_CAL_REG 0x8 | ||
35 | #define PHY_28NM_TX_REG0 0x0c | ||
36 | #define PHY_28NM_TX_REG1 0x10 | ||
37 | #define PHY_28NM_RX_REG0 0x14 | ||
38 | #define PHY_28NM_RX_REG1 0x18 | ||
39 | #define PHY_28NM_DIG_REG0 0x1c | ||
40 | #define PHY_28NM_DIG_REG1 0x20 | ||
41 | #define PHY_28NM_TEST_REG0 0x24 | ||
42 | #define PHY_28NM_TEST_REG1 0x28 | ||
43 | #define PHY_28NM_MOC_REG 0x2c | ||
44 | #define PHY_28NM_PHY_RESERVE 0x30 | ||
45 | #define PHY_28NM_OTG_REG 0x34 | ||
46 | #define PHY_28NM_CHRG_DET 0x38 | ||
47 | #define PHY_28NM_CTRL_REG0 0xc4 | ||
48 | #define PHY_28NM_CTRL_REG1 0xc8 | ||
49 | #define PHY_28NM_CTRL_REG2 0xd4 | ||
50 | #define PHY_28NM_CTRL_REG3 0xdc | ||
51 | |||
52 | /* PHY_28NM_PLL_REG0 */ | ||
53 | #define PHY_28NM_PLL_READY BIT(31) | ||
54 | |||
55 | #define PHY_28NM_PLL_SELLPFR_SHIFT 28 | ||
56 | #define PHY_28NM_PLL_SELLPFR_MASK (0x3 << 28) | ||
57 | |||
58 | #define PHY_28NM_PLL_FBDIV_SHIFT 16 | ||
59 | #define PHY_28NM_PLL_FBDIV_MASK (0x1ff << 16) | ||
60 | |||
61 | #define PHY_28NM_PLL_ICP_SHIFT 8 | ||
62 | #define PHY_28NM_PLL_ICP_MASK (0x7 << 8) | ||
63 | |||
64 | #define PHY_28NM_PLL_REFDIV_SHIFT 0 | ||
65 | #define PHY_28NM_PLL_REFDIV_MASK 0x7f | ||
66 | |||
67 | /* PHY_28NM_PLL_REG1 */ | ||
68 | #define PHY_28NM_PLL_PU_BY_REG BIT(1) | ||
69 | |||
70 | #define PHY_28NM_PLL_PU_PLL BIT(0) | ||
71 | |||
72 | /* PHY_28NM_CAL_REG */ | ||
73 | #define PHY_28NM_PLL_PLLCAL_DONE BIT(31) | ||
74 | |||
75 | #define PHY_28NM_PLL_IMPCAL_DONE BIT(23) | ||
76 | |||
77 | #define PHY_28NM_PLL_KVCO_SHIFT 16 | ||
78 | #define PHY_28NM_PLL_KVCO_MASK (0x7 << 16) | ||
79 | |||
80 | #define PHY_28NM_PLL_CAL12_SHIFT 20 | ||
81 | #define PHY_28NM_PLL_CAL12_MASK (0x3 << 20) | ||
82 | |||
83 | #define PHY_28NM_IMPCAL_VTH_SHIFT 8 | ||
84 | #define PHY_28NM_IMPCAL_VTH_MASK (0x7 << 8) | ||
85 | |||
86 | #define PHY_28NM_PLLCAL_START_SHIFT 22 | ||
87 | #define PHY_28NM_IMPCAL_START_SHIFT 13 | ||
88 | |||
89 | /* PHY_28NM_TX_REG0 */ | ||
90 | #define PHY_28NM_TX_PU_BY_REG BIT(25) | ||
91 | |||
92 | #define PHY_28NM_TX_PU_ANA BIT(24) | ||
93 | |||
94 | #define PHY_28NM_TX_AMP_SHIFT 20 | ||
95 | #define PHY_28NM_TX_AMP_MASK (0x7 << 20) | ||
96 | |||
97 | /* PHY_28NM_RX_REG0 */ | ||
98 | #define PHY_28NM_RX_SQ_THRESH_SHIFT 0 | ||
99 | #define PHY_28NM_RX_SQ_THRESH_MASK (0xf << 0) | ||
100 | |||
101 | /* PHY_28NM_RX_REG1 */ | ||
102 | #define PHY_28NM_RX_SQCAL_DONE BIT(31) | ||
103 | |||
104 | /* PHY_28NM_DIG_REG0 */ | ||
105 | #define PHY_28NM_DIG_BITSTAFFING_ERR BIT(31) | ||
106 | #define PHY_28NM_DIG_SYNC_ERR BIT(30) | ||
107 | |||
108 | #define PHY_28NM_DIG_SQ_FILT_SHIFT 16 | ||
109 | #define PHY_28NM_DIG_SQ_FILT_MASK (0x7 << 16) | ||
110 | |||
111 | #define PHY_28NM_DIG_SQ_BLK_SHIFT 12 | ||
112 | #define PHY_28NM_DIG_SQ_BLK_MASK (0x7 << 12) | ||
113 | |||
114 | #define PHY_28NM_DIG_SYNC_NUM_SHIFT 0 | ||
115 | #define PHY_28NM_DIG_SYNC_NUM_MASK (0x3 << 0) | ||
116 | |||
117 | #define PHY_28NM_PLL_LOCK_BYPASS BIT(7) | ||
118 | |||
119 | /* PHY_28NM_OTG_REG */ | ||
120 | #define PHY_28NM_OTG_CONTROL_BY_PIN BIT(5) | ||
121 | #define PHY_28NM_OTG_PU_OTG BIT(4) | ||
122 | |||
123 | #define PHY_28NM_CHGDTC_ENABLE_SWITCH_DM_SHIFT_28 13 | ||
124 | #define PHY_28NM_CHGDTC_ENABLE_SWITCH_DP_SHIFT_28 12 | ||
125 | #define PHY_28NM_CHGDTC_VSRC_CHARGE_SHIFT_28 10 | ||
126 | #define PHY_28NM_CHGDTC_VDAT_CHARGE_SHIFT_28 8 | ||
127 | #define PHY_28NM_CHGDTC_CDP_DM_AUTO_SWITCH_SHIFT_28 7 | ||
128 | #define PHY_28NM_CHGDTC_DP_DM_SWAP_SHIFT_28 6 | ||
129 | #define PHY_28NM_CHGDTC_PU_CHRG_DTC_SHIFT_28 5 | ||
130 | #define PHY_28NM_CHGDTC_PD_EN_SHIFT_28 4 | ||
131 | #define PHY_28NM_CHGDTC_DCP_EN_SHIFT_28 3 | ||
132 | #define PHY_28NM_CHGDTC_CDP_EN_SHIFT_28 2 | ||
133 | #define PHY_28NM_CHGDTC_TESTMON_CHRGDTC_SHIFT_28 0 | ||
134 | |||
135 | #define PHY_28NM_CTRL1_CHRG_DTC_OUT_SHIFT_28 4 | ||
136 | #define PHY_28NM_CTRL1_VBUSDTC_OUT_SHIFT_28 2 | ||
137 | |||
138 | #define PHY_28NM_CTRL3_OVERWRITE BIT(0) | ||
139 | #define PHY_28NM_CTRL3_VBUS_VALID BIT(4) | ||
140 | #define PHY_28NM_CTRL3_AVALID BIT(5) | ||
141 | #define PHY_28NM_CTRL3_BVALID BIT(6) | ||
142 | |||
143 | struct mv_usb2_phy { | ||
144 | struct phy *phy; | ||
145 | struct platform_device *pdev; | ||
146 | void __iomem *base; | ||
147 | struct clk *clk; | ||
148 | }; | ||
149 | |||
150 | static bool wait_for_reg(void __iomem *reg, u32 mask, unsigned long timeout) | ||
151 | { | ||
152 | timeout += jiffies; | ||
153 | while (time_is_after_eq_jiffies(timeout)) { | ||
154 | if ((readl(reg) & mask) == mask) | ||
155 | return true; | ||
156 | msleep(1); | ||
157 | } | ||
158 | return false; | ||
159 | } | ||
160 | |||
161 | static int mv_usb2_phy_28nm_init(struct phy *phy) | ||
162 | { | ||
163 | struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy); | ||
164 | struct platform_device *pdev = mv_phy->pdev; | ||
165 | void __iomem *base = mv_phy->base; | ||
166 | u32 reg; | ||
167 | int ret; | ||
168 | |||
169 | clk_prepare_enable(mv_phy->clk); | ||
170 | |||
171 | /* PHY_28NM_PLL_REG0 */ | ||
172 | reg = readl(base + PHY_28NM_PLL_REG0) & | ||
173 | ~(PHY_28NM_PLL_SELLPFR_MASK | PHY_28NM_PLL_FBDIV_MASK | ||
174 | | PHY_28NM_PLL_ICP_MASK | PHY_28NM_PLL_REFDIV_MASK); | ||
175 | writel(reg | (0x1 << PHY_28NM_PLL_SELLPFR_SHIFT | ||
176 | | 0xf0 << PHY_28NM_PLL_FBDIV_SHIFT | ||
177 | | 0x3 << PHY_28NM_PLL_ICP_SHIFT | ||
178 | | 0xd << PHY_28NM_PLL_REFDIV_SHIFT), | ||
179 | base + PHY_28NM_PLL_REG0); | ||
180 | |||
181 | /* PHY_28NM_PLL_REG1 */ | ||
182 | reg = readl(base + PHY_28NM_PLL_REG1); | ||
183 | writel(reg | PHY_28NM_PLL_PU_PLL | PHY_28NM_PLL_PU_BY_REG, | ||
184 | base + PHY_28NM_PLL_REG1); | ||
185 | |||
186 | /* PHY_28NM_TX_REG0 */ | ||
187 | reg = readl(base + PHY_28NM_TX_REG0) & ~PHY_28NM_TX_AMP_MASK; | ||
188 | writel(reg | PHY_28NM_TX_PU_BY_REG | 0x3 << PHY_28NM_TX_AMP_SHIFT | | ||
189 | PHY_28NM_TX_PU_ANA, | ||
190 | base + PHY_28NM_TX_REG0); | ||
191 | |||
192 | /* PHY_28NM_RX_REG0 */ | ||
193 | reg = readl(base + PHY_28NM_RX_REG0) & ~PHY_28NM_RX_SQ_THRESH_MASK; | ||
194 | writel(reg | 0xa << PHY_28NM_RX_SQ_THRESH_SHIFT, | ||
195 | base + PHY_28NM_RX_REG0); | ||
196 | |||
197 | /* PHY_28NM_DIG_REG0 */ | ||
198 | reg = readl(base + PHY_28NM_DIG_REG0) & | ||
199 | ~(PHY_28NM_DIG_BITSTAFFING_ERR | PHY_28NM_DIG_SYNC_ERR | | ||
200 | PHY_28NM_DIG_SQ_FILT_MASK | PHY_28NM_DIG_SQ_BLK_MASK | | ||
201 | PHY_28NM_DIG_SYNC_NUM_MASK); | ||
202 | writel(reg | (0x1 << PHY_28NM_DIG_SYNC_NUM_SHIFT | | ||
203 | PHY_28NM_PLL_LOCK_BYPASS), | ||
204 | base + PHY_28NM_DIG_REG0); | ||
205 | |||
206 | /* PHY_28NM_OTG_REG */ | ||
207 | reg = readl(base + PHY_28NM_OTG_REG) | PHY_28NM_OTG_PU_OTG; | ||
208 | writel(reg & ~PHY_28NM_OTG_CONTROL_BY_PIN, base + PHY_28NM_OTG_REG); | ||
209 | |||
210 | /* | ||
211 | * Calibration Timing | ||
212 | * ____________________________ | ||
213 | * CAL START ___| | ||
214 | * ____________________ | ||
215 | * CAL_DONE ___________| | ||
216 | * | 400us | | ||
217 | */ | ||
218 | |||
219 | /* Make sure PHY Calibration is ready */ | ||
220 | if (!wait_for_reg(base + PHY_28NM_CAL_REG, | ||
221 | PHY_28NM_PLL_PLLCAL_DONE | PHY_28NM_PLL_IMPCAL_DONE, | ||
222 | HZ / 10)) { | ||
223 | dev_warn(&pdev->dev, "USB PHY PLL calibrate not done after 100mS."); | ||
224 | ret = -ETIMEDOUT; | ||
225 | goto err_clk; | ||
226 | } | ||
227 | if (!wait_for_reg(base + PHY_28NM_RX_REG1, | ||
228 | PHY_28NM_RX_SQCAL_DONE, HZ / 10)) { | ||
229 | dev_warn(&pdev->dev, "USB PHY RX SQ calibrate not done after 100mS."); | ||
230 | ret = -ETIMEDOUT; | ||
231 | goto err_clk; | ||
232 | } | ||
233 | /* Make sure PHY PLL is ready */ | ||
234 | if (!wait_for_reg(base + PHY_28NM_PLL_REG0, | ||
235 | PHY_28NM_PLL_READY, HZ / 10)) { | ||
236 | dev_warn(&pdev->dev, "PLL_READY not set after 100mS."); | ||
237 | ret = -ETIMEDOUT; | ||
238 | goto err_clk; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | err_clk: | ||
243 | clk_disable_unprepare(mv_phy->clk); | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | static int mv_usb2_phy_28nm_power_on(struct phy *phy) | ||
248 | { | ||
249 | struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy); | ||
250 | void __iomem *base = mv_phy->base; | ||
251 | |||
252 | writel(readl(base + PHY_28NM_CTRL_REG3) | | ||
253 | (PHY_28NM_CTRL3_OVERWRITE | PHY_28NM_CTRL3_VBUS_VALID | | ||
254 | PHY_28NM_CTRL3_AVALID | PHY_28NM_CTRL3_BVALID), | ||
255 | base + PHY_28NM_CTRL_REG3); | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int mv_usb2_phy_28nm_power_off(struct phy *phy) | ||
261 | { | ||
262 | struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy); | ||
263 | void __iomem *base = mv_phy->base; | ||
264 | |||
265 | writel(readl(base + PHY_28NM_CTRL_REG3) | | ||
266 | ~(PHY_28NM_CTRL3_OVERWRITE | PHY_28NM_CTRL3_VBUS_VALID | ||
267 | | PHY_28NM_CTRL3_AVALID | PHY_28NM_CTRL3_BVALID), | ||
268 | base + PHY_28NM_CTRL_REG3); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int mv_usb2_phy_28nm_exit(struct phy *phy) | ||
274 | { | ||
275 | struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy); | ||
276 | void __iomem *base = mv_phy->base; | ||
277 | unsigned int val; | ||
278 | |||
279 | val = readw(base + PHY_28NM_PLL_REG1); | ||
280 | val &= ~PHY_28NM_PLL_PU_PLL; | ||
281 | writew(val, base + PHY_28NM_PLL_REG1); | ||
282 | |||
283 | /* power down PHY Analog part */ | ||
284 | val = readw(base + PHY_28NM_TX_REG0); | ||
285 | val &= ~PHY_28NM_TX_PU_ANA; | ||
286 | writew(val, base + PHY_28NM_TX_REG0); | ||
287 | |||
288 | /* power down PHY OTG part */ | ||
289 | val = readw(base + PHY_28NM_OTG_REG); | ||
290 | val &= ~PHY_28NM_OTG_PU_OTG; | ||
291 | writew(val, base + PHY_28NM_OTG_REG); | ||
292 | |||
293 | clk_disable_unprepare(mv_phy->clk); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static const struct phy_ops usb_ops = { | ||
298 | .init = mv_usb2_phy_28nm_init, | ||
299 | .power_on = mv_usb2_phy_28nm_power_on, | ||
300 | .power_off = mv_usb2_phy_28nm_power_off, | ||
301 | .exit = mv_usb2_phy_28nm_exit, | ||
302 | .owner = THIS_MODULE, | ||
303 | }; | ||
304 | |||
305 | static int mv_usb2_phy_probe(struct platform_device *pdev) | ||
306 | { | ||
307 | struct phy_provider *phy_provider; | ||
308 | struct mv_usb2_phy *mv_phy; | ||
309 | struct resource *r; | ||
310 | |||
311 | mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL); | ||
312 | if (!mv_phy) | ||
313 | return -ENOMEM; | ||
314 | |||
315 | mv_phy->pdev = pdev; | ||
316 | |||
317 | mv_phy->clk = devm_clk_get(&pdev->dev, NULL); | ||
318 | if (IS_ERR(mv_phy->clk)) { | ||
319 | dev_err(&pdev->dev, "failed to get clock.\n"); | ||
320 | return PTR_ERR(mv_phy->clk); | ||
321 | } | ||
322 | |||
323 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
324 | mv_phy->base = devm_ioremap_resource(&pdev->dev, r); | ||
325 | if (IS_ERR(mv_phy->base)) | ||
326 | return PTR_ERR(mv_phy->base); | ||
327 | |||
328 | mv_phy->phy = devm_phy_create(&pdev->dev, pdev->dev.of_node, &usb_ops); | ||
329 | if (IS_ERR(mv_phy->phy)) | ||
330 | return PTR_ERR(mv_phy->phy); | ||
331 | |||
332 | phy_set_drvdata(mv_phy->phy, mv_phy); | ||
333 | |||
334 | phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); | ||
335 | return PTR_ERR_OR_ZERO(phy_provider); | ||
336 | } | ||
337 | |||
338 | static const struct of_device_id mv_usbphy_dt_match[] = { | ||
339 | { .compatible = "marvell,pxa1928-usb-phy", }, | ||
340 | {}, | ||
341 | }; | ||
342 | MODULE_DEVICE_TABLE(of, mv_usbphy_dt_match); | ||
343 | |||
344 | static struct platform_driver mv_usb2_phy_driver = { | ||
345 | .probe = mv_usb2_phy_probe, | ||
346 | .driver = { | ||
347 | .name = "mv-usb2-phy", | ||
348 | .of_match_table = of_match_ptr(mv_usbphy_dt_match), | ||
349 | }, | ||
350 | }; | ||
351 | module_platform_driver(mv_usb2_phy_driver); | ||
352 | |||
353 | MODULE_AUTHOR("Rob Herring <robh@kernel.org>"); | ||
354 | MODULE_DESCRIPTION("Marvell USB2 phy driver"); | ||
355 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c index 97d45f47d1ad..39d9b2995435 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/phy-rcar-gen2.c | |||
@@ -195,6 +195,7 @@ static struct phy_ops rcar_gen2_phy_ops = { | |||
195 | static const struct of_device_id rcar_gen2_phy_match_table[] = { | 195 | static const struct of_device_id rcar_gen2_phy_match_table[] = { |
196 | { .compatible = "renesas,usb-phy-r8a7790" }, | 196 | { .compatible = "renesas,usb-phy-r8a7790" }, |
197 | { .compatible = "renesas,usb-phy-r8a7791" }, | 197 | { .compatible = "renesas,usb-phy-r8a7791" }, |
198 | { .compatible = "renesas,usb-phy-r8a7794" }, | ||
198 | { } | 199 | { } |
199 | }; | 200 | }; |
200 | MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table); | 201 | MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table); |
@@ -206,11 +207,6 @@ static struct phy *rcar_gen2_phy_xlate(struct device *dev, | |||
206 | struct device_node *np = args->np; | 207 | struct device_node *np = args->np; |
207 | int i; | 208 | int i; |
208 | 209 | ||
209 | if (!of_device_is_available(np)) { | ||
210 | dev_warn(dev, "Requested PHY is disabled\n"); | ||
211 | return ERR_PTR(-ENODEV); | ||
212 | } | ||
213 | |||
214 | drv = dev_get_drvdata(dev); | 210 | drv = dev_get_drvdata(dev); |
215 | if (!drv) | 211 | if (!drv) |
216 | return ERR_PTR(-EINVAL); | 212 | return ERR_PTR(-EINVAL); |
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index a2b08f3ccb03..e17c539e4f6f 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/of.h> | 30 | #include <linux/of.h> |
31 | #include <linux/of_address.h> | 31 | #include <linux/of_address.h> |
32 | #include <linux/phy/phy.h> | 32 | #include <linux/phy/phy.h> |
33 | #include <linux/phy/phy-sun4i-usb.h> | ||
33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
34 | #include <linux/regulator/consumer.h> | 35 | #include <linux/regulator/consumer.h> |
35 | #include <linux/reset.h> | 36 | #include <linux/reset.h> |
@@ -58,6 +59,7 @@ | |||
58 | #define PHY_OTG_FUNC_EN 0x28 | 59 | #define PHY_OTG_FUNC_EN 0x28 |
59 | #define PHY_VBUS_DET_EN 0x29 | 60 | #define PHY_VBUS_DET_EN 0x29 |
60 | #define PHY_DISCON_TH_SEL 0x2a | 61 | #define PHY_DISCON_TH_SEL 0x2a |
62 | #define PHY_SQUELCH_DETECT 0x3c | ||
61 | 63 | ||
62 | #define MAX_PHYS 3 | 64 | #define MAX_PHYS 3 |
63 | 65 | ||
@@ -204,6 +206,13 @@ static int sun4i_usb_phy_power_off(struct phy *_phy) | |||
204 | return 0; | 206 | return 0; |
205 | } | 207 | } |
206 | 208 | ||
209 | void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled) | ||
210 | { | ||
211 | struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); | ||
212 | |||
213 | sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2); | ||
214 | } | ||
215 | |||
207 | static struct phy_ops sun4i_usb_phy_ops = { | 216 | static struct phy_ops sun4i_usb_phy_ops = { |
208 | .init = sun4i_usb_phy_init, | 217 | .init = sun4i_usb_phy_init, |
209 | .exit = sun4i_usb_phy_exit, | 218 | .exit = sun4i_usb_phy_exit, |
diff --git a/drivers/phy/phy-tusb1210.c b/drivers/phy/phy-tusb1210.c new file mode 100644 index 000000000000..07efdd318bdc --- /dev/null +++ b/drivers/phy/phy-tusb1210.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /** | ||
2 | * tusb1210.c - TUSB1210 USB ULPI PHY driver | ||
3 | * | ||
4 | * Copyright (C) 2015 Intel Corporation | ||
5 | * | ||
6 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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 | #include <linux/module.h> | ||
13 | #include <linux/ulpi/driver.h> | ||
14 | #include <linux/gpio/consumer.h> | ||
15 | |||
16 | #include "ulpi_phy.h" | ||
17 | |||
18 | #define TUSB1210_VENDOR_SPECIFIC2 0x80 | ||
19 | #define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT 0 | ||
20 | #define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT 4 | ||
21 | #define TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT 6 | ||
22 | |||
23 | struct tusb1210 { | ||
24 | struct ulpi *ulpi; | ||
25 | struct phy *phy; | ||
26 | struct gpio_desc *gpio_reset; | ||
27 | struct gpio_desc *gpio_cs; | ||
28 | u8 vendor_specific2; | ||
29 | }; | ||
30 | |||
31 | static int tusb1210_power_on(struct phy *phy) | ||
32 | { | ||
33 | struct tusb1210 *tusb = phy_get_drvdata(phy); | ||
34 | |||
35 | gpiod_set_value_cansleep(tusb->gpio_reset, 1); | ||
36 | gpiod_set_value_cansleep(tusb->gpio_cs, 1); | ||
37 | |||
38 | /* Restore the optional eye diagram optimization value */ | ||
39 | if (tusb->vendor_specific2) | ||
40 | ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2, | ||
41 | tusb->vendor_specific2); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static int tusb1210_power_off(struct phy *phy) | ||
47 | { | ||
48 | struct tusb1210 *tusb = phy_get_drvdata(phy); | ||
49 | |||
50 | gpiod_set_value_cansleep(tusb->gpio_reset, 0); | ||
51 | gpiod_set_value_cansleep(tusb->gpio_cs, 0); | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static struct phy_ops phy_ops = { | ||
57 | .power_on = tusb1210_power_on, | ||
58 | .power_off = tusb1210_power_off, | ||
59 | .owner = THIS_MODULE, | ||
60 | }; | ||
61 | |||
62 | static int tusb1210_probe(struct ulpi *ulpi) | ||
63 | { | ||
64 | struct gpio_desc *gpio; | ||
65 | struct tusb1210 *tusb; | ||
66 | u8 val, reg; | ||
67 | int ret; | ||
68 | |||
69 | tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL); | ||
70 | if (!tusb) | ||
71 | return -ENOMEM; | ||
72 | |||
73 | gpio = devm_gpiod_get(&ulpi->dev, "reset"); | ||
74 | if (!IS_ERR(gpio)) { | ||
75 | ret = gpiod_direction_output(gpio, 0); | ||
76 | if (ret) | ||
77 | return ret; | ||
78 | gpiod_set_value_cansleep(gpio, 1); | ||
79 | tusb->gpio_reset = gpio; | ||
80 | } | ||
81 | |||
82 | gpio = devm_gpiod_get(&ulpi->dev, "cs"); | ||
83 | if (!IS_ERR(gpio)) { | ||
84 | ret = gpiod_direction_output(gpio, 0); | ||
85 | if (ret) | ||
86 | return ret; | ||
87 | gpiod_set_value_cansleep(gpio, 1); | ||
88 | tusb->gpio_cs = gpio; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye | ||
93 | * diagram optimization and DP/DM swap. | ||
94 | */ | ||
95 | |||
96 | /* High speed output drive strength configuration */ | ||
97 | device_property_read_u8(&ulpi->dev, "ihstx", &val); | ||
98 | reg = val << TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT; | ||
99 | |||
100 | /* High speed output impedance configuration */ | ||
101 | device_property_read_u8(&ulpi->dev, "zhsdrv", &val); | ||
102 | reg |= val << TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT; | ||
103 | |||
104 | /* DP/DM swap control */ | ||
105 | device_property_read_u8(&ulpi->dev, "datapolarity", &val); | ||
106 | reg |= val << TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT; | ||
107 | |||
108 | if (reg) { | ||
109 | ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg); | ||
110 | tusb->vendor_specific2 = reg; | ||
111 | } | ||
112 | |||
113 | tusb->phy = ulpi_phy_create(ulpi, &phy_ops); | ||
114 | if (IS_ERR(tusb->phy)) | ||
115 | return PTR_ERR(tusb->phy); | ||
116 | |||
117 | tusb->ulpi = ulpi; | ||
118 | |||
119 | phy_set_drvdata(tusb->phy, tusb); | ||
120 | ulpi_set_drvdata(ulpi, tusb); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static void tusb1210_remove(struct ulpi *ulpi) | ||
125 | { | ||
126 | struct tusb1210 *tusb = ulpi_get_drvdata(ulpi); | ||
127 | |||
128 | ulpi_phy_destroy(ulpi, tusb->phy); | ||
129 | } | ||
130 | |||
131 | #define TI_VENDOR_ID 0x0451 | ||
132 | |||
133 | static const struct ulpi_device_id tusb1210_ulpi_id[] = { | ||
134 | { TI_VENDOR_ID, 0x1507, }, | ||
135 | { }, | ||
136 | }; | ||
137 | MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id); | ||
138 | |||
139 | static struct ulpi_driver tusb1210_driver = { | ||
140 | .id_table = tusb1210_ulpi_id, | ||
141 | .probe = tusb1210_probe, | ||
142 | .remove = tusb1210_remove, | ||
143 | .driver = { | ||
144 | .name = "tusb1210", | ||
145 | .owner = THIS_MODULE, | ||
146 | }, | ||
147 | }; | ||
148 | |||
149 | module_ulpi_driver(tusb1210_driver); | ||
150 | |||
151 | MODULE_AUTHOR("Intel Corporation"); | ||
152 | MODULE_LICENSE("GPL v2"); | ||
153 | MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver"); | ||
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index bc42d6a8939f..3a707dd14238 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
@@ -144,6 +144,16 @@ | |||
144 | #define PMBR1 0x0D | 144 | #define PMBR1 0x0D |
145 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) | 145 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) |
146 | 146 | ||
147 | /* | ||
148 | * If VBUS is valid or ID is ground, then we know a | ||
149 | * cable is present and we need to be runtime-enabled | ||
150 | */ | ||
151 | static inline bool cable_present(enum omap_musb_vbus_id_status stat) | ||
152 | { | ||
153 | return stat == OMAP_MUSB_VBUS_VALID || | ||
154 | stat == OMAP_MUSB_ID_GROUND; | ||
155 | } | ||
156 | |||
147 | struct twl4030_usb { | 157 | struct twl4030_usb { |
148 | struct usb_phy phy; | 158 | struct usb_phy phy; |
149 | struct device *dev; | 159 | struct device *dev; |
@@ -386,8 +396,6 @@ static int twl4030_usb_runtime_suspend(struct device *dev) | |||
386 | struct twl4030_usb *twl = dev_get_drvdata(dev); | 396 | struct twl4030_usb *twl = dev_get_drvdata(dev); |
387 | 397 | ||
388 | dev_dbg(twl->dev, "%s\n", __func__); | 398 | dev_dbg(twl->dev, "%s\n", __func__); |
389 | if (pm_runtime_suspended(dev)) | ||
390 | return 0; | ||
391 | 399 | ||
392 | __twl4030_phy_power(twl, 0); | 400 | __twl4030_phy_power(twl, 0); |
393 | regulator_disable(twl->usb1v5); | 401 | regulator_disable(twl->usb1v5); |
@@ -403,8 +411,6 @@ static int twl4030_usb_runtime_resume(struct device *dev) | |||
403 | int res; | 411 | int res; |
404 | 412 | ||
405 | dev_dbg(twl->dev, "%s\n", __func__); | 413 | dev_dbg(twl->dev, "%s\n", __func__); |
406 | if (pm_runtime_active(dev)) | ||
407 | return 0; | ||
408 | 414 | ||
409 | res = regulator_enable(twl->usb3v1); | 415 | res = regulator_enable(twl->usb3v1); |
410 | if (res) | 416 | if (res) |
@@ -536,8 +542,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
536 | 542 | ||
537 | mutex_lock(&twl->lock); | 543 | mutex_lock(&twl->lock); |
538 | if (status >= 0 && status != twl->linkstat) { | 544 | if (status >= 0 && status != twl->linkstat) { |
545 | status_changed = | ||
546 | cable_present(twl->linkstat) != | ||
547 | cable_present(status); | ||
539 | twl->linkstat = status; | 548 | twl->linkstat = status; |
540 | status_changed = true; | ||
541 | } | 549 | } |
542 | mutex_unlock(&twl->lock); | 550 | mutex_unlock(&twl->lock); |
543 | 551 | ||
@@ -553,15 +561,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
553 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 561 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
554 | * starts to handle softconnect right. | 562 | * starts to handle softconnect right. |
555 | */ | 563 | */ |
556 | if ((status == OMAP_MUSB_VBUS_VALID) || | 564 | if (cable_present(status)) { |
557 | (status == OMAP_MUSB_ID_GROUND)) { | 565 | pm_runtime_get_sync(twl->dev); |
558 | if (pm_runtime_suspended(twl->dev)) | ||
559 | pm_runtime_get_sync(twl->dev); | ||
560 | } else { | 566 | } else { |
561 | if (pm_runtime_active(twl->dev)) { | 567 | pm_runtime_mark_last_busy(twl->dev); |
562 | pm_runtime_mark_last_busy(twl->dev); | 568 | pm_runtime_put_autosuspend(twl->dev); |
563 | pm_runtime_put_autosuspend(twl->dev); | ||
564 | } | ||
565 | } | 569 | } |
566 | omap_musb_mailbox(status); | 570 | omap_musb_mailbox(status); |
567 | } | 571 | } |
@@ -711,7 +715,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
711 | pm_runtime_use_autosuspend(&pdev->dev); | 715 | pm_runtime_use_autosuspend(&pdev->dev); |
712 | pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); | 716 | pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); |
713 | pm_runtime_enable(&pdev->dev); | 717 | pm_runtime_enable(&pdev->dev); |
714 | pm_runtime_get_sync(&pdev->dev); | ||
715 | 718 | ||
716 | /* Our job is to use irqs and status from the power module | 719 | /* Our job is to use irqs and status from the power module |
717 | * to keep the transceiver disabled when nothing's connected. | 720 | * to keep the transceiver disabled when nothing's connected. |
@@ -767,6 +770,9 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
767 | 770 | ||
768 | /* disable complete OTG block */ | 771 | /* disable complete OTG block */ |
769 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 772 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
773 | |||
774 | if (cable_present(twl->linkstat)) | ||
775 | pm_runtime_put_noidle(twl->dev); | ||
770 | pm_runtime_mark_last_busy(twl->dev); | 776 | pm_runtime_mark_last_busy(twl->dev); |
771 | pm_runtime_put(twl->dev); | 777 | pm_runtime_put(twl->dev); |
772 | 778 | ||
diff --git a/drivers/phy/ulpi_phy.h b/drivers/phy/ulpi_phy.h new file mode 100644 index 000000000000..ac49fb6285ee --- /dev/null +++ b/drivers/phy/ulpi_phy.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #include <linux/phy/phy.h> | ||
2 | |||
3 | /** | ||
4 | * Helper that registers PHY for a ULPI device and adds a lookup for binding it | ||
5 | * and it's controller, which is always the parent. | ||
6 | */ | ||
7 | static inline struct phy | ||
8 | *ulpi_phy_create(struct ulpi *ulpi, struct phy_ops *ops) | ||
9 | { | ||
10 | struct phy *phy; | ||
11 | int ret; | ||
12 | |||
13 | phy = phy_create(&ulpi->dev, NULL, ops); | ||
14 | if (IS_ERR(phy)) | ||
15 | return phy; | ||
16 | |||
17 | ret = phy_create_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent)); | ||
18 | if (ret) { | ||
19 | phy_destroy(phy); | ||
20 | return ERR_PTR(ret); | ||
21 | } | ||
22 | |||
23 | return phy; | ||
24 | } | ||
25 | |||
26 | /* Remove a PHY that was created with ulpi_phy_create() and it's lookup. */ | ||
27 | static inline void ulpi_phy_destroy(struct ulpi *ulpi, struct phy *phy) | ||
28 | { | ||
29 | phy_remove_lookup(phy, "usb2-phy", dev_name(ulpi->dev.parent)); | ||
30 | phy_destroy(phy); | ||
31 | } | ||
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index 02a522cb7753..022b8910e443 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c | |||
@@ -638,10 +638,15 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
638 | 638 | ||
639 | INIT_WORK(&bci->work, twl4030_bci_usb_work); | 639 | INIT_WORK(&bci->work, twl4030_bci_usb_work); |
640 | 640 | ||
641 | bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 641 | bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; |
642 | if (!IS_ERR_OR_NULL(bci->transceiver)) { | 642 | if (bci->dev->of_node) { |
643 | bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; | 643 | struct device_node *phynode; |
644 | usb_register_notifier(bci->transceiver, &bci->usb_nb); | 644 | |
645 | phynode = of_find_compatible_node(bci->dev->of_node->parent, | ||
646 | NULL, "ti,twl4030-usb"); | ||
647 | if (phynode) | ||
648 | bci->transceiver = devm_usb_get_phy_by_node( | ||
649 | bci->dev, phynode, &bci->usb_nb); | ||
645 | } | 650 | } |
646 | 651 | ||
647 | /* Enable interrupts now. */ | 652 | /* Enable interrupts now. */ |
@@ -671,10 +676,6 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
671 | return 0; | 676 | return 0; |
672 | 677 | ||
673 | fail_unmask_interrupts: | 678 | fail_unmask_interrupts: |
674 | if (!IS_ERR_OR_NULL(bci->transceiver)) { | ||
675 | usb_unregister_notifier(bci->transceiver, &bci->usb_nb); | ||
676 | usb_put_phy(bci->transceiver); | ||
677 | } | ||
678 | free_irq(bci->irq_bci, bci); | 679 | free_irq(bci->irq_bci, bci); |
679 | fail_bci_irq: | 680 | fail_bci_irq: |
680 | free_irq(bci->irq_chg, bci); | 681 | free_irq(bci->irq_chg, bci); |
@@ -703,10 +704,6 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) | |||
703 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, | 704 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, |
704 | TWL4030_INTERRUPTS_BCIIMR2A); | 705 | TWL4030_INTERRUPTS_BCIIMR2A); |
705 | 706 | ||
706 | if (!IS_ERR_OR_NULL(bci->transceiver)) { | ||
707 | usb_unregister_notifier(bci->transceiver, &bci->usb_nb); | ||
708 | usb_put_phy(bci->transceiver); | ||
709 | } | ||
710 | free_irq(bci->irq_bci, bci); | 707 | free_irq(bci->irq_bci, bci); |
711 | free_irq(bci->irq_chg, bci); | 708 | free_irq(bci->irq_chg, bci); |
712 | power_supply_unregister(bci->usb); | 709 | power_supply_unregister(bci->usb); |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 0dc8c06a7b5f..0270d1312f83 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -255,7 +255,8 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
255 | 255 | ||
256 | usb_dbg(usbatm, "%s entered\n", __func__); | 256 | usb_dbg(usbatm, "%s entered\n", __func__); |
257 | 257 | ||
258 | if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) { | 258 | buffer = (unsigned char *)__get_free_page(GFP_KERNEL); |
259 | if (!buffer) { | ||
259 | ret = -ENOMEM; | 260 | ret = -ENOMEM; |
260 | usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__); | 261 | usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__); |
261 | goto out; | 262 | goto out; |
@@ -638,7 +639,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
638 | goto fail; | 639 | goto fail; |
639 | } | 640 | } |
640 | 641 | ||
641 | if ((int_urb = instance->int_urb)) { | 642 | int_urb = instance->int_urb; |
643 | if (int_urb) { | ||
642 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); | 644 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); |
643 | schedule_work(&instance->status_check_work); | 645 | schedule_work(&instance->status_check_work); |
644 | if (ret < 0) { | 646 | if (ret < 0) { |
@@ -650,7 +652,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
650 | return; | 652 | return; |
651 | 653 | ||
652 | fail: | 654 | fail: |
653 | if ((int_urb = instance->int_urb)) | 655 | int_urb = instance->int_urb; |
656 | if (int_urb) | ||
654 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); | 657 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); |
655 | } | 658 | } |
656 | 659 | ||
@@ -759,11 +762,13 @@ static void speedtch_release_interfaces(struct usb_device *usb_dev, | |||
759 | struct usb_interface *cur_intf; | 762 | struct usb_interface *cur_intf; |
760 | int i; | 763 | int i; |
761 | 764 | ||
762 | for (i = 0; i < num_interfaces; i++) | 765 | for (i = 0; i < num_interfaces; i++) { |
763 | if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) { | 766 | cur_intf = usb_ifnum_to_if(usb_dev, i); |
767 | if (cur_intf) { | ||
764 | usb_set_intfdata(cur_intf, NULL); | 768 | usb_set_intfdata(cur_intf, NULL); |
765 | usb_driver_release_interface(&speedtch_usb_driver, cur_intf); | 769 | usb_driver_release_interface(&speedtch_usb_driver, cur_intf); |
766 | } | 770 | } |
771 | } | ||
767 | } | 772 | } |
768 | 773 | ||
769 | static int speedtch_bind(struct usbatm_data *usbatm, | 774 | static int speedtch_bind(struct usbatm_data *usbatm, |
@@ -787,7 +792,8 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
787 | return -ENODEV; | 792 | return -ENODEV; |
788 | } | 793 | } |
789 | 794 | ||
790 | if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) { | 795 | data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA); |
796 | if (!data_intf) { | ||
791 | usb_err(usbatm, "%s: data interface not found!\n", __func__); | 797 | usb_err(usbatm, "%s: data interface not found!\n", __func__); |
792 | return -ENODEV; | 798 | return -ENODEV; |
793 | } | 799 | } |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index dada0146cd7f..db322d9ccb6e 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -382,7 +382,8 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char | |||
382 | "%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", | 382 | "%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", |
383 | __func__, length, pdu_length, vcc); | 383 | __func__, length, pdu_length, vcc); |
384 | 384 | ||
385 | if (!(skb = dev_alloc_skb(length))) { | 385 | skb = dev_alloc_skb(length); |
386 | if (!skb) { | ||
386 | if (printk_ratelimit()) | 387 | if (printk_ratelimit()) |
387 | atm_err(instance, "%s: no memory for skb (length: %u)!\n", | 388 | atm_err(instance, "%s: no memory for skb (length: %u)!\n", |
388 | __func__, length); | 389 | __func__, length); |
@@ -816,7 +817,8 @@ static int usbatm_atm_open(struct atm_vcc *vcc) | |||
816 | goto fail; | 817 | goto fail; |
817 | } | 818 | } |
818 | 819 | ||
819 | if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) { | 820 | new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL); |
821 | if (!new) { | ||
820 | atm_err(instance, "%s: no memory for vcc_data!\n", __func__); | 822 | atm_err(instance, "%s: no memory for vcc_data!\n", __func__); |
821 | ret = -ENOMEM; | 823 | ret = -ENOMEM; |
822 | goto fail; | 824 | goto fail; |
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index b3b1bb78b2ef..a87597f88a84 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c | |||
@@ -73,7 +73,8 @@ static int xusbatm_capture_intf(struct usbatm_data *usbatm, struct usb_device *u | |||
73 | usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, ifnum, ret); | 73 | usb_err(usbatm, "%s: failed to claim interface %2d (%d)!\n", __func__, ifnum, ret); |
74 | return ret; | 74 | return ret; |
75 | } | 75 | } |
76 | if ((ret = usb_set_interface(usb_dev, ifnum, altsetting))) { | 76 | ret = usb_set_interface(usb_dev, ifnum, altsetting); |
77 | if (ret) { | ||
77 | usb_err(usbatm, "%s: altsetting %2d for interface %2d failed (%d)!\n", __func__, altsetting, ifnum, ret); | 78 | usb_err(usbatm, "%s: altsetting %2d for interface %2d failed (%d)!\n", __func__, altsetting, ifnum, ret); |
78 | return ret; | 79 | return ret; |
79 | } | 80 | } |
@@ -128,7 +129,8 @@ static int xusbatm_bind(struct usbatm_data *usbatm, | |||
128 | rx_intf->altsetting->desc.bInterfaceNumber, | 129 | rx_intf->altsetting->desc.bInterfaceNumber, |
129 | tx_intf->altsetting->desc.bInterfaceNumber); | 130 | tx_intf->altsetting->desc.bInterfaceNumber); |
130 | 131 | ||
131 | if ((ret = xusbatm_capture_intf(usbatm, usb_dev, rx_intf, rx_alt, rx_intf != intf))) | 132 | ret = xusbatm_capture_intf(usbatm, usb_dev, rx_intf, rx_alt, rx_intf != intf); |
133 | if (ret) | ||
132 | return ret; | 134 | return ret; |
133 | 135 | ||
134 | if ((tx_intf != rx_intf) && (ret = xusbatm_capture_intf(usbatm, usb_dev, tx_intf, tx_alt, tx_intf != intf))) { | 136 | if ((tx_intf != rx_intf) && (ret = xusbatm_capture_intf(usbatm, usb_dev, tx_intf, tx_alt, tx_intf != intf))) { |
diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index 45844c951788..9eae1a16cef9 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c | |||
@@ -25,7 +25,7 @@ struct ci_hdrc_usb2_priv { | |||
25 | struct clk *clk; | 25 | struct clk *clk; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static struct ci_hdrc_platform_data ci_default_pdata = { | 28 | static const struct ci_hdrc_platform_data ci_default_pdata = { |
29 | .capoffset = DEF_CAPOFFSET, | 29 | .capoffset = DEF_CAPOFFSET, |
30 | .flags = CI_HDRC_DISABLE_STREAMING, | 30 | .flags = CI_HDRC_DISABLE_STREAMING, |
31 | }; | 31 | }; |
@@ -37,8 +37,10 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev) | |||
37 | struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); | 37 | struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); |
38 | int ret; | 38 | int ret; |
39 | 39 | ||
40 | if (!ci_pdata) | 40 | if (!ci_pdata) { |
41 | ci_pdata = &ci_default_pdata; | 41 | ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL); |
42 | *ci_pdata = ci_default_pdata; /* struct copy */ | ||
43 | } | ||
42 | 44 | ||
43 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 45 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
44 | if (!priv) | 46 | if (!priv) |
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 21fe1a314313..6cf87b8b13a8 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c | |||
@@ -37,12 +37,14 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd); | |||
37 | 37 | ||
38 | struct ehci_ci_priv { | 38 | struct ehci_ci_priv { |
39 | struct regulator *reg_vbus; | 39 | struct regulator *reg_vbus; |
40 | struct ci_hdrc *ci; | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) | 43 | static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) |
43 | { | 44 | { |
44 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 45 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
45 | struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; | 46 | struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; |
47 | struct ci_hdrc *ci = priv->ci; | ||
46 | struct device *dev = hcd->self.controller; | 48 | struct device *dev = hcd->self.controller; |
47 | int ret = 0; | 49 | int ret = 0; |
48 | int port = HCS_N_PORTS(ehci->hcs_params); | 50 | int port = HCS_N_PORTS(ehci->hcs_params); |
@@ -64,6 +66,15 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable) | |||
64 | return ret; | 66 | return ret; |
65 | } | 67 | } |
66 | } | 68 | } |
69 | |||
70 | if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) { | ||
71 | /* | ||
72 | * Marvell 28nm HSIC PHY requires forcing the port to HS mode. | ||
73 | * As HSIC is always HS, this should be safe for others. | ||
74 | */ | ||
75 | hw_port_test_set(ci, 5); | ||
76 | hw_port_test_set(ci, 0); | ||
77 | } | ||
67 | return 0; | 78 | return 0; |
68 | }; | 79 | }; |
69 | 80 | ||
@@ -112,6 +123,7 @@ static int host_start(struct ci_hdrc *ci) | |||
112 | 123 | ||
113 | priv = (struct ehci_ci_priv *)ehci->priv; | 124 | priv = (struct ehci_ci_priv *)ehci->priv; |
114 | priv->reg_vbus = NULL; | 125 | priv->reg_vbus = NULL; |
126 | priv->ci = ci; | ||
115 | 127 | ||
116 | if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { | 128 | if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) { |
117 | if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { | 129 | if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) { |
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 140945cb124f..3cefd49ddb00 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c | |||
@@ -160,7 +160,7 @@ static int usbmisc_imx27_init(struct imx_usbmisc_data *data) | |||
160 | break; | 160 | break; |
161 | default: | 161 | default: |
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | }; | 163 | } |
164 | 164 | ||
165 | spin_lock_irqsave(&usbmisc->lock, flags); | 165 | spin_lock_irqsave(&usbmisc->lock, flags); |
166 | if (data->disable_oc) | 166 | if (data->disable_oc) |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5c8f58114677..519a77ba214c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/usb/cdc.h> | 46 | #include <linux/usb/cdc.h> |
47 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
48 | #include <asm/unaligned.h> | 48 | #include <asm/unaligned.h> |
49 | #include <linux/idr.h> | ||
49 | #include <linux/list.h> | 50 | #include <linux/list.h> |
50 | 51 | ||
51 | #include "cdc-acm.h" | 52 | #include "cdc-acm.h" |
@@ -56,27 +57,27 @@ | |||
56 | 57 | ||
57 | static struct usb_driver acm_driver; | 58 | static struct usb_driver acm_driver; |
58 | static struct tty_driver *acm_tty_driver; | 59 | static struct tty_driver *acm_tty_driver; |
59 | static struct acm *acm_table[ACM_TTY_MINORS]; | ||
60 | 60 | ||
61 | static DEFINE_MUTEX(acm_table_lock); | 61 | static DEFINE_IDR(acm_minors); |
62 | static DEFINE_MUTEX(acm_minors_lock); | ||
62 | 63 | ||
63 | static void acm_tty_set_termios(struct tty_struct *tty, | 64 | static void acm_tty_set_termios(struct tty_struct *tty, |
64 | struct ktermios *termios_old); | 65 | struct ktermios *termios_old); |
65 | 66 | ||
66 | /* | 67 | /* |
67 | * acm_table accessors | 68 | * acm_minors accessors |
68 | */ | 69 | */ |
69 | 70 | ||
70 | /* | 71 | /* |
71 | * Look up an ACM structure by index. If found and not disconnected, increment | 72 | * Look up an ACM structure by minor. If found and not disconnected, increment |
72 | * its refcount and return it with its mutex held. | 73 | * its refcount and return it with its mutex held. |
73 | */ | 74 | */ |
74 | static struct acm *acm_get_by_index(unsigned index) | 75 | static struct acm *acm_get_by_minor(unsigned int minor) |
75 | { | 76 | { |
76 | struct acm *acm; | 77 | struct acm *acm; |
77 | 78 | ||
78 | mutex_lock(&acm_table_lock); | 79 | mutex_lock(&acm_minors_lock); |
79 | acm = acm_table[index]; | 80 | acm = idr_find(&acm_minors, minor); |
80 | if (acm) { | 81 | if (acm) { |
81 | mutex_lock(&acm->mutex); | 82 | mutex_lock(&acm->mutex); |
82 | if (acm->disconnected) { | 83 | if (acm->disconnected) { |
@@ -87,7 +88,7 @@ static struct acm *acm_get_by_index(unsigned index) | |||
87 | mutex_unlock(&acm->mutex); | 88 | mutex_unlock(&acm->mutex); |
88 | } | 89 | } |
89 | } | 90 | } |
90 | mutex_unlock(&acm_table_lock); | 91 | mutex_unlock(&acm_minors_lock); |
91 | return acm; | 92 | return acm; |
92 | } | 93 | } |
93 | 94 | ||
@@ -98,14 +99,9 @@ static int acm_alloc_minor(struct acm *acm) | |||
98 | { | 99 | { |
99 | int minor; | 100 | int minor; |
100 | 101 | ||
101 | mutex_lock(&acm_table_lock); | 102 | mutex_lock(&acm_minors_lock); |
102 | for (minor = 0; minor < ACM_TTY_MINORS; minor++) { | 103 | minor = idr_alloc(&acm_minors, acm, 0, ACM_TTY_MINORS, GFP_KERNEL); |
103 | if (!acm_table[minor]) { | 104 | mutex_unlock(&acm_minors_lock); |
104 | acm_table[minor] = acm; | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | mutex_unlock(&acm_table_lock); | ||
109 | 105 | ||
110 | return minor; | 106 | return minor; |
111 | } | 107 | } |
@@ -113,9 +109,9 @@ static int acm_alloc_minor(struct acm *acm) | |||
113 | /* Release the minor number associated with 'acm'. */ | 109 | /* Release the minor number associated with 'acm'. */ |
114 | static void acm_release_minor(struct acm *acm) | 110 | static void acm_release_minor(struct acm *acm) |
115 | { | 111 | { |
116 | mutex_lock(&acm_table_lock); | 112 | mutex_lock(&acm_minors_lock); |
117 | acm_table[acm->minor] = NULL; | 113 | idr_remove(&acm_minors, acm->minor); |
118 | mutex_unlock(&acm_table_lock); | 114 | mutex_unlock(&acm_minors_lock); |
119 | } | 115 | } |
120 | 116 | ||
121 | /* | 117 | /* |
@@ -497,7 +493,7 @@ static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
497 | 493 | ||
498 | dev_dbg(tty->dev, "%s\n", __func__); | 494 | dev_dbg(tty->dev, "%s\n", __func__); |
499 | 495 | ||
500 | acm = acm_get_by_index(tty->index); | 496 | acm = acm_get_by_minor(tty->index); |
501 | if (!acm) | 497 | if (!acm) |
502 | return -ENODEV; | 498 | return -ENODEV; |
503 | 499 | ||
@@ -1267,12 +1263,9 @@ skip_normal_probe: | |||
1267 | != CDC_DATA_INTERFACE_TYPE) { | 1263 | != CDC_DATA_INTERFACE_TYPE) { |
1268 | if (control_interface->cur_altsetting->desc.bInterfaceClass | 1264 | if (control_interface->cur_altsetting->desc.bInterfaceClass |
1269 | == CDC_DATA_INTERFACE_TYPE) { | 1265 | == CDC_DATA_INTERFACE_TYPE) { |
1270 | struct usb_interface *t; | ||
1271 | dev_dbg(&intf->dev, | 1266 | dev_dbg(&intf->dev, |
1272 | "Your device has switched interfaces.\n"); | 1267 | "Your device has switched interfaces.\n"); |
1273 | t = control_interface; | 1268 | swap(control_interface, data_interface); |
1274 | control_interface = data_interface; | ||
1275 | data_interface = t; | ||
1276 | } else { | 1269 | } else { |
1277 | return -EINVAL; | 1270 | return -EINVAL; |
1278 | } | 1271 | } |
@@ -1301,12 +1294,9 @@ skip_normal_probe: | |||
1301 | /* workaround for switched endpoints */ | 1294 | /* workaround for switched endpoints */ |
1302 | if (!usb_endpoint_dir_in(epread)) { | 1295 | if (!usb_endpoint_dir_in(epread)) { |
1303 | /* descriptors are swapped */ | 1296 | /* descriptors are swapped */ |
1304 | struct usb_endpoint_descriptor *t; | ||
1305 | dev_dbg(&intf->dev, | 1297 | dev_dbg(&intf->dev, |
1306 | "The data interface has switched endpoints\n"); | 1298 | "The data interface has switched endpoints\n"); |
1307 | t = epread; | 1299 | swap(epread, epwrite); |
1308 | epread = epwrite; | ||
1309 | epwrite = t; | ||
1310 | } | 1300 | } |
1311 | made_compressed_probe: | 1301 | made_compressed_probe: |
1312 | dev_dbg(&intf->dev, "interfaces are valid\n"); | 1302 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
@@ -1316,7 +1306,7 @@ made_compressed_probe: | |||
1316 | goto alloc_fail; | 1306 | goto alloc_fail; |
1317 | 1307 | ||
1318 | minor = acm_alloc_minor(acm); | 1308 | minor = acm_alloc_minor(acm); |
1319 | if (minor == ACM_TTY_MINORS) { | 1309 | if (minor < 0) { |
1320 | dev_err(&intf->dev, "no more free acm devices\n"); | 1310 | dev_err(&intf->dev, "no more free acm devices\n"); |
1321 | kfree(acm); | 1311 | kfree(acm); |
1322 | return -ENODEV; | 1312 | return -ENODEV; |
@@ -1477,6 +1467,11 @@ skip_countries: | |||
1477 | goto alloc_fail8; | 1467 | goto alloc_fail8; |
1478 | } | 1468 | } |
1479 | 1469 | ||
1470 | if (quirks & CLEAR_HALT_CONDITIONS) { | ||
1471 | usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress)); | ||
1472 | usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress)); | ||
1473 | } | ||
1474 | |||
1480 | return 0; | 1475 | return 0; |
1481 | alloc_fail8: | 1476 | alloc_fail8: |
1482 | if (acm->country_codes) { | 1477 | if (acm->country_codes) { |
@@ -1756,6 +1751,10 @@ static const struct usb_device_id acm_ids[] = { | |||
1756 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ | 1751 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ |
1757 | }, | 1752 | }, |
1758 | 1753 | ||
1754 | { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ | ||
1755 | .driver_info = CLEAR_HALT_CONDITIONS, | ||
1756 | }, | ||
1757 | |||
1759 | /* Nokia S60 phones expose two ACM channels. The first is | 1758 | /* Nokia S60 phones expose two ACM channels. The first is |
1760 | * a modem and is picked up by the standard AT-command | 1759 | * a modem and is picked up by the standard AT-command |
1761 | * information below. The second is 'vendor-specific' but | 1760 | * information below. The second is 'vendor-specific' but |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index ffeb3c83941f..dd9af38e7cda 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define ACM_TTY_MAJOR 166 | 21 | #define ACM_TTY_MAJOR 166 |
22 | #define ACM_TTY_MINORS 32 | 22 | #define ACM_TTY_MINORS 256 |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * Requests. | 25 | * Requests. |
@@ -133,3 +133,4 @@ struct acm { | |||
133 | #define NO_DATA_INTERFACE BIT(4) | 133 | #define NO_DATA_INTERFACE BIT(4) |
134 | #define IGNORE_DEVICE BIT(5) | 134 | #define IGNORE_DEVICE BIT(5) |
135 | #define QUIRK_CONTROL_LINE_STATE BIT(6) | 135 | #define QUIRK_CONTROL_LINE_STATE BIT(6) |
136 | #define CLEAR_HALT_CONDITIONS BIT(7) | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 0924ee40a966..f38e875a3fb1 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -660,7 +660,8 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
660 | switch (cmd) { | 660 | switch (cmd) { |
661 | 661 | ||
662 | case LPGETSTATUS: | 662 | case LPGETSTATUS: |
663 | if ((retval = usblp_read_status(usblp, usblp->statusbuf))) { | 663 | retval = usblp_read_status(usblp, usblp->statusbuf); |
664 | if (retval) { | ||
664 | printk_ratelimited(KERN_ERR "usblp%d:" | 665 | printk_ratelimited(KERN_ERR "usblp%d:" |
665 | "failed reading printer status (%d)\n", | 666 | "failed reading printer status (%d)\n", |
666 | usblp->minor, retval); | 667 | usblp->minor, retval); |
@@ -693,9 +694,11 @@ static struct urb *usblp_new_writeurb(struct usblp *usblp, int transfer_length) | |||
693 | struct urb *urb; | 694 | struct urb *urb; |
694 | char *writebuf; | 695 | char *writebuf; |
695 | 696 | ||
696 | if ((writebuf = kmalloc(transfer_length, GFP_KERNEL)) == NULL) | 697 | writebuf = kmalloc(transfer_length, GFP_KERNEL); |
698 | if (writebuf == NULL) | ||
697 | return NULL; | 699 | return NULL; |
698 | if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { | 700 | urb = usb_alloc_urb(0, GFP_KERNEL); |
701 | if (urb == NULL) { | ||
699 | kfree(writebuf); | 702 | kfree(writebuf); |
700 | return NULL; | 703 | return NULL; |
701 | } | 704 | } |
@@ -732,7 +735,8 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
732 | transfer_length = USBLP_BUF_SIZE; | 735 | transfer_length = USBLP_BUF_SIZE; |
733 | 736 | ||
734 | rv = -ENOMEM; | 737 | rv = -ENOMEM; |
735 | if ((writeurb = usblp_new_writeurb(usblp, transfer_length)) == NULL) | 738 | writeurb = usblp_new_writeurb(usblp, transfer_length); |
739 | if (writeurb == NULL) | ||
736 | goto raise_urb; | 740 | goto raise_urb; |
737 | usb_anchor_urb(writeurb, &usblp->urbs); | 741 | usb_anchor_urb(writeurb, &usblp->urbs); |
738 | 742 | ||
@@ -980,7 +984,8 @@ static int usblp_submit_read(struct usblp *usblp) | |||
980 | int rc; | 984 | int rc; |
981 | 985 | ||
982 | rc = -ENOMEM; | 986 | rc = -ENOMEM; |
983 | if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) | 987 | urb = usb_alloc_urb(0, GFP_KERNEL); |
988 | if (urb == NULL) | ||
984 | goto raise_urb; | 989 | goto raise_urb; |
985 | 990 | ||
986 | usb_fill_bulk_urb(urb, usblp->dev, | 991 | usb_fill_bulk_urb(urb, usblp->dev, |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 960bc089111b..7a11a8263171 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -109,6 +109,7 @@ struct usbtmc_ID_rigol_quirk { | |||
109 | 109 | ||
110 | static const struct usbtmc_ID_rigol_quirk usbtmc_id_quirk[] = { | 110 | static const struct usbtmc_ID_rigol_quirk usbtmc_id_quirk[] = { |
111 | { 0x1ab1, 0x0588 }, | 111 | { 0x1ab1, 0x0588 }, |
112 | { 0x1ab1, 0x04b0 }, | ||
112 | { 0, 0 } | 113 | { 0, 0 } |
113 | }; | 114 | }; |
114 | 115 | ||
diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile index ca2f8bd0e431..6bbb3ec17018 100644 --- a/drivers/usb/common/Makefile +++ b/drivers/usb/common/Makefile | |||
@@ -7,3 +7,4 @@ usb-common-y += common.o | |||
7 | usb-common-$(CONFIG_USB_LED_TRIG) += led.o | 7 | usb-common-$(CONFIG_USB_LED_TRIG) += led.o |
8 | 8 | ||
9 | obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o | 9 | obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o |
10 | obj-$(CONFIG_USB_ULPI_BUS) += ulpi.o | ||
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c new file mode 100644 index 000000000000..0e6f968e93fe --- /dev/null +++ b/drivers/usb/common/ulpi.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /** | ||
2 | * ulpi.c - USB ULPI PHY bus | ||
3 | * | ||
4 | * Copyright (C) 2015 Intel Corporation | ||
5 | * | ||
6 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/ulpi/interface.h> | ||
14 | #include <linux/ulpi/driver.h> | ||
15 | #include <linux/ulpi/regs.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/acpi.h> | ||
19 | |||
20 | /* -------------------------------------------------------------------------- */ | ||
21 | |||
22 | int ulpi_read(struct ulpi *ulpi, u8 addr) | ||
23 | { | ||
24 | return ulpi->ops->read(ulpi->ops, addr); | ||
25 | } | ||
26 | EXPORT_SYMBOL_GPL(ulpi_read); | ||
27 | |||
28 | int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val) | ||
29 | { | ||
30 | return ulpi->ops->write(ulpi->ops, addr, val); | ||
31 | } | ||
32 | EXPORT_SYMBOL_GPL(ulpi_write); | ||
33 | |||
34 | /* -------------------------------------------------------------------------- */ | ||
35 | |||
36 | static int ulpi_match(struct device *dev, struct device_driver *driver) | ||
37 | { | ||
38 | struct ulpi_driver *drv = to_ulpi_driver(driver); | ||
39 | struct ulpi *ulpi = to_ulpi_dev(dev); | ||
40 | const struct ulpi_device_id *id; | ||
41 | |||
42 | for (id = drv->id_table; id->vendor; id++) | ||
43 | if (id->vendor == ulpi->id.vendor && | ||
44 | id->product == ulpi->id.product) | ||
45 | return 1; | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
51 | { | ||
52 | struct ulpi *ulpi = to_ulpi_dev(dev); | ||
53 | |||
54 | if (add_uevent_var(env, "MODALIAS=ulpi:v%04xp%04x", | ||
55 | ulpi->id.vendor, ulpi->id.product)) | ||
56 | return -ENOMEM; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int ulpi_probe(struct device *dev) | ||
61 | { | ||
62 | struct ulpi_driver *drv = to_ulpi_driver(dev->driver); | ||
63 | |||
64 | return drv->probe(to_ulpi_dev(dev)); | ||
65 | } | ||
66 | |||
67 | static int ulpi_remove(struct device *dev) | ||
68 | { | ||
69 | struct ulpi_driver *drv = to_ulpi_driver(dev->driver); | ||
70 | |||
71 | if (drv->remove) | ||
72 | drv->remove(to_ulpi_dev(dev)); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static struct bus_type ulpi_bus = { | ||
78 | .name = "ulpi", | ||
79 | .match = ulpi_match, | ||
80 | .uevent = ulpi_uevent, | ||
81 | .probe = ulpi_probe, | ||
82 | .remove = ulpi_remove, | ||
83 | }; | ||
84 | |||
85 | /* -------------------------------------------------------------------------- */ | ||
86 | |||
87 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | ||
88 | char *buf) | ||
89 | { | ||
90 | struct ulpi *ulpi = to_ulpi_dev(dev); | ||
91 | |||
92 | return sprintf(buf, "ulpi:v%04xp%04x\n", | ||
93 | ulpi->id.vendor, ulpi->id.product); | ||
94 | } | ||
95 | static DEVICE_ATTR_RO(modalias); | ||
96 | |||
97 | static struct attribute *ulpi_dev_attrs[] = { | ||
98 | &dev_attr_modalias.attr, | ||
99 | NULL | ||
100 | }; | ||
101 | |||
102 | static struct attribute_group ulpi_dev_attr_group = { | ||
103 | .attrs = ulpi_dev_attrs, | ||
104 | }; | ||
105 | |||
106 | static const struct attribute_group *ulpi_dev_attr_groups[] = { | ||
107 | &ulpi_dev_attr_group, | ||
108 | NULL | ||
109 | }; | ||
110 | |||
111 | static void ulpi_dev_release(struct device *dev) | ||
112 | { | ||
113 | kfree(to_ulpi_dev(dev)); | ||
114 | } | ||
115 | |||
116 | static struct device_type ulpi_dev_type = { | ||
117 | .name = "ulpi_device", | ||
118 | .groups = ulpi_dev_attr_groups, | ||
119 | .release = ulpi_dev_release, | ||
120 | }; | ||
121 | |||
122 | /* -------------------------------------------------------------------------- */ | ||
123 | |||
124 | /** | ||
125 | * ulpi_register_driver - register a driver with the ULPI bus | ||
126 | * @drv: driver being registered | ||
127 | * | ||
128 | * Registers a driver with the ULPI bus. | ||
129 | */ | ||
130 | int ulpi_register_driver(struct ulpi_driver *drv) | ||
131 | { | ||
132 | if (!drv->probe) | ||
133 | return -EINVAL; | ||
134 | |||
135 | drv->driver.bus = &ulpi_bus; | ||
136 | |||
137 | return driver_register(&drv->driver); | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(ulpi_register_driver); | ||
140 | |||
141 | /** | ||
142 | * ulpi_unregister_driver - unregister a driver with the ULPI bus | ||
143 | * @drv: driver to unregister | ||
144 | * | ||
145 | * Unregisters a driver with the ULPI bus. | ||
146 | */ | ||
147 | void ulpi_unregister_driver(struct ulpi_driver *drv) | ||
148 | { | ||
149 | driver_unregister(&drv->driver); | ||
150 | } | ||
151 | EXPORT_SYMBOL_GPL(ulpi_unregister_driver); | ||
152 | |||
153 | /* -------------------------------------------------------------------------- */ | ||
154 | |||
155 | static int ulpi_register(struct device *dev, struct ulpi *ulpi) | ||
156 | { | ||
157 | int ret; | ||
158 | |||
159 | /* Test the interface */ | ||
160 | ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa); | ||
161 | if (ret < 0) | ||
162 | return ret; | ||
163 | |||
164 | ret = ulpi_read(ulpi, ULPI_SCRATCH); | ||
165 | if (ret < 0) | ||
166 | return ret; | ||
167 | |||
168 | if (ret != 0xaa) | ||
169 | return -ENODEV; | ||
170 | |||
171 | ulpi->id.vendor = ulpi_read(ulpi, ULPI_VENDOR_ID_LOW); | ||
172 | ulpi->id.vendor |= ulpi_read(ulpi, ULPI_VENDOR_ID_HIGH) << 8; | ||
173 | |||
174 | ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW); | ||
175 | ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8; | ||
176 | |||
177 | ulpi->dev.parent = dev; | ||
178 | ulpi->dev.bus = &ulpi_bus; | ||
179 | ulpi->dev.type = &ulpi_dev_type; | ||
180 | dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev)); | ||
181 | |||
182 | ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev)); | ||
183 | |||
184 | request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product); | ||
185 | |||
186 | ret = device_register(&ulpi->dev); | ||
187 | if (ret) | ||
188 | return ret; | ||
189 | |||
190 | dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n", | ||
191 | ulpi->id.vendor, ulpi->id.product); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * ulpi_register_interface - instantiate new ULPI device | ||
198 | * @dev: USB controller's device interface | ||
199 | * @ops: ULPI register access | ||
200 | * | ||
201 | * Allocates and registers a ULPI device and an interface for it. Called from | ||
202 | * the USB controller that provides the ULPI interface. | ||
203 | */ | ||
204 | struct ulpi *ulpi_register_interface(struct device *dev, struct ulpi_ops *ops) | ||
205 | { | ||
206 | struct ulpi *ulpi; | ||
207 | int ret; | ||
208 | |||
209 | ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); | ||
210 | if (!ulpi) | ||
211 | return ERR_PTR(-ENOMEM); | ||
212 | |||
213 | ulpi->ops = ops; | ||
214 | ops->dev = dev; | ||
215 | |||
216 | ret = ulpi_register(dev, ulpi); | ||
217 | if (ret) { | ||
218 | kfree(ulpi); | ||
219 | return ERR_PTR(ret); | ||
220 | } | ||
221 | |||
222 | return ulpi; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(ulpi_register_interface); | ||
225 | |||
226 | /** | ||
227 | * ulpi_unregister_interface - unregister ULPI interface | ||
228 | * @intrf: struct ulpi_interface | ||
229 | * | ||
230 | * Unregisters a ULPI device and it's interface that was created with | ||
231 | * ulpi_create_interface(). | ||
232 | */ | ||
233 | void ulpi_unregister_interface(struct ulpi *ulpi) | ||
234 | { | ||
235 | device_unregister(&ulpi->dev); | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(ulpi_unregister_interface); | ||
238 | |||
239 | /* -------------------------------------------------------------------------- */ | ||
240 | |||
241 | static int __init ulpi_init(void) | ||
242 | { | ||
243 | return bus_register(&ulpi_bus); | ||
244 | } | ||
245 | module_init(ulpi_init); | ||
246 | |||
247 | static void __exit ulpi_exit(void) | ||
248 | { | ||
249 | bus_unregister(&ulpi_bus); | ||
250 | } | ||
251 | module_exit(ulpi_exit); | ||
252 | |||
253 | MODULE_AUTHOR("Intel Corporation"); | ||
254 | MODULE_LICENSE("GPL v2"); | ||
255 | MODULE_DESCRIPTION("USB ULPI PHY bus"); | ||
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index cc0ced08bae2..a99c89e78126 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -84,3 +84,23 @@ config USB_OTG_FSM | |||
84 | Implements OTG Finite State Machine as specified in On-The-Go | 84 | Implements OTG Finite State Machine as specified in On-The-Go |
85 | and Embedded Host Supplement to the USB Revision 2.0 Specification. | 85 | and Embedded Host Supplement to the USB Revision 2.0 Specification. |
86 | 86 | ||
87 | config USB_ULPI_BUS | ||
88 | tristate "USB ULPI PHY interface support" | ||
89 | depends on USB_SUPPORT | ||
90 | help | ||
91 | UTMI+ Low Pin Interface (ULPI) is specification for a commonly used | ||
92 | USB 2.0 PHY interface. The ULPI specification defines a standard set | ||
93 | of registers that can be used to detect the vendor and product which | ||
94 | allows ULPI to be handled as a bus. This module is the driver for that | ||
95 | bus. | ||
96 | |||
97 | The ULPI interfaces (the buses) are registered by the drivers for USB | ||
98 | controllers which support ULPI register access and have ULPI PHY | ||
99 | attached to them. The ULPI PHY drivers themselves are normal PHY | ||
100 | drivers. | ||
101 | |||
102 | ULPI PHYs provide often functions such as ADP sensing/probing (OTG | ||
103 | protocol) and USB charger detection. | ||
104 | |||
105 | To compile this driver as a module, choose M here: the module will | ||
106 | be called ulpi. | ||
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 506b969ea7fd..89f2e7765093 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -70,7 +70,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) | |||
70 | size = pool_max[i]; | 70 | size = pool_max[i]; |
71 | if (!size) | 71 | if (!size) |
72 | continue; | 72 | continue; |
73 | snprintf(name, sizeof name, "buffer-%d", size); | 73 | snprintf(name, sizeof(name), "buffer-%d", size); |
74 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, | 74 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, |
75 | size, size, 0); | 75 | size, size, 0); |
76 | if (!hcd->pool[i]) { | 76 | if (!hcd->pool[i]) { |
@@ -95,6 +95,7 @@ void hcd_buffer_destroy(struct usb_hcd *hcd) | |||
95 | 95 | ||
96 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 96 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
97 | struct dma_pool *pool = hcd->pool[i]; | 97 | struct dma_pool *pool = hcd->pool[i]; |
98 | |||
98 | if (pool) { | 99 | if (pool) { |
99 | dma_pool_destroy(pool); | 100 | dma_pool_destroy(pool); |
100 | hcd->pool[i] = NULL; | 101 | hcd->pool[i] = NULL; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4b0448c26810..986abde07683 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -513,7 +513,7 @@ static void async_completed(struct urb *urb) | |||
513 | snoop(&urb->dev->dev, "urb complete\n"); | 513 | snoop(&urb->dev->dev, "urb complete\n"); |
514 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, | 514 | snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length, |
515 | as->status, COMPLETE, NULL, 0); | 515 | as->status, COMPLETE, NULL, 0); |
516 | if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN) | 516 | if ((urb->transfer_flags & URB_DIR_MASK) == URB_DIR_IN) |
517 | snoop_urb_data(urb, urb->actual_length); | 517 | snoop_urb_data(urb, urb->actual_length); |
518 | 518 | ||
519 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && | 519 | if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 45a915ccd71c..be5b2074f906 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -2691,7 +2691,8 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2691 | if ((retval = usb_register_bus(&hcd->self)) < 0) | 2691 | if ((retval = usb_register_bus(&hcd->self)) < 0) |
2692 | goto err_register_bus; | 2692 | goto err_register_bus; |
2693 | 2693 | ||
2694 | if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) { | 2694 | rhdev = usb_alloc_dev(NULL, &hcd->self, 0); |
2695 | if (rhdev == NULL) { | ||
2695 | dev_err(hcd->self.controller, "unable to allocate root hub\n"); | 2696 | dev_err(hcd->self.controller, "unable to allocate root hub\n"); |
2696 | retval = -ENOMEM; | 2697 | retval = -ENOMEM; |
2697 | goto err_allocate_root_hub; | 2698 | goto err_allocate_root_hub; |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 3b7151687776..43cb2f2e3b43 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -127,7 +127,7 @@ static int usb_device_supports_lpm(struct usb_device *udev) | |||
127 | /* USB 2.1 (and greater) devices indicate LPM support through | 127 | /* USB 2.1 (and greater) devices indicate LPM support through |
128 | * their USB 2.0 Extended Capabilities BOS descriptor. | 128 | * their USB 2.0 Extended Capabilities BOS descriptor. |
129 | */ | 129 | */ |
130 | if (udev->speed == USB_SPEED_HIGH) { | 130 | if (udev->speed == USB_SPEED_HIGH || udev->speed == USB_SPEED_FULL) { |
131 | if (udev->bos->ext_cap && | 131 | if (udev->bos->ext_cap && |
132 | (USB_LPM_SUPPORT & | 132 | (USB_LPM_SUPPORT & |
133 | le32_to_cpu(udev->bos->ext_cap->bmAttributes))) | 133 | le32_to_cpu(udev->bos->ext_cap->bmAttributes))) |
@@ -795,7 +795,8 @@ int usb_hub_clear_tt_buffer(struct urb *urb) | |||
795 | * since each TT has "at least two" buffers that can need it (and | 795 | * since each TT has "at least two" buffers that can need it (and |
796 | * there can be many TTs per hub). even if they're uncommon. | 796 | * there can be many TTs per hub). even if they're uncommon. |
797 | */ | 797 | */ |
798 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { | 798 | clear = kmalloc(sizeof *clear, GFP_ATOMIC); |
799 | if (clear == NULL) { | ||
799 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); | 800 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); |
800 | /* FIXME recover somehow ... RESET_TT? */ | 801 | /* FIXME recover somehow ... RESET_TT? */ |
801 | return -ENOMEM; | 802 | return -ENOMEM; |
@@ -2350,6 +2351,26 @@ static void set_usb_port_removable(struct usb_device *udev) | |||
2350 | 2351 | ||
2351 | hub = usb_hub_to_struct_hub(udev->parent); | 2352 | hub = usb_hub_to_struct_hub(udev->parent); |
2352 | 2353 | ||
2354 | /* | ||
2355 | * If the platform firmware has provided information about a port, | ||
2356 | * use that to determine whether it's removable. | ||
2357 | */ | ||
2358 | switch (hub->ports[udev->portnum - 1]->connect_type) { | ||
2359 | case USB_PORT_CONNECT_TYPE_HOT_PLUG: | ||
2360 | udev->removable = USB_DEVICE_REMOVABLE; | ||
2361 | return; | ||
2362 | case USB_PORT_CONNECT_TYPE_HARD_WIRED: | ||
2363 | case USB_PORT_NOT_USED: | ||
2364 | udev->removable = USB_DEVICE_FIXED; | ||
2365 | return; | ||
2366 | default: | ||
2367 | break; | ||
2368 | } | ||
2369 | |||
2370 | /* | ||
2371 | * Otherwise, check whether the hub knows whether a port is removable | ||
2372 | * or not | ||
2373 | */ | ||
2353 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | 2374 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
2354 | 2375 | ||
2355 | if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) | 2376 | if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) |
@@ -2369,21 +2390,6 @@ static void set_usb_port_removable(struct usb_device *udev) | |||
2369 | else | 2390 | else |
2370 | udev->removable = USB_DEVICE_FIXED; | 2391 | udev->removable = USB_DEVICE_FIXED; |
2371 | 2392 | ||
2372 | /* | ||
2373 | * Platform firmware may have populated an alternative value for | ||
2374 | * removable. If the parent port has a known connect_type use | ||
2375 | * that instead. | ||
2376 | */ | ||
2377 | switch (hub->ports[udev->portnum - 1]->connect_type) { | ||
2378 | case USB_PORT_CONNECT_TYPE_HOT_PLUG: | ||
2379 | udev->removable = USB_DEVICE_REMOVABLE; | ||
2380 | break; | ||
2381 | case USB_PORT_CONNECT_TYPE_HARD_WIRED: | ||
2382 | udev->removable = USB_DEVICE_FIXED; | ||
2383 | break; | ||
2384 | default: /* use what was set above */ | ||
2385 | break; | ||
2386 | } | ||
2387 | } | 2393 | } |
2388 | 2394 | ||
2389 | /** | 2395 | /** |
@@ -2616,9 +2622,6 @@ static bool use_new_scheme(struct usb_device *udev, int retry) | |||
2616 | return USE_NEW_SCHEME(retry); | 2622 | return USE_NEW_SCHEME(retry); |
2617 | } | 2623 | } |
2618 | 2624 | ||
2619 | static int hub_port_reset(struct usb_hub *hub, int port1, | ||
2620 | struct usb_device *udev, unsigned int delay, bool warm); | ||
2621 | |||
2622 | /* Is a USB 3.0 port in the Inactive or Compliance Mode state? | 2625 | /* Is a USB 3.0 port in the Inactive or Compliance Mode state? |
2623 | * Port worm reset is required to recover | 2626 | * Port worm reset is required to recover |
2624 | */ | 2627 | */ |
@@ -2706,44 +2709,6 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, | |||
2706 | return 0; | 2709 | return 0; |
2707 | } | 2710 | } |
2708 | 2711 | ||
2709 | static void hub_port_finish_reset(struct usb_hub *hub, int port1, | ||
2710 | struct usb_device *udev, int *status) | ||
2711 | { | ||
2712 | switch (*status) { | ||
2713 | case 0: | ||
2714 | /* TRSTRCY = 10 ms; plus some extra */ | ||
2715 | msleep(10 + 40); | ||
2716 | if (udev) { | ||
2717 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
2718 | |||
2719 | update_devnum(udev, 0); | ||
2720 | /* The xHC may think the device is already reset, | ||
2721 | * so ignore the status. | ||
2722 | */ | ||
2723 | if (hcd->driver->reset_device) | ||
2724 | hcd->driver->reset_device(hcd, udev); | ||
2725 | } | ||
2726 | /* FALL THROUGH */ | ||
2727 | case -ENOTCONN: | ||
2728 | case -ENODEV: | ||
2729 | usb_clear_port_feature(hub->hdev, | ||
2730 | port1, USB_PORT_FEAT_C_RESET); | ||
2731 | if (hub_is_superspeed(hub->hdev)) { | ||
2732 | usb_clear_port_feature(hub->hdev, port1, | ||
2733 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
2734 | usb_clear_port_feature(hub->hdev, port1, | ||
2735 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
2736 | usb_clear_port_feature(hub->hdev, port1, | ||
2737 | USB_PORT_FEAT_C_CONNECTION); | ||
2738 | } | ||
2739 | if (udev) | ||
2740 | usb_set_device_state(udev, *status | ||
2741 | ? USB_STATE_NOTATTACHED | ||
2742 | : USB_STATE_DEFAULT); | ||
2743 | break; | ||
2744 | } | ||
2745 | } | ||
2746 | |||
2747 | /* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */ | 2712 | /* Handle port reset and port warm(BH) reset (for USB3 protocol ports) */ |
2748 | static int hub_port_reset(struct usb_hub *hub, int port1, | 2713 | static int hub_port_reset(struct usb_hub *hub, int port1, |
2749 | struct usb_device *udev, unsigned int delay, bool warm) | 2714 | struct usb_device *udev, unsigned int delay, bool warm) |
@@ -2767,13 +2732,10 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2767 | * If the caller hasn't explicitly requested a warm reset, | 2732 | * If the caller hasn't explicitly requested a warm reset, |
2768 | * double check and see if one is needed. | 2733 | * double check and see if one is needed. |
2769 | */ | 2734 | */ |
2770 | status = hub_port_status(hub, port1, | 2735 | if (hub_port_status(hub, port1, &portstatus, &portchange) == 0) |
2771 | &portstatus, &portchange); | 2736 | if (hub_port_warm_reset_required(hub, port1, |
2772 | if (status < 0) | 2737 | portstatus)) |
2773 | goto done; | 2738 | warm = true; |
2774 | |||
2775 | if (hub_port_warm_reset_required(hub, port1, portstatus)) | ||
2776 | warm = true; | ||
2777 | } | 2739 | } |
2778 | clear_bit(port1, hub->warm_reset_bits); | 2740 | clear_bit(port1, hub->warm_reset_bits); |
2779 | 2741 | ||
@@ -2799,11 +2761,19 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2799 | 2761 | ||
2800 | /* Check for disconnect or reset */ | 2762 | /* Check for disconnect or reset */ |
2801 | if (status == 0 || status == -ENOTCONN || status == -ENODEV) { | 2763 | if (status == 0 || status == -ENOTCONN || status == -ENODEV) { |
2802 | hub_port_finish_reset(hub, port1, udev, &status); | 2764 | usb_clear_port_feature(hub->hdev, port1, |
2765 | USB_PORT_FEAT_C_RESET); | ||
2803 | 2766 | ||
2804 | if (!hub_is_superspeed(hub->hdev)) | 2767 | if (!hub_is_superspeed(hub->hdev)) |
2805 | goto done; | 2768 | goto done; |
2806 | 2769 | ||
2770 | usb_clear_port_feature(hub->hdev, port1, | ||
2771 | USB_PORT_FEAT_C_BH_PORT_RESET); | ||
2772 | usb_clear_port_feature(hub->hdev, port1, | ||
2773 | USB_PORT_FEAT_C_PORT_LINK_STATE); | ||
2774 | usb_clear_port_feature(hub->hdev, port1, | ||
2775 | USB_PORT_FEAT_C_CONNECTION); | ||
2776 | |||
2807 | /* | 2777 | /* |
2808 | * If a USB 3.0 device migrates from reset to an error | 2778 | * If a USB 3.0 device migrates from reset to an error |
2809 | * state, re-issue the warm reset. | 2779 | * state, re-issue the warm reset. |
@@ -2836,6 +2806,26 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
2836 | dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n"); | 2806 | dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n"); |
2837 | 2807 | ||
2838 | done: | 2808 | done: |
2809 | if (status == 0) { | ||
2810 | /* TRSTRCY = 10 ms; plus some extra */ | ||
2811 | msleep(10 + 40); | ||
2812 | if (udev) { | ||
2813 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
2814 | |||
2815 | update_devnum(udev, 0); | ||
2816 | /* The xHC may think the device is already reset, | ||
2817 | * so ignore the status. | ||
2818 | */ | ||
2819 | if (hcd->driver->reset_device) | ||
2820 | hcd->driver->reset_device(hcd, udev); | ||
2821 | |||
2822 | usb_set_device_state(udev, USB_STATE_DEFAULT); | ||
2823 | } | ||
2824 | } else { | ||
2825 | if (udev) | ||
2826 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | ||
2827 | } | ||
2828 | |||
2839 | if (!hub_is_superspeed(hub->hdev)) | 2829 | if (!hub_is_superspeed(hub->hdev)) |
2840 | up_read(&ehci_cf_port_reset_rwsem); | 2830 | up_read(&ehci_cf_port_reset_rwsem); |
2841 | 2831 | ||
diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index 1bcb36ae6505..fd95ba6ec317 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig | |||
@@ -50,18 +50,10 @@ config USB_DWC2_DUAL_ROLE | |||
50 | option requires USB_GADGET to be enabled. | 50 | option requires USB_GADGET to be enabled. |
51 | endchoice | 51 | endchoice |
52 | 52 | ||
53 | config USB_DWC2_PLATFORM | ||
54 | tristate "DWC2 Platform" | ||
55 | default USB_DWC2_HOST || USB_DWC2_PERIPHERAL | ||
56 | help | ||
57 | The Designware USB2.0 platform interface module for | ||
58 | controllers directly connected to the CPU. | ||
59 | |||
60 | config USB_DWC2_PCI | 53 | config USB_DWC2_PCI |
61 | tristate "DWC2 PCI" | 54 | tristate "DWC2 PCI" |
62 | depends on PCI | 55 | depends on PCI |
63 | default n | 56 | default n |
64 | select USB_DWC2_PLATFORM | ||
65 | select NOP_USB_XCEIV | 57 | select NOP_USB_XCEIV |
66 | help | 58 | help |
67 | The Designware USB2.0 PCI interface module for controllers | 59 | The Designware USB2.0 PCI interface module for controllers |
diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index f07b425eaff3..50fdaace1e73 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile | |||
@@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG | |||
2 | ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG | 2 | ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG |
3 | 3 | ||
4 | obj-$(CONFIG_USB_DWC2) += dwc2.o | 4 | obj-$(CONFIG_USB_DWC2) += dwc2.o |
5 | dwc2-y := core.o core_intr.o | 5 | dwc2-y := core.o core_intr.o platform.o |
6 | 6 | ||
7 | ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) | 7 | ifneq ($(filter y,$(CONFIG_USB_DWC2_HOST) $(CONFIG_USB_DWC2_DUAL_ROLE)),) |
8 | dwc2-y += hcd.o hcd_intr.o | 8 | dwc2-y += hcd.o hcd_intr.o |
@@ -13,6 +13,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC2_PERIPHERAL) $(CONFIG_USB_DWC2_DUAL_ROLE)),) | |||
13 | dwc2-y += gadget.o | 13 | dwc2-y += gadget.o |
14 | endif | 14 | endif |
15 | 15 | ||
16 | ifneq ($(CONFIG_DEBUG_FS),) | ||
17 | dwc2-y += debugfs.o | ||
18 | endif | ||
19 | |||
16 | # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to | 20 | # NOTE: The previous s3c-hsotg peripheral mode only driver has been moved to |
17 | # this location and renamed gadget.c. When building for dynamically linked | 21 | # this location and renamed gadget.c. When building for dynamically linked |
18 | # modules, dwc2.ko will get built for host mode, peripheral mode, and dual-role | 22 | # modules, dwc2.ko will get built for host mode, peripheral mode, and dual-role |
@@ -21,6 +25,3 @@ endif | |||
21 | 25 | ||
22 | obj-$(CONFIG_USB_DWC2_PCI) += dwc2_pci.o | 26 | obj-$(CONFIG_USB_DWC2_PCI) += dwc2_pci.o |
23 | dwc2_pci-y := pci.o | 27 | dwc2_pci-y := pci.o |
24 | |||
25 | obj-$(CONFIG_USB_DWC2_PLATFORM) += dwc2_platform.o | ||
26 | dwc2_platform-y := platform.o | ||
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d5197d492e21..e5b546f1152e 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -56,6 +56,389 @@ | |||
56 | #include "core.h" | 56 | #include "core.h" |
57 | #include "hcd.h" | 57 | #include "hcd.h" |
58 | 58 | ||
59 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | ||
60 | /** | ||
61 | * dwc2_backup_host_registers() - Backup controller host registers. | ||
62 | * When suspending usb bus, registers needs to be backuped | ||
63 | * if controller power is disabled once suspended. | ||
64 | * | ||
65 | * @hsotg: Programming view of the DWC_otg controller | ||
66 | */ | ||
67 | static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
68 | { | ||
69 | struct dwc2_hregs_backup *hr; | ||
70 | int i; | ||
71 | |||
72 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
73 | |||
74 | /* Backup Host regs */ | ||
75 | hr = hsotg->hr_backup; | ||
76 | if (!hr) { | ||
77 | hr = devm_kzalloc(hsotg->dev, sizeof(*hr), GFP_KERNEL); | ||
78 | if (!hr) { | ||
79 | dev_err(hsotg->dev, "%s: can't allocate host regs\n", | ||
80 | __func__); | ||
81 | return -ENOMEM; | ||
82 | } | ||
83 | |||
84 | hsotg->hr_backup = hr; | ||
85 | } | ||
86 | hr->hcfg = readl(hsotg->regs + HCFG); | ||
87 | hr->haintmsk = readl(hsotg->regs + HAINTMSK); | ||
88 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
89 | hr->hcintmsk[i] = readl(hsotg->regs + HCINTMSK(i)); | ||
90 | |||
91 | hr->hprt0 = readl(hsotg->regs + HPRT0); | ||
92 | hr->hfir = readl(hsotg->regs + HFIR); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * dwc2_restore_host_registers() - Restore controller host registers. | ||
99 | * When resuming usb bus, device registers needs to be restored | ||
100 | * if controller power were disabled. | ||
101 | * | ||
102 | * @hsotg: Programming view of the DWC_otg controller | ||
103 | */ | ||
104 | static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
105 | { | ||
106 | struct dwc2_hregs_backup *hr; | ||
107 | int i; | ||
108 | |||
109 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
110 | |||
111 | /* Restore host regs */ | ||
112 | hr = hsotg->hr_backup; | ||
113 | if (!hr) { | ||
114 | dev_err(hsotg->dev, "%s: no host registers to restore\n", | ||
115 | __func__); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | |||
119 | writel(hr->hcfg, hsotg->regs + HCFG); | ||
120 | writel(hr->haintmsk, hsotg->regs + HAINTMSK); | ||
121 | |||
122 | for (i = 0; i < hsotg->core_params->host_channels; ++i) | ||
123 | writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i)); | ||
124 | |||
125 | writel(hr->hprt0, hsotg->regs + HPRT0); | ||
126 | writel(hr->hfir, hsotg->regs + HFIR); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | #else | ||
131 | static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) | ||
132 | { return 0; } | ||
133 | |||
134 | static inline int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) | ||
135 | { return 0; } | ||
136 | #endif | ||
137 | |||
138 | #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ | ||
139 | IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | ||
140 | /** | ||
141 | * dwc2_backup_device_registers() - Backup controller device registers. | ||
142 | * When suspending usb bus, registers needs to be backuped | ||
143 | * if controller power is disabled once suspended. | ||
144 | * | ||
145 | * @hsotg: Programming view of the DWC_otg controller | ||
146 | */ | ||
147 | static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
148 | { | ||
149 | struct dwc2_dregs_backup *dr; | ||
150 | int i; | ||
151 | |||
152 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
153 | |||
154 | /* Backup dev regs */ | ||
155 | dr = hsotg->dr_backup; | ||
156 | if (!dr) { | ||
157 | dr = devm_kzalloc(hsotg->dev, sizeof(*dr), GFP_KERNEL); | ||
158 | if (!dr) { | ||
159 | dev_err(hsotg->dev, "%s: can't allocate device regs\n", | ||
160 | __func__); | ||
161 | return -ENOMEM; | ||
162 | } | ||
163 | |||
164 | hsotg->dr_backup = dr; | ||
165 | } | ||
166 | |||
167 | dr->dcfg = readl(hsotg->regs + DCFG); | ||
168 | dr->dctl = readl(hsotg->regs + DCTL); | ||
169 | dr->daintmsk = readl(hsotg->regs + DAINTMSK); | ||
170 | dr->diepmsk = readl(hsotg->regs + DIEPMSK); | ||
171 | dr->doepmsk = readl(hsotg->regs + DOEPMSK); | ||
172 | |||
173 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
174 | /* Backup IN EPs */ | ||
175 | dr->diepctl[i] = readl(hsotg->regs + DIEPCTL(i)); | ||
176 | |||
177 | /* Ensure DATA PID is correctly configured */ | ||
178 | if (dr->diepctl[i] & DXEPCTL_DPID) | ||
179 | dr->diepctl[i] |= DXEPCTL_SETD1PID; | ||
180 | else | ||
181 | dr->diepctl[i] |= DXEPCTL_SETD0PID; | ||
182 | |||
183 | dr->dieptsiz[i] = readl(hsotg->regs + DIEPTSIZ(i)); | ||
184 | dr->diepdma[i] = readl(hsotg->regs + DIEPDMA(i)); | ||
185 | |||
186 | /* Backup OUT EPs */ | ||
187 | dr->doepctl[i] = readl(hsotg->regs + DOEPCTL(i)); | ||
188 | |||
189 | /* Ensure DATA PID is correctly configured */ | ||
190 | if (dr->doepctl[i] & DXEPCTL_DPID) | ||
191 | dr->doepctl[i] |= DXEPCTL_SETD1PID; | ||
192 | else | ||
193 | dr->doepctl[i] |= DXEPCTL_SETD0PID; | ||
194 | |||
195 | dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i)); | ||
196 | dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i)); | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * dwc2_restore_device_registers() - Restore controller device registers. | ||
204 | * When resuming usb bus, device registers needs to be restored | ||
205 | * if controller power were disabled. | ||
206 | * | ||
207 | * @hsotg: Programming view of the DWC_otg controller | ||
208 | */ | ||
209 | static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
210 | { | ||
211 | struct dwc2_dregs_backup *dr; | ||
212 | u32 dctl; | ||
213 | int i; | ||
214 | |||
215 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
216 | |||
217 | /* Restore dev regs */ | ||
218 | dr = hsotg->dr_backup; | ||
219 | if (!dr) { | ||
220 | dev_err(hsotg->dev, "%s: no device registers to restore\n", | ||
221 | __func__); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | |||
225 | writel(dr->dcfg, hsotg->regs + DCFG); | ||
226 | writel(dr->dctl, hsotg->regs + DCTL); | ||
227 | writel(dr->daintmsk, hsotg->regs + DAINTMSK); | ||
228 | writel(dr->diepmsk, hsotg->regs + DIEPMSK); | ||
229 | writel(dr->doepmsk, hsotg->regs + DOEPMSK); | ||
230 | |||
231 | for (i = 0; i < hsotg->num_of_eps; i++) { | ||
232 | /* Restore IN EPs */ | ||
233 | writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i)); | ||
234 | writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i)); | ||
235 | writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i)); | ||
236 | |||
237 | /* Restore OUT EPs */ | ||
238 | writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i)); | ||
239 | writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i)); | ||
240 | writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i)); | ||
241 | } | ||
242 | |||
243 | /* Set the Power-On Programming done bit */ | ||
244 | dctl = readl(hsotg->regs + DCTL); | ||
245 | dctl |= DCTL_PWRONPRGDONE; | ||
246 | writel(dctl, hsotg->regs + DCTL); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | #else | ||
251 | static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) | ||
252 | { return 0; } | ||
253 | |||
254 | static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) | ||
255 | { return 0; } | ||
256 | #endif | ||
257 | |||
258 | /** | ||
259 | * dwc2_backup_global_registers() - Backup global controller registers. | ||
260 | * When suspending usb bus, registers needs to be backuped | ||
261 | * if controller power is disabled once suspended. | ||
262 | * | ||
263 | * @hsotg: Programming view of the DWC_otg controller | ||
264 | */ | ||
265 | static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) | ||
266 | { | ||
267 | struct dwc2_gregs_backup *gr; | ||
268 | int i; | ||
269 | |||
270 | /* Backup global regs */ | ||
271 | gr = hsotg->gr_backup; | ||
272 | if (!gr) { | ||
273 | gr = devm_kzalloc(hsotg->dev, sizeof(*gr), GFP_KERNEL); | ||
274 | if (!gr) { | ||
275 | dev_err(hsotg->dev, "%s: can't allocate global regs\n", | ||
276 | __func__); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | |||
280 | hsotg->gr_backup = gr; | ||
281 | } | ||
282 | |||
283 | gr->gotgctl = readl(hsotg->regs + GOTGCTL); | ||
284 | gr->gintmsk = readl(hsotg->regs + GINTMSK); | ||
285 | gr->gahbcfg = readl(hsotg->regs + GAHBCFG); | ||
286 | gr->gusbcfg = readl(hsotg->regs + GUSBCFG); | ||
287 | gr->grxfsiz = readl(hsotg->regs + GRXFSIZ); | ||
288 | gr->gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); | ||
289 | gr->hptxfsiz = readl(hsotg->regs + HPTXFSIZ); | ||
290 | gr->gdfifocfg = readl(hsotg->regs + GDFIFOCFG); | ||
291 | for (i = 0; i < MAX_EPS_CHANNELS; i++) | ||
292 | gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i)); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * dwc2_restore_global_registers() - Restore controller global registers. | ||
299 | * When resuming usb bus, device registers needs to be restored | ||
300 | * if controller power were disabled. | ||
301 | * | ||
302 | * @hsotg: Programming view of the DWC_otg controller | ||
303 | */ | ||
304 | static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg) | ||
305 | { | ||
306 | struct dwc2_gregs_backup *gr; | ||
307 | int i; | ||
308 | |||
309 | dev_dbg(hsotg->dev, "%s\n", __func__); | ||
310 | |||
311 | /* Restore global regs */ | ||
312 | gr = hsotg->gr_backup; | ||
313 | if (!gr) { | ||
314 | dev_err(hsotg->dev, "%s: no global registers to restore\n", | ||
315 | __func__); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | writel(0xffffffff, hsotg->regs + GINTSTS); | ||
320 | writel(gr->gotgctl, hsotg->regs + GOTGCTL); | ||
321 | writel(gr->gintmsk, hsotg->regs + GINTMSK); | ||
322 | writel(gr->gusbcfg, hsotg->regs + GUSBCFG); | ||
323 | writel(gr->gahbcfg, hsotg->regs + GAHBCFG); | ||
324 | writel(gr->grxfsiz, hsotg->regs + GRXFSIZ); | ||
325 | writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ); | ||
326 | writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ); | ||
327 | writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG); | ||
328 | for (i = 0; i < MAX_EPS_CHANNELS; i++) | ||
329 | writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i)); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | /** | ||
335 | * dwc2_exit_hibernation() - Exit controller from Partial Power Down. | ||
336 | * | ||
337 | * @hsotg: Programming view of the DWC_otg controller | ||
338 | * @restore: Controller registers need to be restored | ||
339 | */ | ||
340 | int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore) | ||
341 | { | ||
342 | u32 pcgcctl; | ||
343 | int ret = 0; | ||
344 | |||
345 | if (!hsotg->core_params->hibernation) | ||
346 | return -ENOTSUPP; | ||
347 | |||
348 | pcgcctl = readl(hsotg->regs + PCGCTL); | ||
349 | pcgcctl &= ~PCGCTL_STOPPCLK; | ||
350 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
351 | |||
352 | pcgcctl = readl(hsotg->regs + PCGCTL); | ||
353 | pcgcctl &= ~PCGCTL_PWRCLMP; | ||
354 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
355 | |||
356 | pcgcctl = readl(hsotg->regs + PCGCTL); | ||
357 | pcgcctl &= ~PCGCTL_RSTPDWNMODULE; | ||
358 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
359 | |||
360 | udelay(100); | ||
361 | if (restore) { | ||
362 | ret = dwc2_restore_global_registers(hsotg); | ||
363 | if (ret) { | ||
364 | dev_err(hsotg->dev, "%s: failed to restore registers\n", | ||
365 | __func__); | ||
366 | return ret; | ||
367 | } | ||
368 | if (dwc2_is_host_mode(hsotg)) { | ||
369 | ret = dwc2_restore_host_registers(hsotg); | ||
370 | if (ret) { | ||
371 | dev_err(hsotg->dev, "%s: failed to restore host registers\n", | ||
372 | __func__); | ||
373 | return ret; | ||
374 | } | ||
375 | } else { | ||
376 | ret = dwc2_restore_device_registers(hsotg); | ||
377 | if (ret) { | ||
378 | dev_err(hsotg->dev, "%s: failed to restore device registers\n", | ||
379 | __func__); | ||
380 | return ret; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * dwc2_enter_hibernation() - Put controller in Partial Power Down. | ||
390 | * | ||
391 | * @hsotg: Programming view of the DWC_otg controller | ||
392 | */ | ||
393 | int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg) | ||
394 | { | ||
395 | u32 pcgcctl; | ||
396 | int ret = 0; | ||
397 | |||
398 | if (!hsotg->core_params->hibernation) | ||
399 | return -ENOTSUPP; | ||
400 | |||
401 | /* Backup all registers */ | ||
402 | ret = dwc2_backup_global_registers(hsotg); | ||
403 | if (ret) { | ||
404 | dev_err(hsotg->dev, "%s: failed to backup global registers\n", | ||
405 | __func__); | ||
406 | return ret; | ||
407 | } | ||
408 | |||
409 | if (dwc2_is_host_mode(hsotg)) { | ||
410 | ret = dwc2_backup_host_registers(hsotg); | ||
411 | if (ret) { | ||
412 | dev_err(hsotg->dev, "%s: failed to backup host registers\n", | ||
413 | __func__); | ||
414 | return ret; | ||
415 | } | ||
416 | } else { | ||
417 | ret = dwc2_backup_device_registers(hsotg); | ||
418 | if (ret) { | ||
419 | dev_err(hsotg->dev, "%s: failed to backup device registers\n", | ||
420 | __func__); | ||
421 | return ret; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /* Put the controller in low power state */ | ||
426 | pcgcctl = readl(hsotg->regs + PCGCTL); | ||
427 | |||
428 | pcgcctl |= PCGCTL_PWRCLMP; | ||
429 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
430 | ndelay(20); | ||
431 | |||
432 | pcgcctl |= PCGCTL_RSTPDWNMODULE; | ||
433 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
434 | ndelay(20); | ||
435 | |||
436 | pcgcctl |= PCGCTL_STOPPCLK; | ||
437 | writel(pcgcctl, hsotg->regs + PCGCTL); | ||
438 | |||
439 | return ret; | ||
440 | } | ||
441 | |||
59 | /** | 442 | /** |
60 | * dwc2_enable_common_interrupts() - Initializes the commmon interrupts, | 443 | * dwc2_enable_common_interrupts() - Initializes the commmon interrupts, |
61 | * used in both device and host modes | 444 | * used in both device and host modes |
@@ -77,8 +460,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) | |||
77 | 460 | ||
78 | if (hsotg->core_params->dma_enable <= 0) | 461 | if (hsotg->core_params->dma_enable <= 0) |
79 | intmsk |= GINTSTS_RXFLVL; | 462 | intmsk |= GINTSTS_RXFLVL; |
463 | if (hsotg->core_params->external_id_pin_ctl <= 0) | ||
464 | intmsk |= GINTSTS_CONIDSTSCHNG; | ||
80 | 465 | ||
81 | intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP | | 466 | intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP | |
82 | GINTSTS_SESSREQINT; | 467 | GINTSTS_SESSREQINT; |
83 | 468 | ||
84 | writel(intmsk, hsotg->regs + GINTMSK); | 469 | writel(intmsk, hsotg->regs + GINTMSK); |
@@ -2602,6 +2987,40 @@ static void dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val) | |||
2602 | hsotg->core_params->uframe_sched = val; | 2987 | hsotg->core_params->uframe_sched = val; |
2603 | } | 2988 | } |
2604 | 2989 | ||
2990 | static void dwc2_set_param_external_id_pin_ctl(struct dwc2_hsotg *hsotg, | ||
2991 | int val) | ||
2992 | { | ||
2993 | if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { | ||
2994 | if (val >= 0) { | ||
2995 | dev_err(hsotg->dev, | ||
2996 | "'%d' invalid for parameter external_id_pin_ctl\n", | ||
2997 | val); | ||
2998 | dev_err(hsotg->dev, "external_id_pin_ctl must be 0 or 1\n"); | ||
2999 | } | ||
3000 | val = 0; | ||
3001 | dev_dbg(hsotg->dev, "Setting external_id_pin_ctl to %d\n", val); | ||
3002 | } | ||
3003 | |||
3004 | hsotg->core_params->external_id_pin_ctl = val; | ||
3005 | } | ||
3006 | |||
3007 | static void dwc2_set_param_hibernation(struct dwc2_hsotg *hsotg, | ||
3008 | int val) | ||
3009 | { | ||
3010 | if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { | ||
3011 | if (val >= 0) { | ||
3012 | dev_err(hsotg->dev, | ||
3013 | "'%d' invalid for parameter hibernation\n", | ||
3014 | val); | ||
3015 | dev_err(hsotg->dev, "hibernation must be 0 or 1\n"); | ||
3016 | } | ||
3017 | val = 0; | ||
3018 | dev_dbg(hsotg->dev, "Setting hibernation to %d\n", val); | ||
3019 | } | ||
3020 | |||
3021 | hsotg->core_params->hibernation = val; | ||
3022 | } | ||
3023 | |||
2605 | /* | 3024 | /* |
2606 | * This function is called during module intialization to pass module parameters | 3025 | * This function is called during module intialization to pass module parameters |
2607 | * for the DWC_otg core. | 3026 | * for the DWC_otg core. |
@@ -2646,6 +3065,8 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg, | |||
2646 | dwc2_set_param_ahbcfg(hsotg, params->ahbcfg); | 3065 | dwc2_set_param_ahbcfg(hsotg, params->ahbcfg); |
2647 | dwc2_set_param_otg_ver(hsotg, params->otg_ver); | 3066 | dwc2_set_param_otg_ver(hsotg, params->otg_ver); |
2648 | dwc2_set_param_uframe_sched(hsotg, params->uframe_sched); | 3067 | dwc2_set_param_uframe_sched(hsotg, params->uframe_sched); |
3068 | dwc2_set_param_external_id_pin_ctl(hsotg, params->external_id_pin_ctl); | ||
3069 | dwc2_set_param_hibernation(hsotg, params->hibernation); | ||
2649 | } | 3070 | } |
2650 | 3071 | ||
2651 | /** | 3072 | /** |
@@ -2814,6 +3235,22 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) | |||
2814 | return 0; | 3235 | return 0; |
2815 | } | 3236 | } |
2816 | 3237 | ||
3238 | /* | ||
3239 | * Sets all parameters to the given value. | ||
3240 | * | ||
3241 | * Assumes that the dwc2_core_params struct contains only integers. | ||
3242 | */ | ||
3243 | void dwc2_set_all_params(struct dwc2_core_params *params, int value) | ||
3244 | { | ||
3245 | int *p = (int *)params; | ||
3246 | size_t size = sizeof(*params) / sizeof(*p); | ||
3247 | int i; | ||
3248 | |||
3249 | for (i = 0; i < size; i++) | ||
3250 | p[i] = value; | ||
3251 | } | ||
3252 | |||
3253 | |||
2817 | u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg) | 3254 | u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg) |
2818 | { | 3255 | { |
2819 | return hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103; | 3256 | return hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103; |
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 836c012c7707..53b8de03f102 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h | |||
@@ -331,6 +331,17 @@ enum dwc2_ep0_state { | |||
331 | * by the driver and are ignored in this | 331 | * by the driver and are ignored in this |
332 | * configuration value. | 332 | * configuration value. |
333 | * @uframe_sched: True to enable the microframe scheduler | 333 | * @uframe_sched: True to enable the microframe scheduler |
334 | * @external_id_pin_ctl: Specifies whether ID pin is handled externally. | ||
335 | * Disable CONIDSTSCHNG controller interrupt in such | ||
336 | * case. | ||
337 | * 0 - No (default) | ||
338 | * 1 - Yes | ||
339 | * @hibernation: Specifies whether the controller support hibernation. | ||
340 | * If hibernation is enabled, the controller will enter | ||
341 | * hibernation in both peripheral and host mode when | ||
342 | * needed. | ||
343 | * 0 - No (default) | ||
344 | * 1 - Yes | ||
334 | * | 345 | * |
335 | * The following parameters may be specified when starting the module. These | 346 | * The following parameters may be specified when starting the module. These |
336 | * parameters define how the DWC_otg controller should be configured. A | 347 | * parameters define how the DWC_otg controller should be configured. A |
@@ -368,6 +379,8 @@ struct dwc2_core_params { | |||
368 | int reload_ctl; | 379 | int reload_ctl; |
369 | int ahbcfg; | 380 | int ahbcfg; |
370 | int uframe_sched; | 381 | int uframe_sched; |
382 | int external_id_pin_ctl; | ||
383 | int hibernation; | ||
371 | }; | 384 | }; |
372 | 385 | ||
373 | /** | 386 | /** |
@@ -452,6 +465,82 @@ struct dwc2_hw_params { | |||
452 | #define DWC2_CTRL_BUFF_SIZE 8 | 465 | #define DWC2_CTRL_BUFF_SIZE 8 |
453 | 466 | ||
454 | /** | 467 | /** |
468 | * struct dwc2_gregs_backup - Holds global registers state before entering partial | ||
469 | * power down | ||
470 | * @gotgctl: Backup of GOTGCTL register | ||
471 | * @gintmsk: Backup of GINTMSK register | ||
472 | * @gahbcfg: Backup of GAHBCFG register | ||
473 | * @gusbcfg: Backup of GUSBCFG register | ||
474 | * @grxfsiz: Backup of GRXFSIZ register | ||
475 | * @gnptxfsiz: Backup of GNPTXFSIZ register | ||
476 | * @gi2cctl: Backup of GI2CCTL register | ||
477 | * @hptxfsiz: Backup of HPTXFSIZ register | ||
478 | * @gdfifocfg: Backup of GDFIFOCFG register | ||
479 | * @dtxfsiz: Backup of DTXFSIZ registers for each endpoint | ||
480 | * @gpwrdn: Backup of GPWRDN register | ||
481 | */ | ||
482 | struct dwc2_gregs_backup { | ||
483 | u32 gotgctl; | ||
484 | u32 gintmsk; | ||
485 | u32 gahbcfg; | ||
486 | u32 gusbcfg; | ||
487 | u32 grxfsiz; | ||
488 | u32 gnptxfsiz; | ||
489 | u32 gi2cctl; | ||
490 | u32 hptxfsiz; | ||
491 | u32 pcgcctl; | ||
492 | u32 gdfifocfg; | ||
493 | u32 dtxfsiz[MAX_EPS_CHANNELS]; | ||
494 | u32 gpwrdn; | ||
495 | }; | ||
496 | |||
497 | /** | ||
498 | * struct dwc2_dregs_backup - Holds device registers state before entering partial | ||
499 | * power down | ||
500 | * @dcfg: Backup of DCFG register | ||
501 | * @dctl: Backup of DCTL register | ||
502 | * @daintmsk: Backup of DAINTMSK register | ||
503 | * @diepmsk: Backup of DIEPMSK register | ||
504 | * @doepmsk: Backup of DOEPMSK register | ||
505 | * @diepctl: Backup of DIEPCTL register | ||
506 | * @dieptsiz: Backup of DIEPTSIZ register | ||
507 | * @diepdma: Backup of DIEPDMA register | ||
508 | * @doepctl: Backup of DOEPCTL register | ||
509 | * @doeptsiz: Backup of DOEPTSIZ register | ||
510 | * @doepdma: Backup of DOEPDMA register | ||
511 | */ | ||
512 | struct dwc2_dregs_backup { | ||
513 | u32 dcfg; | ||
514 | u32 dctl; | ||
515 | u32 daintmsk; | ||
516 | u32 diepmsk; | ||
517 | u32 doepmsk; | ||
518 | u32 diepctl[MAX_EPS_CHANNELS]; | ||
519 | u32 dieptsiz[MAX_EPS_CHANNELS]; | ||
520 | u32 diepdma[MAX_EPS_CHANNELS]; | ||
521 | u32 doepctl[MAX_EPS_CHANNELS]; | ||
522 | u32 doeptsiz[MAX_EPS_CHANNELS]; | ||
523 | u32 doepdma[MAX_EPS_CHANNELS]; | ||
524 | }; | ||
525 | |||
526 | /** | ||
527 | * struct dwc2_hregs_backup - Holds host registers state before entering partial | ||
528 | * power down | ||
529 | * @hcfg: Backup of HCFG register | ||
530 | * @haintmsk: Backup of HAINTMSK register | ||
531 | * @hcintmsk: Backup of HCINTMSK register | ||
532 | * @hptr0: Backup of HPTR0 register | ||
533 | * @hfir: Backup of HFIR register | ||
534 | */ | ||
535 | struct dwc2_hregs_backup { | ||
536 | u32 hcfg; | ||
537 | u32 haintmsk; | ||
538 | u32 hcintmsk[MAX_EPS_CHANNELS]; | ||
539 | u32 hprt0; | ||
540 | u32 hfir; | ||
541 | }; | ||
542 | |||
543 | /** | ||
455 | * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic | 544 | * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic |
456 | * and periodic schedules | 545 | * and periodic schedules |
457 | * | 546 | * |
@@ -481,6 +570,9 @@ struct dwc2_hw_params { | |||
481 | * interrupt | 570 | * interrupt |
482 | * @wkp_timer: Timer object for handling Wakeup Detected interrupt | 571 | * @wkp_timer: Timer object for handling Wakeup Detected interrupt |
483 | * @lx_state: Lx state of connected device | 572 | * @lx_state: Lx state of connected device |
573 | * @gregs_backup: Backup of global registers during suspend | ||
574 | * @dregs_backup: Backup of device registers during suspend | ||
575 | * @hregs_backup: Backup of host registers during suspend | ||
484 | * | 576 | * |
485 | * These are for host mode: | 577 | * These are for host mode: |
486 | * | 578 | * |
@@ -613,11 +705,12 @@ struct dwc2_hsotg { | |||
613 | struct work_struct wf_otg; | 705 | struct work_struct wf_otg; |
614 | struct timer_list wkp_timer; | 706 | struct timer_list wkp_timer; |
615 | enum dwc2_lx_state lx_state; | 707 | enum dwc2_lx_state lx_state; |
708 | struct dwc2_gregs_backup *gr_backup; | ||
709 | struct dwc2_dregs_backup *dr_backup; | ||
710 | struct dwc2_hregs_backup *hr_backup; | ||
616 | 711 | ||
617 | struct dentry *debug_root; | 712 | struct dentry *debug_root; |
618 | struct dentry *debug_file; | 713 | struct debugfs_regset32 *regset; |
619 | struct dentry *debug_testmode; | ||
620 | struct dentry *debug_fifo; | ||
621 | 714 | ||
622 | /* DWC OTG HW Release versions */ | 715 | /* DWC OTG HW Release versions */ |
623 | #define DWC2_CORE_REV_2_71a 0x4f54271a | 716 | #define DWC2_CORE_REV_2_71a 0x4f54271a |
@@ -751,6 +844,8 @@ enum dwc2_halt_status { | |||
751 | * and the DWC_otg controller | 844 | * and the DWC_otg controller |
752 | */ | 845 | */ |
753 | extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); | 846 | extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); |
847 | extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); | ||
848 | extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); | ||
754 | 849 | ||
755 | /* | 850 | /* |
756 | * Host core Functions. | 851 | * Host core Functions. |
@@ -983,6 +1078,15 @@ extern void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val); | |||
983 | 1078 | ||
984 | extern void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val); | 1079 | extern void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val); |
985 | 1080 | ||
1081 | extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg, | ||
1082 | const struct dwc2_core_params *params); | ||
1083 | |||
1084 | extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); | ||
1085 | |||
1086 | extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); | ||
1087 | |||
1088 | |||
1089 | |||
986 | /* | 1090 | /* |
987 | * Dump core registers and SPRAM | 1091 | * Dump core registers and SPRAM |
988 | */ | 1092 | */ |
@@ -1005,6 +1109,8 @@ extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, | |||
1005 | bool reset); | 1109 | bool reset); |
1006 | extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); | 1110 | extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); |
1007 | extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); | 1111 | extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); |
1112 | extern int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); | ||
1113 | #define dwc2_is_device_connected(hsotg) (hsotg->connected) | ||
1008 | #else | 1114 | #else |
1009 | static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) | 1115 | static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) |
1010 | { return 0; } | 1116 | { return 0; } |
@@ -1018,6 +1124,10 @@ static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, | |||
1018 | bool reset) {} | 1124 | bool reset) {} |
1019 | static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} | 1125 | static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} |
1020 | static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} | 1126 | static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} |
1127 | static inline int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, | ||
1128 | int testmode) | ||
1129 | { return 0; } | ||
1130 | #define dwc2_is_device_connected(hsotg) (0) | ||
1021 | #endif | 1131 | #endif |
1022 | 1132 | ||
1023 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | 1133 | #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) |
@@ -1025,14 +1135,12 @@ extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg); | |||
1025 | extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); | 1135 | extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg); |
1026 | extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); | 1136 | extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg); |
1027 | #else | 1137 | #else |
1028 | static inline void dwc2_set_all_params(struct dwc2_core_params *params, int value) {} | ||
1029 | static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) | 1138 | static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) |
1030 | { return 0; } | 1139 | { return 0; } |
1031 | static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} | 1140 | static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) {} |
1032 | static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} | 1141 | static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} |
1033 | static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} | 1142 | static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} |
1034 | static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | 1143 | static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) |
1035 | const struct dwc2_core_params *params) | ||
1036 | { return 0; } | 1144 | { return 0; } |
1037 | #endif | 1145 | #endif |
1038 | 1146 | ||
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 6cf047878dba..927be1e8b3dc 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c | |||
@@ -334,6 +334,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) | |||
334 | */ | 334 | */ |
335 | static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) | 335 | static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) |
336 | { | 336 | { |
337 | int ret; | ||
337 | dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n"); | 338 | dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n"); |
338 | dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); | 339 | dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); |
339 | 340 | ||
@@ -345,6 +346,11 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) | |||
345 | /* Clear Remote Wakeup Signaling */ | 346 | /* Clear Remote Wakeup Signaling */ |
346 | dctl &= ~DCTL_RMTWKUPSIG; | 347 | dctl &= ~DCTL_RMTWKUPSIG; |
347 | writel(dctl, hsotg->regs + DCTL); | 348 | writel(dctl, hsotg->regs + DCTL); |
349 | ret = dwc2_exit_hibernation(hsotg, true); | ||
350 | if (ret && (ret != -ENOTSUPP)) | ||
351 | dev_err(hsotg->dev, "exit hibernation failed\n"); | ||
352 | |||
353 | call_gadget(hsotg, resume); | ||
348 | } | 354 | } |
349 | /* Change to L0 state */ | 355 | /* Change to L0 state */ |
350 | hsotg->lx_state = DWC2_L0; | 356 | hsotg->lx_state = DWC2_L0; |
@@ -397,6 +403,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) | |||
397 | static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) | 403 | static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) |
398 | { | 404 | { |
399 | u32 dsts; | 405 | u32 dsts; |
406 | int ret; | ||
400 | 407 | ||
401 | dev_dbg(hsotg->dev, "USB SUSPEND\n"); | 408 | dev_dbg(hsotg->dev, "USB SUSPEND\n"); |
402 | 409 | ||
@@ -411,10 +418,43 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) | |||
411 | "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", | 418 | "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", |
412 | !!(dsts & DSTS_SUSPSTS), | 419 | !!(dsts & DSTS_SUSPSTS), |
413 | hsotg->hw_params.power_optimized); | 420 | hsotg->hw_params.power_optimized); |
421 | if ((dsts & DSTS_SUSPSTS) && hsotg->hw_params.power_optimized) { | ||
422 | /* Ignore suspend request before enumeration */ | ||
423 | if (!dwc2_is_device_connected(hsotg)) { | ||
424 | dev_dbg(hsotg->dev, | ||
425 | "ignore suspend request before enumeration\n"); | ||
426 | goto clear_int; | ||
427 | } | ||
428 | |||
429 | ret = dwc2_enter_hibernation(hsotg); | ||
430 | if (ret) { | ||
431 | if (ret != -ENOTSUPP) | ||
432 | dev_err(hsotg->dev, | ||
433 | "enter hibernation failed\n"); | ||
434 | goto skip_power_saving; | ||
435 | } | ||
436 | |||
437 | udelay(100); | ||
438 | |||
439 | /* Ask phy to be suspended */ | ||
440 | if (!IS_ERR_OR_NULL(hsotg->uphy)) | ||
441 | usb_phy_set_suspend(hsotg->uphy, true); | ||
442 | skip_power_saving: | ||
443 | /* | ||
444 | * Change to L2 (suspend) state before releasing | ||
445 | * spinlock | ||
446 | */ | ||
447 | hsotg->lx_state = DWC2_L2; | ||
448 | |||
449 | /* Call gadget suspend callback */ | ||
450 | call_gadget(hsotg, suspend); | ||
451 | } | ||
414 | } else { | 452 | } else { |
415 | if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { | 453 | if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { |
416 | dev_dbg(hsotg->dev, "a_peripheral->a_host\n"); | 454 | dev_dbg(hsotg->dev, "a_peripheral->a_host\n"); |
417 | 455 | ||
456 | /* Change to L2 (suspend) state */ | ||
457 | hsotg->lx_state = DWC2_L2; | ||
418 | /* Clear the a_peripheral flag, back to a_host */ | 458 | /* Clear the a_peripheral flag, back to a_host */ |
419 | spin_unlock(&hsotg->lock); | 459 | spin_unlock(&hsotg->lock); |
420 | dwc2_hcd_start(hsotg); | 460 | dwc2_hcd_start(hsotg); |
@@ -423,9 +463,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) | |||
423 | } | 463 | } |
424 | } | 464 | } |
425 | 465 | ||
426 | /* Change to L2 (suspend) state */ | 466 | clear_int: |
427 | hsotg->lx_state = DWC2_L2; | ||
428 | |||
429 | /* Clear interrupt */ | 467 | /* Clear interrupt */ |
430 | writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); | 468 | writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); |
431 | } | 469 | } |
@@ -522,4 +560,3 @@ out: | |||
522 | spin_unlock(&hsotg->lock); | 560 | spin_unlock(&hsotg->lock); |
523 | return retval; | 561 | return retval; |
524 | } | 562 | } |
525 | EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); | ||
diff --git a/drivers/usb/dwc2/debug.h b/drivers/usb/dwc2/debug.h new file mode 100644 index 000000000000..12dbd1daec87 --- /dev/null +++ b/drivers/usb/dwc2/debug.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /** | ||
2 | * debug.h - Designware USB2 DRD controller debug header | ||
3 | * | ||
4 | * Copyright (C) 2015 Intel Corporation | ||
5 | * Mian Yousaf Kaukab <yousaf.kaukab@intel.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 of | ||
9 | * the License as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include "core.h" | ||
18 | |||
19 | #ifdef CONFIG_DEBUG_FS | ||
20 | extern int dwc2_debugfs_init(struct dwc2_hsotg *); | ||
21 | extern void dwc2_debugfs_exit(struct dwc2_hsotg *); | ||
22 | #else | ||
23 | static inline int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) | ||
24 | { return 0; } | ||
25 | static inline void dwc2_debugfs_exit(struct dwc2_hsotg *hsotg) | ||
26 | { } | ||
27 | #endif | ||
diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c new file mode 100644 index 000000000000..ef2ee3d9a25d --- /dev/null +++ b/drivers/usb/dwc2/debugfs.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /** | ||
2 | * debugfs.c - Designware USB2 DRD controller debugfs | ||
3 | * | ||
4 | * Copyright (C) 2015 Intel Corporation | ||
5 | * Mian Yousaf Kaukab <yousaf.kaukab@intel.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 of | ||
9 | * the License as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/debugfs.h> | ||
19 | #include <linux/seq_file.h> | ||
20 | #include <linux/uaccess.h> | ||
21 | |||
22 | #include "core.h" | ||
23 | #include "debug.h" | ||
24 | |||
25 | #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \ | ||
26 | IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) | ||
27 | /** | ||
28 | * testmode_write - debugfs: change usb test mode | ||
29 | * @seq: The seq file to write to. | ||
30 | * @v: Unused parameter. | ||
31 | * | ||
32 | * This debugfs entry modify the current usb test mode. | ||
33 | */ | ||
34 | static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t | ||
35 | count, loff_t *ppos) | ||
36 | { | ||
37 | struct seq_file *s = file->private_data; | ||
38 | struct dwc2_hsotg *hsotg = s->private; | ||
39 | unsigned long flags; | ||
40 | u32 testmode = 0; | ||
41 | char buf[32]; | ||
42 | |||
43 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
44 | return -EFAULT; | ||
45 | |||
46 | if (!strncmp(buf, "test_j", 6)) | ||
47 | testmode = TEST_J; | ||
48 | else if (!strncmp(buf, "test_k", 6)) | ||
49 | testmode = TEST_K; | ||
50 | else if (!strncmp(buf, "test_se0_nak", 12)) | ||
51 | testmode = TEST_SE0_NAK; | ||
52 | else if (!strncmp(buf, "test_packet", 11)) | ||
53 | testmode = TEST_PACKET; | ||
54 | else if (!strncmp(buf, "test_force_enable", 17)) | ||
55 | testmode = TEST_FORCE_EN; | ||
56 | else | ||
57 | testmode = 0; | ||
58 | |||
59 | spin_lock_irqsave(&hsotg->lock, flags); | ||
60 | s3c_hsotg_set_test_mode(hsotg, testmode); | ||
61 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
62 | return count; | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * testmode_show - debugfs: show usb test mode state | ||
67 | * @seq: The seq file to write to. | ||
68 | * @v: Unused parameter. | ||
69 | * | ||
70 | * This debugfs entry shows which usb test mode is currently enabled. | ||
71 | */ | ||
72 | static int testmode_show(struct seq_file *s, void *unused) | ||
73 | { | ||
74 | struct dwc2_hsotg *hsotg = s->private; | ||
75 | unsigned long flags; | ||
76 | int dctl; | ||
77 | |||
78 | spin_lock_irqsave(&hsotg->lock, flags); | ||
79 | dctl = readl(hsotg->regs + DCTL); | ||
80 | dctl &= DCTL_TSTCTL_MASK; | ||
81 | dctl >>= DCTL_TSTCTL_SHIFT; | ||
82 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
83 | |||
84 | switch (dctl) { | ||
85 | case 0: | ||
86 | seq_puts(s, "no test\n"); | ||
87 | break; | ||
88 | case TEST_J: | ||
89 | seq_puts(s, "test_j\n"); | ||
90 | break; | ||
91 | case TEST_K: | ||
92 | seq_puts(s, "test_k\n"); | ||
93 | break; | ||
94 | case TEST_SE0_NAK: | ||
95 | seq_puts(s, "test_se0_nak\n"); | ||
96 | break; | ||
97 | case TEST_PACKET: | ||
98 | seq_puts(s, "test_packet\n"); | ||
99 | break; | ||
100 | case TEST_FORCE_EN: | ||
101 | seq_puts(s, "test_force_enable\n"); | ||
102 | break; | ||
103 | default: | ||
104 | seq_printf(s, "UNKNOWN %d\n", dctl); | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int testmode_open(struct inode *inode, struct file *file) | ||
111 | { | ||
112 | return single_open(file, testmode_show, inode->i_private); | ||
113 | } | ||
114 | |||
115 | static const struct file_operations testmode_fops = { | ||
116 | .owner = THIS_MODULE, | ||
117 | .open = testmode_open, | ||
118 | .write = testmode_write, | ||
119 | .read = seq_read, | ||
120 | .llseek = seq_lseek, | ||
121 | .release = single_release, | ||
122 | }; | ||
123 | |||
124 | /** | ||
125 | * state_show - debugfs: show overall driver and device state. | ||
126 | * @seq: The seq file to write to. | ||
127 | * @v: Unused parameter. | ||
128 | * | ||
129 | * This debugfs entry shows the overall state of the hardware and | ||
130 | * some general information about each of the endpoints available | ||
131 | * to the system. | ||
132 | */ | ||
133 | static int state_show(struct seq_file *seq, void *v) | ||
134 | { | ||
135 | struct dwc2_hsotg *hsotg = seq->private; | ||
136 | void __iomem *regs = hsotg->regs; | ||
137 | int idx; | ||
138 | |||
139 | seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n", | ||
140 | readl(regs + DCFG), | ||
141 | readl(regs + DCTL), | ||
142 | readl(regs + DSTS)); | ||
143 | |||
144 | seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n", | ||
145 | readl(regs + DIEPMSK), readl(regs + DOEPMSK)); | ||
146 | |||
147 | seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n", | ||
148 | readl(regs + GINTMSK), | ||
149 | readl(regs + GINTSTS)); | ||
150 | |||
151 | seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n", | ||
152 | readl(regs + DAINTMSK), | ||
153 | readl(regs + DAINT)); | ||
154 | |||
155 | seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n", | ||
156 | readl(regs + GNPTXSTS), | ||
157 | readl(regs + GRXSTSR)); | ||
158 | |||
159 | seq_puts(seq, "\nEndpoint status:\n"); | ||
160 | |||
161 | for (idx = 0; idx < hsotg->num_of_eps; idx++) { | ||
162 | u32 in, out; | ||
163 | |||
164 | in = readl(regs + DIEPCTL(idx)); | ||
165 | out = readl(regs + DOEPCTL(idx)); | ||
166 | |||
167 | seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x", | ||
168 | idx, in, out); | ||
169 | |||
170 | in = readl(regs + DIEPTSIZ(idx)); | ||
171 | out = readl(regs + DOEPTSIZ(idx)); | ||
172 | |||
173 | seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", | ||
174 | in, out); | ||
175 | |||
176 | seq_puts(seq, "\n"); | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int state_open(struct inode *inode, struct file *file) | ||
183 | { | ||
184 | return single_open(file, state_show, inode->i_private); | ||
185 | } | ||
186 | |||
187 | static const struct file_operations state_fops = { | ||
188 | .owner = THIS_MODULE, | ||
189 | .open = state_open, | ||
190 | .read = seq_read, | ||
191 | .llseek = seq_lseek, | ||
192 | .release = single_release, | ||
193 | }; | ||
194 | |||
195 | /** | ||
196 | * fifo_show - debugfs: show the fifo information | ||
197 | * @seq: The seq_file to write data to. | ||
198 | * @v: Unused parameter. | ||
199 | * | ||
200 | * Show the FIFO information for the overall fifo and all the | ||
201 | * periodic transmission FIFOs. | ||
202 | */ | ||
203 | static int fifo_show(struct seq_file *seq, void *v) | ||
204 | { | ||
205 | struct dwc2_hsotg *hsotg = seq->private; | ||
206 | void __iomem *regs = hsotg->regs; | ||
207 | u32 val; | ||
208 | int idx; | ||
209 | |||
210 | seq_puts(seq, "Non-periodic FIFOs:\n"); | ||
211 | seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ)); | ||
212 | |||
213 | val = readl(regs + GNPTXFSIZ); | ||
214 | seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n", | ||
215 | val >> FIFOSIZE_DEPTH_SHIFT, | ||
216 | val & FIFOSIZE_DEPTH_MASK); | ||
217 | |||
218 | seq_puts(seq, "\nPeriodic TXFIFOs:\n"); | ||
219 | |||
220 | for (idx = 1; idx < hsotg->num_of_eps; idx++) { | ||
221 | val = readl(regs + DPTXFSIZN(idx)); | ||
222 | |||
223 | seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, | ||
224 | val >> FIFOSIZE_DEPTH_SHIFT, | ||
225 | val & FIFOSIZE_STARTADDR_MASK); | ||
226 | } | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int fifo_open(struct inode *inode, struct file *file) | ||
232 | { | ||
233 | return single_open(file, fifo_show, inode->i_private); | ||
234 | } | ||
235 | |||
236 | static const struct file_operations fifo_fops = { | ||
237 | .owner = THIS_MODULE, | ||
238 | .open = fifo_open, | ||
239 | .read = seq_read, | ||
240 | .llseek = seq_lseek, | ||
241 | .release = single_release, | ||
242 | }; | ||
243 | |||
244 | static const char *decode_direction(int is_in) | ||
245 | { | ||
246 | return is_in ? "in" : "out"; | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * ep_show - debugfs: show the state of an endpoint. | ||
251 | * @seq: The seq_file to write data to. | ||
252 | * @v: Unused parameter. | ||
253 | * | ||
254 | * This debugfs entry shows the state of the given endpoint (one is | ||
255 | * registered for each available). | ||
256 | */ | ||
257 | static int ep_show(struct seq_file *seq, void *v) | ||
258 | { | ||
259 | struct s3c_hsotg_ep *ep = seq->private; | ||
260 | struct dwc2_hsotg *hsotg = ep->parent; | ||
261 | struct s3c_hsotg_req *req; | ||
262 | void __iomem *regs = hsotg->regs; | ||
263 | int index = ep->index; | ||
264 | int show_limit = 15; | ||
265 | unsigned long flags; | ||
266 | |||
267 | seq_printf(seq, "Endpoint index %d, named %s, dir %s:\n", | ||
268 | ep->index, ep->ep.name, decode_direction(ep->dir_in)); | ||
269 | |||
270 | /* first show the register state */ | ||
271 | |||
272 | seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n", | ||
273 | readl(regs + DIEPCTL(index)), | ||
274 | readl(regs + DOEPCTL(index))); | ||
275 | |||
276 | seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n", | ||
277 | readl(regs + DIEPDMA(index)), | ||
278 | readl(regs + DOEPDMA(index))); | ||
279 | |||
280 | seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n", | ||
281 | readl(regs + DIEPINT(index)), | ||
282 | readl(regs + DOEPINT(index))); | ||
283 | |||
284 | seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n", | ||
285 | readl(regs + DIEPTSIZ(index)), | ||
286 | readl(regs + DOEPTSIZ(index))); | ||
287 | |||
288 | seq_puts(seq, "\n"); | ||
289 | seq_printf(seq, "mps %d\n", ep->ep.maxpacket); | ||
290 | seq_printf(seq, "total_data=%ld\n", ep->total_data); | ||
291 | |||
292 | seq_printf(seq, "request list (%p,%p):\n", | ||
293 | ep->queue.next, ep->queue.prev); | ||
294 | |||
295 | spin_lock_irqsave(&hsotg->lock, flags); | ||
296 | |||
297 | list_for_each_entry(req, &ep->queue, queue) { | ||
298 | if (--show_limit < 0) { | ||
299 | seq_puts(seq, "not showing more requests...\n"); | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | seq_printf(seq, "%c req %p: %d bytes @%p, ", | ||
304 | req == ep->req ? '*' : ' ', | ||
305 | req, req->req.length, req->req.buf); | ||
306 | seq_printf(seq, "%d done, res %d\n", | ||
307 | req->req.actual, req->req.status); | ||
308 | } | ||
309 | |||
310 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int ep_open(struct inode *inode, struct file *file) | ||
316 | { | ||
317 | return single_open(file, ep_show, inode->i_private); | ||
318 | } | ||
319 | |||
320 | static const struct file_operations ep_fops = { | ||
321 | .owner = THIS_MODULE, | ||
322 | .open = ep_open, | ||
323 | .read = seq_read, | ||
324 | .llseek = seq_lseek, | ||
325 | .release = single_release, | ||
326 | }; | ||
327 | |||
328 | /** | ||
329 | * s3c_hsotg_create_debug - create debugfs directory and files | ||
330 | * @hsotg: The driver state | ||
331 | * | ||
332 | * Create the debugfs files to allow the user to get information | ||
333 | * about the state of the system. The directory name is created | ||
334 | * with the same name as the device itself, in case we end up | ||
335 | * with multiple blocks in future systems. | ||
336 | */ | ||
337 | static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) | ||
338 | { | ||
339 | struct dentry *root; | ||
340 | struct dentry *file; | ||
341 | unsigned epidx; | ||
342 | |||
343 | root = hsotg->debug_root; | ||
344 | |||
345 | /* create general state file */ | ||
346 | |||
347 | file = debugfs_create_file("state", S_IRUGO, root, hsotg, &state_fops); | ||
348 | if (IS_ERR(file)) | ||
349 | dev_err(hsotg->dev, "%s: failed to create state\n", __func__); | ||
350 | |||
351 | file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, hsotg, | ||
352 | &testmode_fops); | ||
353 | if (IS_ERR(file)) | ||
354 | dev_err(hsotg->dev, "%s: failed to create testmode\n", | ||
355 | __func__); | ||
356 | |||
357 | file = debugfs_create_file("fifo", S_IRUGO, root, hsotg, &fifo_fops); | ||
358 | if (IS_ERR(file)) | ||
359 | dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); | ||
360 | |||
361 | /* Create one file for each out endpoint */ | ||
362 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { | ||
363 | struct s3c_hsotg_ep *ep; | ||
364 | |||
365 | ep = hsotg->eps_out[epidx]; | ||
366 | if (ep) { | ||
367 | file = debugfs_create_file(ep->name, S_IRUGO, | ||
368 | root, ep, &ep_fops); | ||
369 | if (IS_ERR(file)) | ||
370 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
371 | ep->name); | ||
372 | } | ||
373 | } | ||
374 | /* Create one file for each in endpoint. EP0 is handled with out eps */ | ||
375 | for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) { | ||
376 | struct s3c_hsotg_ep *ep; | ||
377 | |||
378 | ep = hsotg->eps_in[epidx]; | ||
379 | if (ep) { | ||
380 | file = debugfs_create_file(ep->name, S_IRUGO, | ||
381 | root, ep, &ep_fops); | ||
382 | if (IS_ERR(file)) | ||
383 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
384 | ep->name); | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | #else | ||
389 | static inline void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) {} | ||
390 | #endif | ||
391 | |||
392 | /* s3c_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */ | ||
393 | |||
394 | #define dump_register(nm) \ | ||
395 | { \ | ||
396 | .name = #nm, \ | ||
397 | .offset = nm, \ | ||
398 | } | ||
399 | |||
400 | static const struct debugfs_reg32 dwc2_regs[] = { | ||
401 | /* | ||
402 | * Accessing registers like this can trigger mode mismatch interrupt. | ||
403 | * However, according to dwc2 databook, the register access, in this | ||
404 | * case, is completed on the processor bus but is ignored by the core | ||
405 | * and does not affect its operation. | ||
406 | */ | ||
407 | dump_register(GOTGCTL), | ||
408 | dump_register(GOTGINT), | ||
409 | dump_register(GAHBCFG), | ||
410 | dump_register(GUSBCFG), | ||
411 | dump_register(GRSTCTL), | ||
412 | dump_register(GINTSTS), | ||
413 | dump_register(GINTMSK), | ||
414 | dump_register(GRXSTSR), | ||
415 | dump_register(GRXSTSP), | ||
416 | dump_register(GRXFSIZ), | ||
417 | dump_register(GNPTXFSIZ), | ||
418 | dump_register(GNPTXSTS), | ||
419 | dump_register(GI2CCTL), | ||
420 | dump_register(GPVNDCTL), | ||
421 | dump_register(GGPIO), | ||
422 | dump_register(GUID), | ||
423 | dump_register(GSNPSID), | ||
424 | dump_register(GHWCFG1), | ||
425 | dump_register(GHWCFG2), | ||
426 | dump_register(GHWCFG3), | ||
427 | dump_register(GHWCFG4), | ||
428 | dump_register(GLPMCFG), | ||
429 | dump_register(GPWRDN), | ||
430 | dump_register(GDFIFOCFG), | ||
431 | dump_register(ADPCTL), | ||
432 | dump_register(HPTXFSIZ), | ||
433 | dump_register(DPTXFSIZN(1)), | ||
434 | dump_register(DPTXFSIZN(2)), | ||
435 | dump_register(DPTXFSIZN(3)), | ||
436 | dump_register(DPTXFSIZN(4)), | ||
437 | dump_register(DPTXFSIZN(5)), | ||
438 | dump_register(DPTXFSIZN(6)), | ||
439 | dump_register(DPTXFSIZN(7)), | ||
440 | dump_register(DPTXFSIZN(8)), | ||
441 | dump_register(DPTXFSIZN(9)), | ||
442 | dump_register(DPTXFSIZN(10)), | ||
443 | dump_register(DPTXFSIZN(11)), | ||
444 | dump_register(DPTXFSIZN(12)), | ||
445 | dump_register(DPTXFSIZN(13)), | ||
446 | dump_register(DPTXFSIZN(14)), | ||
447 | dump_register(DPTXFSIZN(15)), | ||
448 | dump_register(DCFG), | ||
449 | dump_register(DCTL), | ||
450 | dump_register(DSTS), | ||
451 | dump_register(DIEPMSK), | ||
452 | dump_register(DOEPMSK), | ||
453 | dump_register(DAINT), | ||
454 | dump_register(DAINTMSK), | ||
455 | dump_register(DTKNQR1), | ||
456 | dump_register(DTKNQR2), | ||
457 | dump_register(DTKNQR3), | ||
458 | dump_register(DTKNQR4), | ||
459 | dump_register(DVBUSDIS), | ||
460 | dump_register(DVBUSPULSE), | ||
461 | dump_register(DIEPCTL(0)), | ||
462 | dump_register(DIEPCTL(1)), | ||
463 | dump_register(DIEPCTL(2)), | ||
464 | dump_register(DIEPCTL(3)), | ||
465 | dump_register(DIEPCTL(4)), | ||
466 | dump_register(DIEPCTL(5)), | ||
467 | dump_register(DIEPCTL(6)), | ||
468 | dump_register(DIEPCTL(7)), | ||
469 | dump_register(DIEPCTL(8)), | ||
470 | dump_register(DIEPCTL(9)), | ||
471 | dump_register(DIEPCTL(10)), | ||
472 | dump_register(DIEPCTL(11)), | ||
473 | dump_register(DIEPCTL(12)), | ||
474 | dump_register(DIEPCTL(13)), | ||
475 | dump_register(DIEPCTL(14)), | ||
476 | dump_register(DIEPCTL(15)), | ||
477 | dump_register(DOEPCTL(0)), | ||
478 | dump_register(DOEPCTL(1)), | ||
479 | dump_register(DOEPCTL(2)), | ||
480 | dump_register(DOEPCTL(3)), | ||
481 | dump_register(DOEPCTL(4)), | ||
482 | dump_register(DOEPCTL(5)), | ||
483 | dump_register(DOEPCTL(6)), | ||
484 | dump_register(DOEPCTL(7)), | ||
485 | dump_register(DOEPCTL(8)), | ||
486 | dump_register(DOEPCTL(9)), | ||
487 | dump_register(DOEPCTL(10)), | ||
488 | dump_register(DOEPCTL(11)), | ||
489 | dump_register(DOEPCTL(12)), | ||
490 | dump_register(DOEPCTL(13)), | ||
491 | dump_register(DOEPCTL(14)), | ||
492 | dump_register(DOEPCTL(15)), | ||
493 | dump_register(DIEPINT(0)), | ||
494 | dump_register(DIEPINT(1)), | ||
495 | dump_register(DIEPINT(2)), | ||
496 | dump_register(DIEPINT(3)), | ||
497 | dump_register(DIEPINT(4)), | ||
498 | dump_register(DIEPINT(5)), | ||
499 | dump_register(DIEPINT(6)), | ||
500 | dump_register(DIEPINT(7)), | ||
501 | dump_register(DIEPINT(8)), | ||
502 | dump_register(DIEPINT(9)), | ||
503 | dump_register(DIEPINT(10)), | ||
504 | dump_register(DIEPINT(11)), | ||
505 | dump_register(DIEPINT(12)), | ||
506 | dump_register(DIEPINT(13)), | ||
507 | dump_register(DIEPINT(14)), | ||
508 | dump_register(DIEPINT(15)), | ||
509 | dump_register(DOEPINT(0)), | ||
510 | dump_register(DOEPINT(1)), | ||
511 | dump_register(DOEPINT(2)), | ||
512 | dump_register(DOEPINT(3)), | ||
513 | dump_register(DOEPINT(4)), | ||
514 | dump_register(DOEPINT(5)), | ||
515 | dump_register(DOEPINT(6)), | ||
516 | dump_register(DOEPINT(7)), | ||
517 | dump_register(DOEPINT(8)), | ||
518 | dump_register(DOEPINT(9)), | ||
519 | dump_register(DOEPINT(10)), | ||
520 | dump_register(DOEPINT(11)), | ||
521 | dump_register(DOEPINT(12)), | ||
522 | dump_register(DOEPINT(13)), | ||
523 | dump_register(DOEPINT(14)), | ||
524 | dump_register(DOEPINT(15)), | ||
525 | dump_register(DIEPTSIZ(0)), | ||
526 | dump_register(DIEPTSIZ(1)), | ||
527 | dump_register(DIEPTSIZ(2)), | ||
528 | dump_register(DIEPTSIZ(3)), | ||
529 | dump_register(DIEPTSIZ(4)), | ||
530 | dump_register(DIEPTSIZ(5)), | ||
531 | dump_register(DIEPTSIZ(6)), | ||
532 | dump_register(DIEPTSIZ(7)), | ||
533 | dump_register(DIEPTSIZ(8)), | ||
534 | dump_register(DIEPTSIZ(9)), | ||
535 | dump_register(DIEPTSIZ(10)), | ||
536 | dump_register(DIEPTSIZ(11)), | ||
537 | dump_register(DIEPTSIZ(12)), | ||
538 | dump_register(DIEPTSIZ(13)), | ||
539 | dump_register(DIEPTSIZ(14)), | ||
540 | dump_register(DIEPTSIZ(15)), | ||
541 | dump_register(DOEPTSIZ(0)), | ||
542 | dump_register(DOEPTSIZ(1)), | ||
543 | dump_register(DOEPTSIZ(2)), | ||
544 | dump_register(DOEPTSIZ(3)), | ||
545 | dump_register(DOEPTSIZ(4)), | ||
546 | dump_register(DOEPTSIZ(5)), | ||
547 | dump_register(DOEPTSIZ(6)), | ||
548 | dump_register(DOEPTSIZ(7)), | ||
549 | dump_register(DOEPTSIZ(8)), | ||
550 | dump_register(DOEPTSIZ(9)), | ||
551 | dump_register(DOEPTSIZ(10)), | ||
552 | dump_register(DOEPTSIZ(11)), | ||
553 | dump_register(DOEPTSIZ(12)), | ||
554 | dump_register(DOEPTSIZ(13)), | ||
555 | dump_register(DOEPTSIZ(14)), | ||
556 | dump_register(DOEPTSIZ(15)), | ||
557 | dump_register(DIEPDMA(0)), | ||
558 | dump_register(DIEPDMA(1)), | ||
559 | dump_register(DIEPDMA(2)), | ||
560 | dump_register(DIEPDMA(3)), | ||
561 | dump_register(DIEPDMA(4)), | ||
562 | dump_register(DIEPDMA(5)), | ||
563 | dump_register(DIEPDMA(6)), | ||
564 | dump_register(DIEPDMA(7)), | ||
565 | dump_register(DIEPDMA(8)), | ||
566 | dump_register(DIEPDMA(9)), | ||
567 | dump_register(DIEPDMA(10)), | ||
568 | dump_register(DIEPDMA(11)), | ||
569 | dump_register(DIEPDMA(12)), | ||
570 | dump_register(DIEPDMA(13)), | ||
571 | dump_register(DIEPDMA(14)), | ||
572 | dump_register(DIEPDMA(15)), | ||
573 | dump_register(DOEPDMA(0)), | ||
574 | dump_register(DOEPDMA(1)), | ||
575 | dump_register(DOEPDMA(2)), | ||
576 | dump_register(DOEPDMA(3)), | ||
577 | dump_register(DOEPDMA(4)), | ||
578 | dump_register(DOEPDMA(5)), | ||
579 | dump_register(DOEPDMA(6)), | ||
580 | dump_register(DOEPDMA(7)), | ||
581 | dump_register(DOEPDMA(8)), | ||
582 | dump_register(DOEPDMA(9)), | ||
583 | dump_register(DOEPDMA(10)), | ||
584 | dump_register(DOEPDMA(11)), | ||
585 | dump_register(DOEPDMA(12)), | ||
586 | dump_register(DOEPDMA(13)), | ||
587 | dump_register(DOEPDMA(14)), | ||
588 | dump_register(DOEPDMA(15)), | ||
589 | dump_register(DTXFSTS(0)), | ||
590 | dump_register(DTXFSTS(1)), | ||
591 | dump_register(DTXFSTS(2)), | ||
592 | dump_register(DTXFSTS(3)), | ||
593 | dump_register(DTXFSTS(4)), | ||
594 | dump_register(DTXFSTS(5)), | ||
595 | dump_register(DTXFSTS(6)), | ||
596 | dump_register(DTXFSTS(7)), | ||
597 | dump_register(DTXFSTS(8)), | ||
598 | dump_register(DTXFSTS(9)), | ||
599 | dump_register(DTXFSTS(10)), | ||
600 | dump_register(DTXFSTS(11)), | ||
601 | dump_register(DTXFSTS(12)), | ||
602 | dump_register(DTXFSTS(13)), | ||
603 | dump_register(DTXFSTS(14)), | ||
604 | dump_register(DTXFSTS(15)), | ||
605 | dump_register(PCGCTL), | ||
606 | dump_register(HCFG), | ||
607 | dump_register(HFIR), | ||
608 | dump_register(HFNUM), | ||
609 | dump_register(HPTXSTS), | ||
610 | dump_register(HAINT), | ||
611 | dump_register(HAINTMSK), | ||
612 | dump_register(HFLBADDR), | ||
613 | dump_register(HPRT0), | ||
614 | dump_register(HCCHAR(0)), | ||
615 | dump_register(HCCHAR(1)), | ||
616 | dump_register(HCCHAR(2)), | ||
617 | dump_register(HCCHAR(3)), | ||
618 | dump_register(HCCHAR(4)), | ||
619 | dump_register(HCCHAR(5)), | ||
620 | dump_register(HCCHAR(6)), | ||
621 | dump_register(HCCHAR(7)), | ||
622 | dump_register(HCCHAR(8)), | ||
623 | dump_register(HCCHAR(9)), | ||
624 | dump_register(HCCHAR(10)), | ||
625 | dump_register(HCCHAR(11)), | ||
626 | dump_register(HCCHAR(12)), | ||
627 | dump_register(HCCHAR(13)), | ||
628 | dump_register(HCCHAR(14)), | ||
629 | dump_register(HCCHAR(15)), | ||
630 | dump_register(HCSPLT(0)), | ||
631 | dump_register(HCSPLT(1)), | ||
632 | dump_register(HCSPLT(2)), | ||
633 | dump_register(HCSPLT(3)), | ||
634 | dump_register(HCSPLT(4)), | ||
635 | dump_register(HCSPLT(5)), | ||
636 | dump_register(HCSPLT(6)), | ||
637 | dump_register(HCSPLT(7)), | ||
638 | dump_register(HCSPLT(8)), | ||
639 | dump_register(HCSPLT(9)), | ||
640 | dump_register(HCSPLT(10)), | ||
641 | dump_register(HCSPLT(11)), | ||
642 | dump_register(HCSPLT(12)), | ||
643 | dump_register(HCSPLT(13)), | ||
644 | dump_register(HCSPLT(14)), | ||
645 | dump_register(HCSPLT(15)), | ||
646 | dump_register(HCINT(0)), | ||
647 | dump_register(HCINT(1)), | ||
648 | dump_register(HCINT(2)), | ||
649 | dump_register(HCINT(3)), | ||
650 | dump_register(HCINT(4)), | ||
651 | dump_register(HCINT(5)), | ||
652 | dump_register(HCINT(6)), | ||
653 | dump_register(HCINT(7)), | ||
654 | dump_register(HCINT(8)), | ||
655 | dump_register(HCINT(9)), | ||
656 | dump_register(HCINT(10)), | ||
657 | dump_register(HCINT(11)), | ||
658 | dump_register(HCINT(12)), | ||
659 | dump_register(HCINT(13)), | ||
660 | dump_register(HCINT(14)), | ||
661 | dump_register(HCINT(15)), | ||
662 | dump_register(HCINTMSK(0)), | ||
663 | dump_register(HCINTMSK(1)), | ||
664 | dump_register(HCINTMSK(2)), | ||
665 | dump_register(HCINTMSK(3)), | ||
666 | dump_register(HCINTMSK(4)), | ||
667 | dump_register(HCINTMSK(5)), | ||
668 | dump_register(HCINTMSK(6)), | ||
669 | dump_register(HCINTMSK(7)), | ||
670 | dump_register(HCINTMSK(8)), | ||
671 | dump_register(HCINTMSK(9)), | ||
672 | dump_register(HCINTMSK(10)), | ||
673 | dump_register(HCINTMSK(11)), | ||
674 | dump_register(HCINTMSK(12)), | ||
675 | dump_register(HCINTMSK(13)), | ||
676 | dump_register(HCINTMSK(14)), | ||
677 | dump_register(HCINTMSK(15)), | ||
678 | dump_register(HCTSIZ(0)), | ||
679 | dump_register(HCTSIZ(1)), | ||
680 | dump_register(HCTSIZ(2)), | ||
681 | dump_register(HCTSIZ(3)), | ||
682 | dump_register(HCTSIZ(4)), | ||
683 | dump_register(HCTSIZ(5)), | ||
684 | dump_register(HCTSIZ(6)), | ||
685 | dump_register(HCTSIZ(7)), | ||
686 | dump_register(HCTSIZ(8)), | ||
687 | dump_register(HCTSIZ(9)), | ||
688 | dump_register(HCTSIZ(10)), | ||
689 | dump_register(HCTSIZ(11)), | ||
690 | dump_register(HCTSIZ(12)), | ||
691 | dump_register(HCTSIZ(13)), | ||
692 | dump_register(HCTSIZ(14)), | ||
693 | dump_register(HCTSIZ(15)), | ||
694 | dump_register(HCDMA(0)), | ||
695 | dump_register(HCDMA(1)), | ||
696 | dump_register(HCDMA(2)), | ||
697 | dump_register(HCDMA(3)), | ||
698 | dump_register(HCDMA(4)), | ||
699 | dump_register(HCDMA(5)), | ||
700 | dump_register(HCDMA(6)), | ||
701 | dump_register(HCDMA(7)), | ||
702 | dump_register(HCDMA(8)), | ||
703 | dump_register(HCDMA(9)), | ||
704 | dump_register(HCDMA(10)), | ||
705 | dump_register(HCDMA(11)), | ||
706 | dump_register(HCDMA(12)), | ||
707 | dump_register(HCDMA(13)), | ||
708 | dump_register(HCDMA(14)), | ||
709 | dump_register(HCDMA(15)), | ||
710 | dump_register(HCDMAB(0)), | ||
711 | dump_register(HCDMAB(1)), | ||
712 | dump_register(HCDMAB(2)), | ||
713 | dump_register(HCDMAB(3)), | ||
714 | dump_register(HCDMAB(4)), | ||
715 | dump_register(HCDMAB(5)), | ||
716 | dump_register(HCDMAB(6)), | ||
717 | dump_register(HCDMAB(7)), | ||
718 | dump_register(HCDMAB(8)), | ||
719 | dump_register(HCDMAB(9)), | ||
720 | dump_register(HCDMAB(10)), | ||
721 | dump_register(HCDMAB(11)), | ||
722 | dump_register(HCDMAB(12)), | ||
723 | dump_register(HCDMAB(13)), | ||
724 | dump_register(HCDMAB(14)), | ||
725 | dump_register(HCDMAB(15)), | ||
726 | }; | ||
727 | |||
728 | int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) | ||
729 | { | ||
730 | int ret; | ||
731 | struct dentry *file; | ||
732 | |||
733 | hsotg->debug_root = debugfs_create_dir(dev_name(hsotg->dev), NULL); | ||
734 | if (!hsotg->debug_root) { | ||
735 | ret = -ENOMEM; | ||
736 | goto err0; | ||
737 | } | ||
738 | |||
739 | /* Add gadget debugfs nodes */ | ||
740 | s3c_hsotg_create_debug(hsotg); | ||
741 | |||
742 | hsotg->regset = devm_kzalloc(hsotg->dev, sizeof(*hsotg->regset), | ||
743 | GFP_KERNEL); | ||
744 | if (!hsotg->regset) { | ||
745 | ret = -ENOMEM; | ||
746 | goto err1; | ||
747 | } | ||
748 | |||
749 | hsotg->regset->regs = dwc2_regs; | ||
750 | hsotg->regset->nregs = ARRAY_SIZE(dwc2_regs); | ||
751 | hsotg->regset->base = hsotg->regs; | ||
752 | |||
753 | file = debugfs_create_regset32("regdump", S_IRUGO, hsotg->debug_root, | ||
754 | hsotg->regset); | ||
755 | if (!file) { | ||
756 | ret = -ENOMEM; | ||
757 | goto err1; | ||
758 | } | ||
759 | |||
760 | return 0; | ||
761 | err1: | ||
762 | debugfs_remove_recursive(hsotg->debug_root); | ||
763 | err0: | ||
764 | return ret; | ||
765 | } | ||
766 | |||
767 | void dwc2_debugfs_exit(struct dwc2_hsotg *hsotg) | ||
768 | { | ||
769 | debugfs_remove_recursive(hsotg->debug_root); | ||
770 | hsotg->debug_root = NULL; | ||
771 | } | ||
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6a30887082cd..4d47b7c09238 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/debugfs.h> | ||
24 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
25 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
26 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
@@ -35,7 +34,6 @@ | |||
35 | #include <linux/usb/gadget.h> | 34 | #include <linux/usb/gadget.h> |
36 | #include <linux/usb/phy.h> | 35 | #include <linux/usb/phy.h> |
37 | #include <linux/platform_data/s3c-hsotg.h> | 36 | #include <linux/platform_data/s3c-hsotg.h> |
38 | #include <linux/uaccess.h> | ||
39 | 37 | ||
40 | #include "core.h" | 38 | #include "core.h" |
41 | #include "hw.h" | 39 | #include "hw.h" |
@@ -792,6 +790,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
792 | ep->name, req, req->length, req->buf, req->no_interrupt, | 790 | ep->name, req, req->length, req->buf, req->no_interrupt, |
793 | req->zero, req->short_not_ok); | 791 | req->zero, req->short_not_ok); |
794 | 792 | ||
793 | /* Prevent new request submission when controller is suspended */ | ||
794 | if (hs->lx_state == DWC2_L2) { | ||
795 | dev_dbg(hs->dev, "%s: don't submit request while suspended\n", | ||
796 | __func__); | ||
797 | return -EAGAIN; | ||
798 | } | ||
799 | |||
795 | /* initialise status of the request */ | 800 | /* initialise status of the request */ |
796 | INIT_LIST_HEAD(&hs_req->queue); | 801 | INIT_LIST_HEAD(&hs_req->queue); |
797 | req->actual = 0; | 802 | req->actual = 0; |
@@ -894,7 +899,7 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, | |||
894 | * @testmode: requested usb test mode | 899 | * @testmode: requested usb test mode |
895 | * Enable usb Test Mode requested by the Host. | 900 | * Enable usb Test Mode requested by the Host. |
896 | */ | 901 | */ |
897 | static int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) | 902 | int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) |
898 | { | 903 | { |
899 | int dctl = readl(hsotg->regs + DCTL); | 904 | int dctl = readl(hsotg->regs + DCTL); |
900 | 905 | ||
@@ -2185,7 +2190,6 @@ void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) | |||
2185 | 2190 | ||
2186 | call_gadget(hsotg, disconnect); | 2191 | call_gadget(hsotg, disconnect); |
2187 | } | 2192 | } |
2188 | EXPORT_SYMBOL_GPL(s3c_hsotg_disconnect); | ||
2189 | 2193 | ||
2190 | /** | 2194 | /** |
2191 | * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler | 2195 | * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler |
@@ -2310,8 +2314,9 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, | |||
2310 | writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | | 2314 | writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | |
2311 | GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF | | 2315 | GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF | |
2312 | GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST | | 2316 | GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST | |
2313 | GINTSTS_ENUMDONE | GINTSTS_OTGINT | | 2317 | GINTSTS_RESETDET | GINTSTS_ENUMDONE | |
2314 | GINTSTS_USBSUSP | GINTSTS_WKUPINT, | 2318 | GINTSTS_OTGINT | GINTSTS_USBSUSP | |
2319 | GINTSTS_WKUPINT, | ||
2315 | hsotg->regs + GINTMSK); | 2320 | hsotg->regs + GINTMSK); |
2316 | 2321 | ||
2317 | if (using_dma(hsotg)) | 2322 | if (using_dma(hsotg)) |
@@ -2477,7 +2482,19 @@ irq_retry: | |||
2477 | } | 2482 | } |
2478 | } | 2483 | } |
2479 | 2484 | ||
2480 | if (gintsts & GINTSTS_USBRST) { | 2485 | if (gintsts & GINTSTS_RESETDET) { |
2486 | dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__); | ||
2487 | |||
2488 | writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS); | ||
2489 | |||
2490 | /* This event must be used only if controller is suspended */ | ||
2491 | if (hsotg->lx_state == DWC2_L2) { | ||
2492 | dwc2_exit_hibernation(hsotg, true); | ||
2493 | hsotg->lx_state = DWC2_L0; | ||
2494 | } | ||
2495 | } | ||
2496 | |||
2497 | if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { | ||
2481 | 2498 | ||
2482 | u32 usb_status = readl(hsotg->regs + GOTGCTL); | 2499 | u32 usb_status = readl(hsotg->regs + GOTGCTL); |
2483 | 2500 | ||
@@ -2497,6 +2514,7 @@ irq_retry: | |||
2497 | kill_all_requests(hsotg, hsotg->eps_out[0], | 2514 | kill_all_requests(hsotg, hsotg->eps_out[0], |
2498 | -ECONNRESET); | 2515 | -ECONNRESET); |
2499 | 2516 | ||
2517 | hsotg->lx_state = DWC2_L0; | ||
2500 | s3c_hsotg_core_init_disconnected(hsotg, true); | 2518 | s3c_hsotg_core_init_disconnected(hsotg, true); |
2501 | } | 2519 | } |
2502 | } | 2520 | } |
@@ -2745,7 +2763,7 @@ error: | |||
2745 | * s3c_hsotg_ep_disable - disable given endpoint | 2763 | * s3c_hsotg_ep_disable - disable given endpoint |
2746 | * @ep: The endpoint to disable. | 2764 | * @ep: The endpoint to disable. |
2747 | */ | 2765 | */ |
2748 | static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) | 2766 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) |
2749 | { | 2767 | { |
2750 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2768 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2751 | struct dwc2_hsotg *hsotg = hs_ep->parent; | 2769 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
@@ -2788,10 +2806,6 @@ static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) | |||
2788 | return 0; | 2806 | return 0; |
2789 | } | 2807 | } |
2790 | 2808 | ||
2791 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) | ||
2792 | { | ||
2793 | return s3c_hsotg_ep_disable_force(ep, false); | ||
2794 | } | ||
2795 | /** | 2809 | /** |
2796 | * on_list - check request is on the given endpoint | 2810 | * on_list - check request is on the given endpoint |
2797 | * @ep: The endpoint to check. | 2811 | * @ep: The endpoint to check. |
@@ -3187,6 +3201,14 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) | |||
3187 | spin_lock_irqsave(&hsotg->lock, flags); | 3201 | spin_lock_irqsave(&hsotg->lock, flags); |
3188 | 3202 | ||
3189 | if (is_active) { | 3203 | if (is_active) { |
3204 | /* | ||
3205 | * If controller is hibernated, it must exit from hibernation | ||
3206 | * before being initialized | ||
3207 | */ | ||
3208 | if (hsotg->lx_state == DWC2_L2) { | ||
3209 | dwc2_exit_hibernation(hsotg, false); | ||
3210 | hsotg->lx_state = DWC2_L0; | ||
3211 | } | ||
3190 | /* Kill any ep0 requests as controller will be reinitialized */ | 3212 | /* Kill any ep0 requests as controller will be reinitialized */ |
3191 | kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); | 3213 | kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); |
3192 | s3c_hsotg_core_init_disconnected(hsotg, false); | 3214 | s3c_hsotg_core_init_disconnected(hsotg, false); |
@@ -3391,404 +3413,6 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) | |||
3391 | #endif | 3413 | #endif |
3392 | } | 3414 | } |
3393 | 3415 | ||
3394 | /** | ||
3395 | * testmode_write - debugfs: change usb test mode | ||
3396 | * @seq: The seq file to write to. | ||
3397 | * @v: Unused parameter. | ||
3398 | * | ||
3399 | * This debugfs entry modify the current usb test mode. | ||
3400 | */ | ||
3401 | static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t | ||
3402 | count, loff_t *ppos) | ||
3403 | { | ||
3404 | struct seq_file *s = file->private_data; | ||
3405 | struct dwc2_hsotg *hsotg = s->private; | ||
3406 | unsigned long flags; | ||
3407 | u32 testmode = 0; | ||
3408 | char buf[32]; | ||
3409 | |||
3410 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
3411 | return -EFAULT; | ||
3412 | |||
3413 | if (!strncmp(buf, "test_j", 6)) | ||
3414 | testmode = TEST_J; | ||
3415 | else if (!strncmp(buf, "test_k", 6)) | ||
3416 | testmode = TEST_K; | ||
3417 | else if (!strncmp(buf, "test_se0_nak", 12)) | ||
3418 | testmode = TEST_SE0_NAK; | ||
3419 | else if (!strncmp(buf, "test_packet", 11)) | ||
3420 | testmode = TEST_PACKET; | ||
3421 | else if (!strncmp(buf, "test_force_enable", 17)) | ||
3422 | testmode = TEST_FORCE_EN; | ||
3423 | else | ||
3424 | testmode = 0; | ||
3425 | |||
3426 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3427 | s3c_hsotg_set_test_mode(hsotg, testmode); | ||
3428 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3429 | return count; | ||
3430 | } | ||
3431 | |||
3432 | /** | ||
3433 | * testmode_show - debugfs: show usb test mode state | ||
3434 | * @seq: The seq file to write to. | ||
3435 | * @v: Unused parameter. | ||
3436 | * | ||
3437 | * This debugfs entry shows which usb test mode is currently enabled. | ||
3438 | */ | ||
3439 | static int testmode_show(struct seq_file *s, void *unused) | ||
3440 | { | ||
3441 | struct dwc2_hsotg *hsotg = s->private; | ||
3442 | unsigned long flags; | ||
3443 | int dctl; | ||
3444 | |||
3445 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3446 | dctl = readl(hsotg->regs + DCTL); | ||
3447 | dctl &= DCTL_TSTCTL_MASK; | ||
3448 | dctl >>= DCTL_TSTCTL_SHIFT; | ||
3449 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3450 | |||
3451 | switch (dctl) { | ||
3452 | case 0: | ||
3453 | seq_puts(s, "no test\n"); | ||
3454 | break; | ||
3455 | case TEST_J: | ||
3456 | seq_puts(s, "test_j\n"); | ||
3457 | break; | ||
3458 | case TEST_K: | ||
3459 | seq_puts(s, "test_k\n"); | ||
3460 | break; | ||
3461 | case TEST_SE0_NAK: | ||
3462 | seq_puts(s, "test_se0_nak\n"); | ||
3463 | break; | ||
3464 | case TEST_PACKET: | ||
3465 | seq_puts(s, "test_packet\n"); | ||
3466 | break; | ||
3467 | case TEST_FORCE_EN: | ||
3468 | seq_puts(s, "test_force_enable\n"); | ||
3469 | break; | ||
3470 | default: | ||
3471 | seq_printf(s, "UNKNOWN %d\n", dctl); | ||
3472 | } | ||
3473 | |||
3474 | return 0; | ||
3475 | } | ||
3476 | |||
3477 | static int testmode_open(struct inode *inode, struct file *file) | ||
3478 | { | ||
3479 | return single_open(file, testmode_show, inode->i_private); | ||
3480 | } | ||
3481 | |||
3482 | static const struct file_operations testmode_fops = { | ||
3483 | .owner = THIS_MODULE, | ||
3484 | .open = testmode_open, | ||
3485 | .write = testmode_write, | ||
3486 | .read = seq_read, | ||
3487 | .llseek = seq_lseek, | ||
3488 | .release = single_release, | ||
3489 | }; | ||
3490 | |||
3491 | /** | ||
3492 | * state_show - debugfs: show overall driver and device state. | ||
3493 | * @seq: The seq file to write to. | ||
3494 | * @v: Unused parameter. | ||
3495 | * | ||
3496 | * This debugfs entry shows the overall state of the hardware and | ||
3497 | * some general information about each of the endpoints available | ||
3498 | * to the system. | ||
3499 | */ | ||
3500 | static int state_show(struct seq_file *seq, void *v) | ||
3501 | { | ||
3502 | struct dwc2_hsotg *hsotg = seq->private; | ||
3503 | void __iomem *regs = hsotg->regs; | ||
3504 | int idx; | ||
3505 | |||
3506 | seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n", | ||
3507 | readl(regs + DCFG), | ||
3508 | readl(regs + DCTL), | ||
3509 | readl(regs + DSTS)); | ||
3510 | |||
3511 | seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n", | ||
3512 | readl(regs + DIEPMSK), readl(regs + DOEPMSK)); | ||
3513 | |||
3514 | seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n", | ||
3515 | readl(regs + GINTMSK), | ||
3516 | readl(regs + GINTSTS)); | ||
3517 | |||
3518 | seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n", | ||
3519 | readl(regs + DAINTMSK), | ||
3520 | readl(regs + DAINT)); | ||
3521 | |||
3522 | seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n", | ||
3523 | readl(regs + GNPTXSTS), | ||
3524 | readl(regs + GRXSTSR)); | ||
3525 | |||
3526 | seq_puts(seq, "\nEndpoint status:\n"); | ||
3527 | |||
3528 | for (idx = 0; idx < hsotg->num_of_eps; idx++) { | ||
3529 | u32 in, out; | ||
3530 | |||
3531 | in = readl(regs + DIEPCTL(idx)); | ||
3532 | out = readl(regs + DOEPCTL(idx)); | ||
3533 | |||
3534 | seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x", | ||
3535 | idx, in, out); | ||
3536 | |||
3537 | in = readl(regs + DIEPTSIZ(idx)); | ||
3538 | out = readl(regs + DOEPTSIZ(idx)); | ||
3539 | |||
3540 | seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", | ||
3541 | in, out); | ||
3542 | |||
3543 | seq_puts(seq, "\n"); | ||
3544 | } | ||
3545 | |||
3546 | return 0; | ||
3547 | } | ||
3548 | |||
3549 | static int state_open(struct inode *inode, struct file *file) | ||
3550 | { | ||
3551 | return single_open(file, state_show, inode->i_private); | ||
3552 | } | ||
3553 | |||
3554 | static const struct file_operations state_fops = { | ||
3555 | .owner = THIS_MODULE, | ||
3556 | .open = state_open, | ||
3557 | .read = seq_read, | ||
3558 | .llseek = seq_lseek, | ||
3559 | .release = single_release, | ||
3560 | }; | ||
3561 | |||
3562 | /** | ||
3563 | * fifo_show - debugfs: show the fifo information | ||
3564 | * @seq: The seq_file to write data to. | ||
3565 | * @v: Unused parameter. | ||
3566 | * | ||
3567 | * Show the FIFO information for the overall fifo and all the | ||
3568 | * periodic transmission FIFOs. | ||
3569 | */ | ||
3570 | static int fifo_show(struct seq_file *seq, void *v) | ||
3571 | { | ||
3572 | struct dwc2_hsotg *hsotg = seq->private; | ||
3573 | void __iomem *regs = hsotg->regs; | ||
3574 | u32 val; | ||
3575 | int idx; | ||
3576 | |||
3577 | seq_puts(seq, "Non-periodic FIFOs:\n"); | ||
3578 | seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ)); | ||
3579 | |||
3580 | val = readl(regs + GNPTXFSIZ); | ||
3581 | seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n", | ||
3582 | val >> FIFOSIZE_DEPTH_SHIFT, | ||
3583 | val & FIFOSIZE_DEPTH_MASK); | ||
3584 | |||
3585 | seq_puts(seq, "\nPeriodic TXFIFOs:\n"); | ||
3586 | |||
3587 | for (idx = 1; idx < hsotg->num_of_eps; idx++) { | ||
3588 | val = readl(regs + DPTXFSIZN(idx)); | ||
3589 | |||
3590 | seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, | ||
3591 | val >> FIFOSIZE_DEPTH_SHIFT, | ||
3592 | val & FIFOSIZE_STARTADDR_MASK); | ||
3593 | } | ||
3594 | |||
3595 | return 0; | ||
3596 | } | ||
3597 | |||
3598 | static int fifo_open(struct inode *inode, struct file *file) | ||
3599 | { | ||
3600 | return single_open(file, fifo_show, inode->i_private); | ||
3601 | } | ||
3602 | |||
3603 | static const struct file_operations fifo_fops = { | ||
3604 | .owner = THIS_MODULE, | ||
3605 | .open = fifo_open, | ||
3606 | .read = seq_read, | ||
3607 | .llseek = seq_lseek, | ||
3608 | .release = single_release, | ||
3609 | }; | ||
3610 | |||
3611 | |||
3612 | static const char *decode_direction(int is_in) | ||
3613 | { | ||
3614 | return is_in ? "in" : "out"; | ||
3615 | } | ||
3616 | |||
3617 | /** | ||
3618 | * ep_show - debugfs: show the state of an endpoint. | ||
3619 | * @seq: The seq_file to write data to. | ||
3620 | * @v: Unused parameter. | ||
3621 | * | ||
3622 | * This debugfs entry shows the state of the given endpoint (one is | ||
3623 | * registered for each available). | ||
3624 | */ | ||
3625 | static int ep_show(struct seq_file *seq, void *v) | ||
3626 | { | ||
3627 | struct s3c_hsotg_ep *ep = seq->private; | ||
3628 | struct dwc2_hsotg *hsotg = ep->parent; | ||
3629 | struct s3c_hsotg_req *req; | ||
3630 | void __iomem *regs = hsotg->regs; | ||
3631 | int index = ep->index; | ||
3632 | int show_limit = 15; | ||
3633 | unsigned long flags; | ||
3634 | |||
3635 | seq_printf(seq, "Endpoint index %d, named %s, dir %s:\n", | ||
3636 | ep->index, ep->ep.name, decode_direction(ep->dir_in)); | ||
3637 | |||
3638 | /* first show the register state */ | ||
3639 | |||
3640 | seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n", | ||
3641 | readl(regs + DIEPCTL(index)), | ||
3642 | readl(regs + DOEPCTL(index))); | ||
3643 | |||
3644 | seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n", | ||
3645 | readl(regs + DIEPDMA(index)), | ||
3646 | readl(regs + DOEPDMA(index))); | ||
3647 | |||
3648 | seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n", | ||
3649 | readl(regs + DIEPINT(index)), | ||
3650 | readl(regs + DOEPINT(index))); | ||
3651 | |||
3652 | seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n", | ||
3653 | readl(regs + DIEPTSIZ(index)), | ||
3654 | readl(regs + DOEPTSIZ(index))); | ||
3655 | |||
3656 | seq_puts(seq, "\n"); | ||
3657 | seq_printf(seq, "mps %d\n", ep->ep.maxpacket); | ||
3658 | seq_printf(seq, "total_data=%ld\n", ep->total_data); | ||
3659 | |||
3660 | seq_printf(seq, "request list (%p,%p):\n", | ||
3661 | ep->queue.next, ep->queue.prev); | ||
3662 | |||
3663 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3664 | |||
3665 | list_for_each_entry(req, &ep->queue, queue) { | ||
3666 | if (--show_limit < 0) { | ||
3667 | seq_puts(seq, "not showing more requests...\n"); | ||
3668 | break; | ||
3669 | } | ||
3670 | |||
3671 | seq_printf(seq, "%c req %p: %d bytes @%p, ", | ||
3672 | req == ep->req ? '*' : ' ', | ||
3673 | req, req->req.length, req->req.buf); | ||
3674 | seq_printf(seq, "%d done, res %d\n", | ||
3675 | req->req.actual, req->req.status); | ||
3676 | } | ||
3677 | |||
3678 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3679 | |||
3680 | return 0; | ||
3681 | } | ||
3682 | |||
3683 | static int ep_open(struct inode *inode, struct file *file) | ||
3684 | { | ||
3685 | return single_open(file, ep_show, inode->i_private); | ||
3686 | } | ||
3687 | |||
3688 | static const struct file_operations ep_fops = { | ||
3689 | .owner = THIS_MODULE, | ||
3690 | .open = ep_open, | ||
3691 | .read = seq_read, | ||
3692 | .llseek = seq_lseek, | ||
3693 | .release = single_release, | ||
3694 | }; | ||
3695 | |||
3696 | /** | ||
3697 | * s3c_hsotg_create_debug - create debugfs directory and files | ||
3698 | * @hsotg: The driver state | ||
3699 | * | ||
3700 | * Create the debugfs files to allow the user to get information | ||
3701 | * about the state of the system. The directory name is created | ||
3702 | * with the same name as the device itself, in case we end up | ||
3703 | * with multiple blocks in future systems. | ||
3704 | */ | ||
3705 | static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) | ||
3706 | { | ||
3707 | struct dentry *root; | ||
3708 | unsigned epidx; | ||
3709 | |||
3710 | root = debugfs_create_dir(dev_name(hsotg->dev), NULL); | ||
3711 | hsotg->debug_root = root; | ||
3712 | if (IS_ERR(root)) { | ||
3713 | dev_err(hsotg->dev, "cannot create debug root\n"); | ||
3714 | return; | ||
3715 | } | ||
3716 | |||
3717 | /* create general state file */ | ||
3718 | |||
3719 | hsotg->debug_file = debugfs_create_file("state", S_IRUGO, root, | ||
3720 | hsotg, &state_fops); | ||
3721 | |||
3722 | if (IS_ERR(hsotg->debug_file)) | ||
3723 | dev_err(hsotg->dev, "%s: failed to create state\n", __func__); | ||
3724 | |||
3725 | hsotg->debug_testmode = debugfs_create_file("testmode", | ||
3726 | S_IRUGO | S_IWUSR, root, | ||
3727 | hsotg, &testmode_fops); | ||
3728 | |||
3729 | if (IS_ERR(hsotg->debug_testmode)) | ||
3730 | dev_err(hsotg->dev, "%s: failed to create testmode\n", | ||
3731 | __func__); | ||
3732 | |||
3733 | hsotg->debug_fifo = debugfs_create_file("fifo", S_IRUGO, root, | ||
3734 | hsotg, &fifo_fops); | ||
3735 | |||
3736 | if (IS_ERR(hsotg->debug_fifo)) | ||
3737 | dev_err(hsotg->dev, "%s: failed to create fifo\n", __func__); | ||
3738 | |||
3739 | /* Create one file for each out endpoint */ | ||
3740 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { | ||
3741 | struct s3c_hsotg_ep *ep; | ||
3742 | |||
3743 | ep = hsotg->eps_out[epidx]; | ||
3744 | if (ep) { | ||
3745 | ep->debugfs = debugfs_create_file(ep->name, S_IRUGO, | ||
3746 | root, ep, &ep_fops); | ||
3747 | |||
3748 | if (IS_ERR(ep->debugfs)) | ||
3749 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
3750 | ep->name); | ||
3751 | } | ||
3752 | } | ||
3753 | /* Create one file for each in endpoint. EP0 is handled with out eps */ | ||
3754 | for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) { | ||
3755 | struct s3c_hsotg_ep *ep; | ||
3756 | |||
3757 | ep = hsotg->eps_in[epidx]; | ||
3758 | if (ep) { | ||
3759 | ep->debugfs = debugfs_create_file(ep->name, S_IRUGO, | ||
3760 | root, ep, &ep_fops); | ||
3761 | |||
3762 | if (IS_ERR(ep->debugfs)) | ||
3763 | dev_err(hsotg->dev, "failed to create %s debug file\n", | ||
3764 | ep->name); | ||
3765 | } | ||
3766 | } | ||
3767 | } | ||
3768 | |||
3769 | /** | ||
3770 | * s3c_hsotg_delete_debug - cleanup debugfs entries | ||
3771 | * @hsotg: The driver state | ||
3772 | * | ||
3773 | * Cleanup (remove) the debugfs files for use on module exit. | ||
3774 | */ | ||
3775 | static void s3c_hsotg_delete_debug(struct dwc2_hsotg *hsotg) | ||
3776 | { | ||
3777 | unsigned epidx; | ||
3778 | |||
3779 | for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { | ||
3780 | if (hsotg->eps_in[epidx]) | ||
3781 | debugfs_remove(hsotg->eps_in[epidx]->debugfs); | ||
3782 | if (hsotg->eps_out[epidx]) | ||
3783 | debugfs_remove(hsotg->eps_out[epidx]->debugfs); | ||
3784 | } | ||
3785 | |||
3786 | debugfs_remove(hsotg->debug_file); | ||
3787 | debugfs_remove(hsotg->debug_testmode); | ||
3788 | debugfs_remove(hsotg->debug_fifo); | ||
3789 | debugfs_remove(hsotg->debug_root); | ||
3790 | } | ||
3791 | |||
3792 | #ifdef CONFIG_OF | 3416 | #ifdef CONFIG_OF |
3793 | static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) | 3417 | static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) |
3794 | { | 3418 | { |
@@ -3896,6 +3520,8 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
3896 | hsotg->gadget.max_speed = USB_SPEED_HIGH; | 3520 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
3897 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; | 3521 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; |
3898 | hsotg->gadget.name = dev_name(dev); | 3522 | hsotg->gadget.name = dev_name(dev); |
3523 | if (hsotg->dr_mode == USB_DR_MODE_OTG) | ||
3524 | hsotg->gadget.is_otg = 1; | ||
3899 | 3525 | ||
3900 | /* reset the system */ | 3526 | /* reset the system */ |
3901 | 3527 | ||
@@ -4028,8 +3654,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) | |||
4028 | if (ret) | 3654 | if (ret) |
4029 | goto err_supplies; | 3655 | goto err_supplies; |
4030 | 3656 | ||
4031 | s3c_hsotg_create_debug(hsotg); | ||
4032 | |||
4033 | s3c_hsotg_dump(hsotg); | 3657 | s3c_hsotg_dump(hsotg); |
4034 | 3658 | ||
4035 | return 0; | 3659 | return 0; |
@@ -4041,7 +3665,6 @@ err_clk: | |||
4041 | 3665 | ||
4042 | return ret; | 3666 | return ret; |
4043 | } | 3667 | } |
4044 | EXPORT_SYMBOL_GPL(dwc2_gadget_init); | ||
4045 | 3668 | ||
4046 | /** | 3669 | /** |
4047 | * s3c_hsotg_remove - remove function for hsotg driver | 3670 | * s3c_hsotg_remove - remove function for hsotg driver |
@@ -4050,18 +3673,19 @@ EXPORT_SYMBOL_GPL(dwc2_gadget_init); | |||
4050 | int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) | 3673 | int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) |
4051 | { | 3674 | { |
4052 | usb_del_gadget_udc(&hsotg->gadget); | 3675 | usb_del_gadget_udc(&hsotg->gadget); |
4053 | s3c_hsotg_delete_debug(hsotg); | ||
4054 | clk_disable_unprepare(hsotg->clk); | 3676 | clk_disable_unprepare(hsotg->clk); |
4055 | 3677 | ||
4056 | return 0; | 3678 | return 0; |
4057 | } | 3679 | } |
4058 | EXPORT_SYMBOL_GPL(s3c_hsotg_remove); | ||
4059 | 3680 | ||
4060 | int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) | 3681 | int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) |
4061 | { | 3682 | { |
4062 | unsigned long flags; | 3683 | unsigned long flags; |
4063 | int ret = 0; | 3684 | int ret = 0; |
4064 | 3685 | ||
3686 | if (hsotg->lx_state != DWC2_L0) | ||
3687 | return ret; | ||
3688 | |||
4065 | mutex_lock(&hsotg->init_mutex); | 3689 | mutex_lock(&hsotg->init_mutex); |
4066 | 3690 | ||
4067 | if (hsotg->driver) { | 3691 | if (hsotg->driver) { |
@@ -4095,13 +3719,15 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) | |||
4095 | 3719 | ||
4096 | return ret; | 3720 | return ret; |
4097 | } | 3721 | } |
4098 | EXPORT_SYMBOL_GPL(s3c_hsotg_suspend); | ||
4099 | 3722 | ||
4100 | int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) | 3723 | int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) |
4101 | { | 3724 | { |
4102 | unsigned long flags; | 3725 | unsigned long flags; |
4103 | int ret = 0; | 3726 | int ret = 0; |
4104 | 3727 | ||
3728 | if (hsotg->lx_state == DWC2_L2) | ||
3729 | return ret; | ||
3730 | |||
4105 | mutex_lock(&hsotg->init_mutex); | 3731 | mutex_lock(&hsotg->init_mutex); |
4106 | 3732 | ||
4107 | if (hsotg->driver) { | 3733 | if (hsotg->driver) { |
@@ -4124,4 +3750,3 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) | |||
4124 | 3750 | ||
4125 | return ret; | 3751 | return ret; |
4126 | } | 3752 | } |
4127 | EXPORT_SYMBOL_GPL(s3c_hsotg_resume); | ||
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index fbbbac2150a5..b10377c65064 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -357,12 +357,12 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) | |||
357 | writel(0, hsotg->regs + HPRT0); | 357 | writel(0, hsotg->regs + HPRT0); |
358 | } | 358 | } |
359 | 359 | ||
360 | /* Caller must hold driver lock */ | ||
360 | static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, | 361 | static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, |
361 | struct dwc2_hcd_urb *urb, void **ep_handle, | 362 | struct dwc2_hcd_urb *urb, void **ep_handle, |
362 | gfp_t mem_flags) | 363 | gfp_t mem_flags) |
363 | { | 364 | { |
364 | struct dwc2_qtd *qtd; | 365 | struct dwc2_qtd *qtd; |
365 | unsigned long flags; | ||
366 | u32 intr_mask; | 366 | u32 intr_mask; |
367 | int retval; | 367 | int retval; |
368 | int dev_speed; | 368 | int dev_speed; |
@@ -413,11 +413,9 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, | |||
413 | */ | 413 | */ |
414 | return 0; | 414 | return 0; |
415 | 415 | ||
416 | spin_lock_irqsave(&hsotg->lock, flags); | ||
417 | tr_type = dwc2_hcd_select_transactions(hsotg); | 416 | tr_type = dwc2_hcd_select_transactions(hsotg); |
418 | if (tr_type != DWC2_TRANSACTION_NONE) | 417 | if (tr_type != DWC2_TRANSACTION_NONE) |
419 | dwc2_hcd_queue_transactions(hsotg, tr_type); | 418 | dwc2_hcd_queue_transactions(hsotg, tr_type); |
420 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
421 | } | 419 | } |
422 | 420 | ||
423 | return 0; | 421 | return 0; |
@@ -721,9 +719,7 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | |||
721 | /* 3072 = 3 max-size Isoc packets */ | 719 | /* 3072 = 3 max-size Isoc packets */ |
722 | buf_size = 3072; | 720 | buf_size = 3072; |
723 | 721 | ||
724 | qh->dw_align_buf = dma_alloc_coherent(hsotg->dev, buf_size, | 722 | qh->dw_align_buf = kmalloc(buf_size, GFP_ATOMIC | GFP_DMA); |
725 | &qh->dw_align_buf_dma, | ||
726 | GFP_ATOMIC); | ||
727 | if (!qh->dw_align_buf) | 723 | if (!qh->dw_align_buf) |
728 | return -ENOMEM; | 724 | return -ENOMEM; |
729 | qh->dw_align_buf_size = buf_size; | 725 | qh->dw_align_buf_size = buf_size; |
@@ -748,6 +744,15 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | |||
748 | } | 744 | } |
749 | } | 745 | } |
750 | 746 | ||
747 | qh->dw_align_buf_dma = dma_map_single(hsotg->dev, | ||
748 | qh->dw_align_buf, qh->dw_align_buf_size, | ||
749 | chan->ep_is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | ||
750 | if (dma_mapping_error(hsotg->dev, qh->dw_align_buf_dma)) { | ||
751 | dev_err(hsotg->dev, "can't map align_buf\n"); | ||
752 | chan->align_buf = 0; | ||
753 | return -EINVAL; | ||
754 | } | ||
755 | |||
751 | chan->align_buf = qh->dw_align_buf_dma; | 756 | chan->align_buf = qh->dw_align_buf_dma; |
752 | return 0; | 757 | return 0; |
753 | } | 758 | } |
@@ -1774,6 +1779,15 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, | |||
1774 | /* Not supported */ | 1779 | /* Not supported */ |
1775 | break; | 1780 | break; |
1776 | 1781 | ||
1782 | case USB_PORT_FEAT_TEST: | ||
1783 | hprt0 = dwc2_read_hprt0(hsotg); | ||
1784 | dev_dbg(hsotg->dev, | ||
1785 | "SetPortFeature - USB_PORT_FEAT_TEST\n"); | ||
1786 | hprt0 &= ~HPRT0_TSTCTL_MASK; | ||
1787 | hprt0 |= (windex >> 8) << HPRT0_TSTCTL_SHIFT; | ||
1788 | writel(hprt0, hsotg->regs + HPRT0); | ||
1789 | break; | ||
1790 | |||
1777 | default: | 1791 | default: |
1778 | retval = -EINVAL; | 1792 | retval = -EINVAL; |
1779 | dev_err(hsotg->dev, | 1793 | dev_err(hsotg->dev, |
@@ -2313,6 +2327,22 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) | |||
2313 | usleep_range(1000, 3000); | 2327 | usleep_range(1000, 3000); |
2314 | } | 2328 | } |
2315 | 2329 | ||
2330 | static int _dwc2_hcd_suspend(struct usb_hcd *hcd) | ||
2331 | { | ||
2332 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | ||
2333 | |||
2334 | hsotg->lx_state = DWC2_L2; | ||
2335 | return 0; | ||
2336 | } | ||
2337 | |||
2338 | static int _dwc2_hcd_resume(struct usb_hcd *hcd) | ||
2339 | { | ||
2340 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | ||
2341 | |||
2342 | hsotg->lx_state = DWC2_L0; | ||
2343 | return 0; | ||
2344 | } | ||
2345 | |||
2316 | /* Returns the current frame number */ | 2346 | /* Returns the current frame number */ |
2317 | static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) | 2347 | static int _dwc2_hcd_get_frame_number(struct usb_hcd *hcd) |
2318 | { | 2348 | { |
@@ -2468,7 +2498,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
2468 | "%s: unaligned transfer with no transfer_buffer", | 2498 | "%s: unaligned transfer with no transfer_buffer", |
2469 | __func__); | 2499 | __func__); |
2470 | retval = -EINVAL; | 2500 | retval = -EINVAL; |
2471 | goto fail1; | 2501 | goto fail0; |
2472 | } | 2502 | } |
2473 | } | 2503 | } |
2474 | 2504 | ||
@@ -2496,7 +2526,6 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
2496 | 2526 | ||
2497 | spin_lock_irqsave(&hsotg->lock, flags); | 2527 | spin_lock_irqsave(&hsotg->lock, flags); |
2498 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | 2528 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2499 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2500 | if (retval) | 2529 | if (retval) |
2501 | goto fail1; | 2530 | goto fail1; |
2502 | 2531 | ||
@@ -2505,22 +2534,22 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
2505 | goto fail2; | 2534 | goto fail2; |
2506 | 2535 | ||
2507 | if (alloc_bandwidth) { | 2536 | if (alloc_bandwidth) { |
2508 | spin_lock_irqsave(&hsotg->lock, flags); | ||
2509 | dwc2_allocate_bus_bandwidth(hcd, | 2537 | dwc2_allocate_bus_bandwidth(hcd, |
2510 | dwc2_hcd_get_ep_bandwidth(hsotg, ep), | 2538 | dwc2_hcd_get_ep_bandwidth(hsotg, ep), |
2511 | urb); | 2539 | urb); |
2512 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2513 | } | 2540 | } |
2514 | 2541 | ||
2542 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2543 | |||
2515 | return 0; | 2544 | return 0; |
2516 | 2545 | ||
2517 | fail2: | 2546 | fail2: |
2518 | spin_lock_irqsave(&hsotg->lock, flags); | ||
2519 | dwc2_urb->priv = NULL; | 2547 | dwc2_urb->priv = NULL; |
2520 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 2548 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
2521 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2522 | fail1: | 2549 | fail1: |
2550 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
2523 | urb->hcpriv = NULL; | 2551 | urb->hcpriv = NULL; |
2552 | fail0: | ||
2524 | kfree(dwc2_urb); | 2553 | kfree(dwc2_urb); |
2525 | 2554 | ||
2526 | return retval; | 2555 | return retval; |
@@ -2683,6 +2712,9 @@ static struct hc_driver dwc2_hc_driver = { | |||
2683 | .hub_status_data = _dwc2_hcd_hub_status_data, | 2712 | .hub_status_data = _dwc2_hcd_hub_status_data, |
2684 | .hub_control = _dwc2_hcd_hub_control, | 2713 | .hub_control = _dwc2_hcd_hub_control, |
2685 | .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, | 2714 | .clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete, |
2715 | |||
2716 | .bus_suspend = _dwc2_hcd_suspend, | ||
2717 | .bus_resume = _dwc2_hcd_resume, | ||
2686 | }; | 2718 | }; |
2687 | 2719 | ||
2688 | /* | 2720 | /* |
@@ -2748,8 +2780,6 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) | |||
2748 | destroy_workqueue(hsotg->wq_otg); | 2780 | destroy_workqueue(hsotg->wq_otg); |
2749 | } | 2781 | } |
2750 | 2782 | ||
2751 | kfree(hsotg->core_params); | ||
2752 | hsotg->core_params = NULL; | ||
2753 | del_timer(&hsotg->wkp_timer); | 2783 | del_timer(&hsotg->wkp_timer); |
2754 | } | 2784 | } |
2755 | 2785 | ||
@@ -2762,29 +2792,12 @@ static void dwc2_hcd_release(struct dwc2_hsotg *hsotg) | |||
2762 | } | 2792 | } |
2763 | 2793 | ||
2764 | /* | 2794 | /* |
2765 | * Sets all parameters to the given value. | ||
2766 | * | ||
2767 | * Assumes that the dwc2_core_params struct contains only integers. | ||
2768 | */ | ||
2769 | void dwc2_set_all_params(struct dwc2_core_params *params, int value) | ||
2770 | { | ||
2771 | int *p = (int *)params; | ||
2772 | size_t size = sizeof(*params) / sizeof(*p); | ||
2773 | int i; | ||
2774 | |||
2775 | for (i = 0; i < size; i++) | ||
2776 | p[i] = value; | ||
2777 | } | ||
2778 | EXPORT_SYMBOL_GPL(dwc2_set_all_params); | ||
2779 | |||
2780 | /* | ||
2781 | * Initializes the HCD. This function allocates memory for and initializes the | 2795 | * Initializes the HCD. This function allocates memory for and initializes the |
2782 | * static parts of the usb_hcd and dwc2_hsotg structures. It also registers the | 2796 | * static parts of the usb_hcd and dwc2_hsotg structures. It also registers the |
2783 | * USB bus with the core and calls the hc_driver->start() function. It returns | 2797 | * USB bus with the core and calls the hc_driver->start() function. It returns |
2784 | * a negative error on failure. | 2798 | * a negative error on failure. |
2785 | */ | 2799 | */ |
2786 | int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | 2800 | int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) |
2787 | const struct dwc2_core_params *params) | ||
2788 | { | 2801 | { |
2789 | struct usb_hcd *hcd; | 2802 | struct usb_hcd *hcd; |
2790 | struct dwc2_host_chan *channel; | 2803 | struct dwc2_host_chan *channel; |
@@ -2797,12 +2810,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | |||
2797 | 2810 | ||
2798 | dev_dbg(hsotg->dev, "DWC OTG HCD INIT\n"); | 2811 | dev_dbg(hsotg->dev, "DWC OTG HCD INIT\n"); |
2799 | 2812 | ||
2800 | /* Detect config values from hardware */ | ||
2801 | retval = dwc2_get_hwparams(hsotg); | ||
2802 | |||
2803 | if (retval) | ||
2804 | return retval; | ||
2805 | |||
2806 | retval = -ENOMEM; | 2813 | retval = -ENOMEM; |
2807 | 2814 | ||
2808 | hcfg = readl(hsotg->regs + HCFG); | 2815 | hcfg = readl(hsotg->regs + HCFG); |
@@ -2821,15 +2828,6 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | |||
2821 | hsotg->last_frame_num = HFNUM_MAX_FRNUM; | 2828 | hsotg->last_frame_num = HFNUM_MAX_FRNUM; |
2822 | #endif | 2829 | #endif |
2823 | 2830 | ||
2824 | hsotg->core_params = kzalloc(sizeof(*hsotg->core_params), GFP_KERNEL); | ||
2825 | if (!hsotg->core_params) | ||
2826 | goto error1; | ||
2827 | |||
2828 | dwc2_set_all_params(hsotg->core_params, -1); | ||
2829 | |||
2830 | /* Validate parameter values */ | ||
2831 | dwc2_set_parameters(hsotg, params); | ||
2832 | |||
2833 | /* Check if the bus driver or platform code has setup a dma_mask */ | 2831 | /* Check if the bus driver or platform code has setup a dma_mask */ |
2834 | if (hsotg->core_params->dma_enable > 0 && | 2832 | if (hsotg->core_params->dma_enable > 0 && |
2835 | hsotg->dev->dma_mask == NULL) { | 2833 | hsotg->dev->dma_mask == NULL) { |
@@ -2947,6 +2945,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | |||
2947 | /* Don't support SG list at this point */ | 2945 | /* Don't support SG list at this point */ |
2948 | hcd->self.sg_tablesize = 0; | 2946 | hcd->self.sg_tablesize = 0; |
2949 | 2947 | ||
2948 | if (!IS_ERR_OR_NULL(hsotg->uphy)) | ||
2949 | otg_set_host(hsotg->uphy->otg, &hcd->self); | ||
2950 | |||
2950 | /* | 2951 | /* |
2951 | * Finish generic HCD initialization and start the HCD. This function | 2952 | * Finish generic HCD initialization and start the HCD. This function |
2952 | * allocates the DMA buffer pool, registers the USB bus, requests the | 2953 | * allocates the DMA buffer pool, registers the USB bus, requests the |
@@ -2979,7 +2980,6 @@ error1: | |||
2979 | dev_err(hsotg->dev, "%s() FAILED, returning %d\n", __func__, retval); | 2980 | dev_err(hsotg->dev, "%s() FAILED, returning %d\n", __func__, retval); |
2980 | return retval; | 2981 | return retval; |
2981 | } | 2982 | } |
2982 | EXPORT_SYMBOL_GPL(dwc2_hcd_init); | ||
2983 | 2983 | ||
2984 | /* | 2984 | /* |
2985 | * Removes the HCD. | 2985 | * Removes the HCD. |
@@ -3000,6 +3000,9 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) | |||
3000 | return; | 3000 | return; |
3001 | } | 3001 | } |
3002 | 3002 | ||
3003 | if (!IS_ERR_OR_NULL(hsotg->uphy)) | ||
3004 | otg_set_host(hsotg->uphy->otg, NULL); | ||
3005 | |||
3003 | usb_remove_hcd(hcd); | 3006 | usb_remove_hcd(hcd); |
3004 | hsotg->priv = NULL; | 3007 | hsotg->priv = NULL; |
3005 | dwc2_hcd_release(hsotg); | 3008 | dwc2_hcd_release(hsotg); |
@@ -3010,4 +3013,3 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) | |||
3010 | kfree(hsotg->frame_num_array); | 3013 | kfree(hsotg->frame_num_array); |
3011 | #endif | 3014 | #endif |
3012 | } | 3015 | } |
3013 | EXPORT_SYMBOL_GPL(dwc2_hcd_remove); | ||
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index e69a843d8928..7b5841c40033 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h | |||
@@ -451,13 +451,8 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe) | |||
451 | return !dwc2_hcd_is_pipe_in(pipe); | 451 | return !dwc2_hcd_is_pipe_in(pipe); |
452 | } | 452 | } |
453 | 453 | ||
454 | extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, | 454 | extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq); |
455 | const struct dwc2_core_params *params); | ||
456 | extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); | 455 | extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); |
457 | extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg, | ||
458 | const struct dwc2_core_params *params); | ||
459 | extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); | ||
460 | extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); | ||
461 | 456 | ||
462 | /* Transaction Execution Functions */ | 457 | /* Transaction Execution Functions */ |
463 | extern enum dwc2_transaction_type dwc2_hcd_select_transactions( | 458 | extern enum dwc2_transaction_type dwc2_hcd_select_transactions( |
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 551ba878b003..4cc95df4262d 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c | |||
@@ -350,6 +350,9 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) | |||
350 | dev_vdbg(hsotg->dev, | 350 | dev_vdbg(hsotg->dev, |
351 | "--Port Interrupt HPRT0=0x%08x Port Connect Detected--\n", | 351 | "--Port Interrupt HPRT0=0x%08x Port Connect Detected--\n", |
352 | hprt0); | 352 | hprt0); |
353 | if (hsotg->lx_state != DWC2_L0) | ||
354 | usb_hcd_resume_root_hub(hsotg->priv); | ||
355 | |||
353 | hsotg->flags.b.port_connect_status_change = 1; | 356 | hsotg->flags.b.port_connect_status_change = 1; |
354 | hsotg->flags.b.port_connect_status = 1; | 357 | hsotg->flags.b.port_connect_status = 1; |
355 | hprt0_modify |= HPRT0_CONNDET; | 358 | hprt0_modify |= HPRT0_CONNDET; |
@@ -463,10 +466,15 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg, | |||
463 | } | 466 | } |
464 | 467 | ||
465 | /* Non DWORD-aligned buffer case handling */ | 468 | /* Non DWORD-aligned buffer case handling */ |
466 | if (chan->align_buf && xfer_length && chan->ep_is_in) { | 469 | if (chan->align_buf && xfer_length) { |
467 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); | 470 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); |
468 | memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, | 471 | dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, |
469 | xfer_length); | 472 | chan->qh->dw_align_buf_size, |
473 | chan->ep_is_in ? | ||
474 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | ||
475 | if (chan->ep_is_in) | ||
476 | memcpy(urb->buf + urb->actual_length, | ||
477 | chan->qh->dw_align_buf, xfer_length); | ||
470 | } | 478 | } |
471 | 479 | ||
472 | dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n", | 480 | dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n", |
@@ -552,13 +560,18 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state( | |||
552 | chan, chnum, qtd, halt_status, NULL); | 560 | chan, chnum, qtd, halt_status, NULL); |
553 | 561 | ||
554 | /* Non DWORD-aligned buffer case handling */ | 562 | /* Non DWORD-aligned buffer case handling */ |
555 | if (chan->align_buf && frame_desc->actual_length && | 563 | if (chan->align_buf && frame_desc->actual_length) { |
556 | chan->ep_is_in) { | ||
557 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", | 564 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", |
558 | __func__); | 565 | __func__); |
559 | memcpy(urb->buf + frame_desc->offset + | 566 | dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, |
560 | qtd->isoc_split_offset, chan->qh->dw_align_buf, | 567 | chan->qh->dw_align_buf_size, |
561 | frame_desc->actual_length); | 568 | chan->ep_is_in ? |
569 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | ||
570 | if (chan->ep_is_in) | ||
571 | memcpy(urb->buf + frame_desc->offset + | ||
572 | qtd->isoc_split_offset, | ||
573 | chan->qh->dw_align_buf, | ||
574 | frame_desc->actual_length); | ||
562 | } | 575 | } |
563 | break; | 576 | break; |
564 | case DWC2_HC_XFER_FRAME_OVERRUN: | 577 | case DWC2_HC_XFER_FRAME_OVERRUN: |
@@ -581,13 +594,18 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state( | |||
581 | chan, chnum, qtd, halt_status, NULL); | 594 | chan, chnum, qtd, halt_status, NULL); |
582 | 595 | ||
583 | /* Non DWORD-aligned buffer case handling */ | 596 | /* Non DWORD-aligned buffer case handling */ |
584 | if (chan->align_buf && frame_desc->actual_length && | 597 | if (chan->align_buf && frame_desc->actual_length) { |
585 | chan->ep_is_in) { | ||
586 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", | 598 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", |
587 | __func__); | 599 | __func__); |
588 | memcpy(urb->buf + frame_desc->offset + | 600 | dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, |
589 | qtd->isoc_split_offset, chan->qh->dw_align_buf, | 601 | chan->qh->dw_align_buf_size, |
590 | frame_desc->actual_length); | 602 | chan->ep_is_in ? |
603 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | ||
604 | if (chan->ep_is_in) | ||
605 | memcpy(urb->buf + frame_desc->offset + | ||
606 | qtd->isoc_split_offset, | ||
607 | chan->qh->dw_align_buf, | ||
608 | frame_desc->actual_length); | ||
591 | } | 609 | } |
592 | 610 | ||
593 | /* Skip whole frame */ | 611 | /* Skip whole frame */ |
@@ -923,6 +941,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg, | |||
923 | 941 | ||
924 | if (chan->align_buf) { | 942 | if (chan->align_buf) { |
925 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); | 943 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); |
944 | dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, | ||
945 | chan->qh->dw_align_buf_size, DMA_FROM_DEVICE); | ||
926 | memcpy(qtd->urb->buf + frame_desc->offset + | 946 | memcpy(qtd->urb->buf + frame_desc->offset + |
927 | qtd->isoc_split_offset, chan->qh->dw_align_buf, len); | 947 | qtd->isoc_split_offset, chan->qh->dw_align_buf, len); |
928 | } | 948 | } |
@@ -1152,8 +1172,14 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg, | |||
1152 | /* Non DWORD-aligned buffer case handling */ | 1172 | /* Non DWORD-aligned buffer case handling */ |
1153 | if (chan->align_buf && xfer_length && chan->ep_is_in) { | 1173 | if (chan->align_buf && xfer_length && chan->ep_is_in) { |
1154 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); | 1174 | dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); |
1155 | memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, | 1175 | dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, |
1156 | xfer_length); | 1176 | chan->qh->dw_align_buf_size, |
1177 | chan->ep_is_in ? | ||
1178 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | ||
1179 | if (chan->ep_is_in) | ||
1180 | memcpy(urb->buf + urb->actual_length, | ||
1181 | chan->qh->dw_align_buf, | ||
1182 | xfer_length); | ||
1157 | } | 1183 | } |
1158 | 1184 | ||
1159 | urb->actual_length += xfer_length; | 1185 | urb->actual_length += xfer_length; |
@@ -1182,6 +1208,16 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg, | |||
1182 | struct dwc2_host_chan *chan, int chnum, | 1208 | struct dwc2_host_chan *chan, int chnum, |
1183 | struct dwc2_qtd *qtd) | 1209 | struct dwc2_qtd *qtd) |
1184 | { | 1210 | { |
1211 | if (!qtd) { | ||
1212 | dev_dbg(hsotg->dev, "%s: qtd is NULL\n", __func__); | ||
1213 | return; | ||
1214 | } | ||
1215 | |||
1216 | if (!qtd->urb) { | ||
1217 | dev_dbg(hsotg->dev, "%s: qtd->urb is NULL\n", __func__); | ||
1218 | return; | ||
1219 | } | ||
1220 | |||
1185 | if (dbg_hc(chan)) | 1221 | if (dbg_hc(chan)) |
1186 | dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: NAK Received--\n", | 1222 | dev_vdbg(hsotg->dev, "--Host Channel %d Interrupt: NAK Received--\n", |
1187 | chnum); | 1223 | chnum); |
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index bb97838bc6c0..9b5c36256627 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c | |||
@@ -229,11 +229,13 @@ static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, | |||
229 | */ | 229 | */ |
230 | void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) | 230 | void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) |
231 | { | 231 | { |
232 | if (hsotg->core_params->dma_desc_enable > 0) | 232 | if (hsotg->core_params->dma_desc_enable > 0) { |
233 | dwc2_hcd_qh_free_ddma(hsotg, qh); | 233 | dwc2_hcd_qh_free_ddma(hsotg, qh); |
234 | else if (qh->dw_align_buf) | 234 | } else { |
235 | dma_free_coherent(hsotg->dev, qh->dw_align_buf_size, | 235 | /* kfree(NULL) is safe */ |
236 | qh->dw_align_buf, qh->dw_align_buf_dma); | 236 | kfree(qh->dw_align_buf); |
237 | qh->dw_align_buf_dma = (dma_addr_t)0; | ||
238 | } | ||
237 | kfree(qh); | 239 | kfree(qh); |
238 | } | 240 | } |
239 | 241 | ||
@@ -761,6 +763,7 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) | |||
761 | 763 | ||
762 | /** | 764 | /** |
763 | * dwc2_hcd_qtd_add() - Adds a QTD to the QTD-list of a QH | 765 | * dwc2_hcd_qtd_add() - Adds a QTD to the QTD-list of a QH |
766 | * Caller must hold driver lock. | ||
764 | * | 767 | * |
765 | * @hsotg: The DWC HCD structure | 768 | * @hsotg: The DWC HCD structure |
766 | * @qtd: The QTD to add | 769 | * @qtd: The QTD to add |
@@ -777,7 +780,6 @@ int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, | |||
777 | struct dwc2_qh **qh, gfp_t mem_flags) | 780 | struct dwc2_qh **qh, gfp_t mem_flags) |
778 | { | 781 | { |
779 | struct dwc2_hcd_urb *urb = qtd->urb; | 782 | struct dwc2_hcd_urb *urb = qtd->urb; |
780 | unsigned long flags; | ||
781 | int allocated = 0; | 783 | int allocated = 0; |
782 | int retval; | 784 | int retval; |
783 | 785 | ||
@@ -792,15 +794,12 @@ int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, | |||
792 | allocated = 1; | 794 | allocated = 1; |
793 | } | 795 | } |
794 | 796 | ||
795 | spin_lock_irqsave(&hsotg->lock, flags); | ||
796 | |||
797 | retval = dwc2_hcd_qh_add(hsotg, *qh); | 797 | retval = dwc2_hcd_qh_add(hsotg, *qh); |
798 | if (retval) | 798 | if (retval) |
799 | goto fail; | 799 | goto fail; |
800 | 800 | ||
801 | qtd->qh = *qh; | 801 | qtd->qh = *qh; |
802 | list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); | 802 | list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); |
803 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
804 | 803 | ||
805 | return 0; | 804 | return 0; |
806 | 805 | ||
@@ -817,10 +816,7 @@ fail: | |||
817 | qtd_list_entry) | 816 | qtd_list_entry) |
818 | dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); | 817 | dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); |
819 | 818 | ||
820 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
821 | dwc2_hcd_qh_free(hsotg, qh_tmp); | 819 | dwc2_hcd_qh_free(hsotg, qh_tmp); |
822 | } else { | ||
823 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
824 | } | 820 | } |
825 | 821 | ||
826 | return retval; | 822 | return retval; |
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 185663e0b5f4..90935304185a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #include "core.h" | 48 | #include "core.h" |
49 | #include "hcd.h" | 49 | #include "hcd.h" |
50 | #include "debug.h" | ||
50 | 51 | ||
51 | static const char dwc2_driver_name[] = "dwc2"; | 52 | static const char dwc2_driver_name[] = "dwc2"; |
52 | 53 | ||
@@ -76,6 +77,8 @@ static const struct dwc2_core_params params_bcm2835 = { | |||
76 | .reload_ctl = 0, | 77 | .reload_ctl = 0, |
77 | .ahbcfg = 0x10, | 78 | .ahbcfg = 0x10, |
78 | .uframe_sched = 0, | 79 | .uframe_sched = 0, |
80 | .external_id_pin_ctl = -1, | ||
81 | .hibernation = -1, | ||
79 | }; | 82 | }; |
80 | 83 | ||
81 | static const struct dwc2_core_params params_rk3066 = { | 84 | static const struct dwc2_core_params params_rk3066 = { |
@@ -104,6 +107,8 @@ static const struct dwc2_core_params params_rk3066 = { | |||
104 | .reload_ctl = -1, | 107 | .reload_ctl = -1, |
105 | .ahbcfg = 0x7, /* INCR16 */ | 108 | .ahbcfg = 0x7, /* INCR16 */ |
106 | .uframe_sched = -1, | 109 | .uframe_sched = -1, |
110 | .external_id_pin_ctl = -1, | ||
111 | .hibernation = -1, | ||
107 | }; | 112 | }; |
108 | 113 | ||
109 | /** | 114 | /** |
@@ -121,6 +126,7 @@ static int dwc2_driver_remove(struct platform_device *dev) | |||
121 | { | 126 | { |
122 | struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); | 127 | struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); |
123 | 128 | ||
129 | dwc2_debugfs_exit(hsotg); | ||
124 | if (hsotg->hcd_enabled) | 130 | if (hsotg->hcd_enabled) |
125 | dwc2_hcd_remove(hsotg); | 131 | dwc2_hcd_remove(hsotg); |
126 | if (hsotg->gadget_enabled) | 132 | if (hsotg->gadget_enabled) |
@@ -237,6 +243,21 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
237 | spin_lock_init(&hsotg->lock); | 243 | spin_lock_init(&hsotg->lock); |
238 | mutex_init(&hsotg->init_mutex); | 244 | mutex_init(&hsotg->init_mutex); |
239 | 245 | ||
246 | /* Detect config values from hardware */ | ||
247 | retval = dwc2_get_hwparams(hsotg); | ||
248 | if (retval) | ||
249 | return retval; | ||
250 | |||
251 | hsotg->core_params = devm_kzalloc(&dev->dev, | ||
252 | sizeof(*hsotg->core_params), GFP_KERNEL); | ||
253 | if (!hsotg->core_params) | ||
254 | return -ENOMEM; | ||
255 | |||
256 | dwc2_set_all_params(hsotg->core_params, -1); | ||
257 | |||
258 | /* Validate parameter values */ | ||
259 | dwc2_set_parameters(hsotg, params); | ||
260 | |||
240 | if (hsotg->dr_mode != USB_DR_MODE_HOST) { | 261 | if (hsotg->dr_mode != USB_DR_MODE_HOST) { |
241 | retval = dwc2_gadget_init(hsotg, irq); | 262 | retval = dwc2_gadget_init(hsotg, irq); |
242 | if (retval) | 263 | if (retval) |
@@ -245,7 +266,7 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
245 | } | 266 | } |
246 | 267 | ||
247 | if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { | 268 | if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { |
248 | retval = dwc2_hcd_init(hsotg, irq, params); | 269 | retval = dwc2_hcd_init(hsotg, irq); |
249 | if (retval) { | 270 | if (retval) { |
250 | if (hsotg->gadget_enabled) | 271 | if (hsotg->gadget_enabled) |
251 | s3c_hsotg_remove(hsotg); | 272 | s3c_hsotg_remove(hsotg); |
@@ -256,6 +277,8 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
256 | 277 | ||
257 | platform_set_drvdata(dev, hsotg); | 278 | platform_set_drvdata(dev, hsotg); |
258 | 279 | ||
280 | dwc2_debugfs_init(hsotg); | ||
281 | |||
259 | return retval; | 282 | return retval; |
260 | } | 283 | } |
261 | 284 | ||
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 827c4f80379f..dede32e809b6 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig | |||
@@ -11,6 +11,13 @@ config USB_DWC3 | |||
11 | 11 | ||
12 | if USB_DWC3 | 12 | if USB_DWC3 |
13 | 13 | ||
14 | config USB_DWC3_ULPI | ||
15 | bool "Register ULPI PHY Interface" | ||
16 | depends on USB_ULPI_BUS=y || USB_ULPI_BUS=USB_DWC3 | ||
17 | help | ||
18 | Select this if you have ULPI type PHY attached to your DWC3 | ||
19 | controller. | ||
20 | |||
14 | choice | 21 | choice |
15 | bool "DWC3 Mode Selection" | 22 | bool "DWC3 Mode Selection" |
16 | default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) | 23 | default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) |
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 46172f47f02d..c7076e37c4ed 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile | |||
@@ -15,6 +15,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),) | |||
15 | dwc3-y += gadget.o ep0.o | 15 | dwc3-y += gadget.o ep0.o |
16 | endif | 16 | endif |
17 | 17 | ||
18 | ifneq ($(CONFIG_USB_DWC3_ULPI),) | ||
19 | dwc3-y += ulpi.o | ||
20 | endif | ||
21 | |||
18 | ifneq ($(CONFIG_DEBUG_FS),) | 22 | ifneq ($(CONFIG_DEBUG_FS),) |
19 | dwc3-y += debugfs.o | 23 | dwc3-y += debugfs.o |
20 | endif | 24 | endif |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 2bbab3d86fff..5c110d8e293b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -117,6 +117,33 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /** | 119 | /** |
120 | * dwc3_soft_reset - Issue soft reset | ||
121 | * @dwc: Pointer to our controller context structure | ||
122 | */ | ||
123 | static int dwc3_soft_reset(struct dwc3 *dwc) | ||
124 | { | ||
125 | unsigned long timeout; | ||
126 | u32 reg; | ||
127 | |||
128 | timeout = jiffies + msecs_to_jiffies(500); | ||
129 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | ||
130 | do { | ||
131 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
132 | if (!(reg & DWC3_DCTL_CSFTRST)) | ||
133 | break; | ||
134 | |||
135 | if (time_after(jiffies, timeout)) { | ||
136 | dev_err(dwc->dev, "Reset Timed Out\n"); | ||
137 | return -ETIMEDOUT; | ||
138 | } | ||
139 | |||
140 | cpu_relax(); | ||
141 | } while (true); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /** | ||
120 | * dwc3_free_one_event_buffer - Frees one event buffer | 147 | * dwc3_free_one_event_buffer - Frees one event buffer |
121 | * @dwc: Pointer to our controller context structure | 148 | * @dwc: Pointer to our controller context structure |
122 | * @evt: Pointer to event buffer to be freed | 149 | * @evt: Pointer to event buffer to be freed |
@@ -367,10 +394,15 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) | |||
367 | /** | 394 | /** |
368 | * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core | 395 | * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core |
369 | * @dwc: Pointer to our controller context structure | 396 | * @dwc: Pointer to our controller context structure |
397 | * | ||
398 | * Returns 0 on success. The USB PHY interfaces are configured but not | ||
399 | * initialized. The PHY interfaces and the PHYs get initialized together with | ||
400 | * the core in dwc3_core_init. | ||
370 | */ | 401 | */ |
371 | static void dwc3_phy_setup(struct dwc3 *dwc) | 402 | static int dwc3_phy_setup(struct dwc3 *dwc) |
372 | { | 403 | { |
373 | u32 reg; | 404 | u32 reg; |
405 | int ret; | ||
374 | 406 | ||
375 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | 407 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
376 | 408 | ||
@@ -409,10 +441,41 @@ static void dwc3_phy_setup(struct dwc3 *dwc) | |||
409 | 441 | ||
410 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | 442 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); |
411 | 443 | ||
412 | mdelay(100); | ||
413 | |||
414 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 444 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
415 | 445 | ||
446 | /* Select the HS PHY interface */ | ||
447 | switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { | ||
448 | case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI: | ||
449 | if (!strncmp(dwc->hsphy_interface, "utmi", 4)) { | ||
450 | reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI; | ||
451 | break; | ||
452 | } else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) { | ||
453 | reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; | ||
454 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
455 | } else { | ||
456 | dev_warn(dwc->dev, "HSPHY Interface not defined\n"); | ||
457 | |||
458 | /* Relying on default value. */ | ||
459 | if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) | ||
460 | break; | ||
461 | } | ||
462 | /* FALLTHROUGH */ | ||
463 | case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: | ||
464 | /* Making sure the interface and PHY are operational */ | ||
465 | ret = dwc3_soft_reset(dwc); | ||
466 | if (ret) | ||
467 | return ret; | ||
468 | |||
469 | udelay(1); | ||
470 | |||
471 | ret = dwc3_ulpi_init(dwc); | ||
472 | if (ret) | ||
473 | return ret; | ||
474 | /* FALLTHROUGH */ | ||
475 | default: | ||
476 | break; | ||
477 | } | ||
478 | |||
416 | /* | 479 | /* |
417 | * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to | 480 | * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to |
418 | * '0' during coreConsultant configuration. So default value will | 481 | * '0' during coreConsultant configuration. So default value will |
@@ -427,7 +490,7 @@ static void dwc3_phy_setup(struct dwc3 *dwc) | |||
427 | 490 | ||
428 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | 491 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
429 | 492 | ||
430 | mdelay(100); | 493 | return 0; |
431 | } | 494 | } |
432 | 495 | ||
433 | /** | 496 | /** |
@@ -438,7 +501,6 @@ static void dwc3_phy_setup(struct dwc3 *dwc) | |||
438 | */ | 501 | */ |
439 | static int dwc3_core_init(struct dwc3 *dwc) | 502 | static int dwc3_core_init(struct dwc3 *dwc) |
440 | { | 503 | { |
441 | unsigned long timeout; | ||
442 | u32 hwparams4 = dwc->hwparams.hwparams4; | 504 | u32 hwparams4 = dwc->hwparams.hwparams4; |
443 | u32 reg; | 505 | u32 reg; |
444 | int ret; | 506 | int ret; |
@@ -466,21 +528,9 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
466 | } | 528 | } |
467 | 529 | ||
468 | /* issue device SoftReset too */ | 530 | /* issue device SoftReset too */ |
469 | timeout = jiffies + msecs_to_jiffies(500); | 531 | ret = dwc3_soft_reset(dwc); |
470 | dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); | 532 | if (ret) |
471 | do { | 533 | goto err0; |
472 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
473 | if (!(reg & DWC3_DCTL_CSFTRST)) | ||
474 | break; | ||
475 | |||
476 | if (time_after(jiffies, timeout)) { | ||
477 | dev_err(dwc->dev, "Reset Timed Out\n"); | ||
478 | ret = -ETIMEDOUT; | ||
479 | goto err0; | ||
480 | } | ||
481 | |||
482 | cpu_relax(); | ||
483 | } while (true); | ||
484 | 534 | ||
485 | ret = dwc3_core_soft_reset(dwc); | 535 | ret = dwc3_core_soft_reset(dwc); |
486 | if (ret) | 536 | if (ret) |
@@ -555,8 +605,6 @@ static int dwc3_core_init(struct dwc3 *dwc) | |||
555 | 605 | ||
556 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 606 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
557 | 607 | ||
558 | dwc3_phy_setup(dwc); | ||
559 | |||
560 | ret = dwc3_alloc_scratch_buffers(dwc); | 608 | ret = dwc3_alloc_scratch_buffers(dwc); |
561 | if (ret) | 609 | if (ret) |
562 | goto err1; | 610 | goto err1; |
@@ -836,6 +884,8 @@ static int dwc3_probe(struct platform_device *pdev) | |||
836 | "snps,tx_de_emphasis_quirk"); | 884 | "snps,tx_de_emphasis_quirk"); |
837 | of_property_read_u8(node, "snps,tx_de_emphasis", | 885 | of_property_read_u8(node, "snps,tx_de_emphasis", |
838 | &tx_de_emphasis); | 886 | &tx_de_emphasis); |
887 | of_property_read_string(node, "snps,hsphy_interface", | ||
888 | &dwc->hsphy_interface); | ||
839 | } else if (pdata) { | 889 | } else if (pdata) { |
840 | dwc->maximum_speed = pdata->maximum_speed; | 890 | dwc->maximum_speed = pdata->maximum_speed; |
841 | dwc->has_lpm_erratum = pdata->has_lpm_erratum; | 891 | dwc->has_lpm_erratum = pdata->has_lpm_erratum; |
@@ -863,6 +913,8 @@ static int dwc3_probe(struct platform_device *pdev) | |||
863 | dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; | 913 | dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; |
864 | if (pdata->tx_de_emphasis) | 914 | if (pdata->tx_de_emphasis) |
865 | tx_de_emphasis = pdata->tx_de_emphasis; | 915 | tx_de_emphasis = pdata->tx_de_emphasis; |
916 | |||
917 | dwc->hsphy_interface = pdata->hsphy_interface; | ||
866 | } | 918 | } |
867 | 919 | ||
868 | /* default to superspeed if no maximum_speed passed */ | 920 | /* default to superspeed if no maximum_speed passed */ |
@@ -875,12 +927,18 @@ static int dwc3_probe(struct platform_device *pdev) | |||
875 | dwc->hird_threshold = hird_threshold | 927 | dwc->hird_threshold = hird_threshold |
876 | | (dwc->is_utmi_l1_suspend << 4); | 928 | | (dwc->is_utmi_l1_suspend << 4); |
877 | 929 | ||
930 | platform_set_drvdata(pdev, dwc); | ||
931 | dwc3_cache_hwparams(dwc); | ||
932 | |||
933 | ret = dwc3_phy_setup(dwc); | ||
934 | if (ret) | ||
935 | goto err0; | ||
936 | |||
878 | ret = dwc3_core_get_phy(dwc); | 937 | ret = dwc3_core_get_phy(dwc); |
879 | if (ret) | 938 | if (ret) |
880 | goto err0; | 939 | goto err0; |
881 | 940 | ||
882 | spin_lock_init(&dwc->lock); | 941 | spin_lock_init(&dwc->lock); |
883 | platform_set_drvdata(pdev, dwc); | ||
884 | 942 | ||
885 | if (!dev->dma_mask) { | 943 | if (!dev->dma_mask) { |
886 | dev->dma_mask = dev->parent->dma_mask; | 944 | dev->dma_mask = dev->parent->dma_mask; |
@@ -892,8 +950,6 @@ static int dwc3_probe(struct platform_device *pdev) | |||
892 | pm_runtime_get_sync(dev); | 950 | pm_runtime_get_sync(dev); |
893 | pm_runtime_forbid(dev); | 951 | pm_runtime_forbid(dev); |
894 | 952 | ||
895 | dwc3_cache_hwparams(dwc); | ||
896 | |||
897 | ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); | 953 | ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); |
898 | if (ret) { | 954 | if (ret) { |
899 | dev_err(dwc->dev, "failed to allocate event buffers\n"); | 955 | dev_err(dwc->dev, "failed to allocate event buffers\n"); |
@@ -964,6 +1020,7 @@ err2: | |||
964 | 1020 | ||
965 | err1: | 1021 | err1: |
966 | dwc3_free_event_buffers(dwc); | 1022 | dwc3_free_event_buffers(dwc); |
1023 | dwc3_ulpi_exit(dwc); | ||
967 | 1024 | ||
968 | err0: | 1025 | err0: |
969 | /* | 1026 | /* |
@@ -999,6 +1056,7 @@ static int dwc3_remove(struct platform_device *pdev) | |||
999 | phy_power_off(dwc->usb3_generic_phy); | 1056 | phy_power_off(dwc->usb3_generic_phy); |
1000 | 1057 | ||
1001 | dwc3_core_exit(dwc); | 1058 | dwc3_core_exit(dwc); |
1059 | dwc3_ulpi_exit(dwc); | ||
1002 | 1060 | ||
1003 | pm_runtime_put_sync(&pdev->dev); | 1061 | pm_runtime_put_sync(&pdev->dev); |
1004 | pm_runtime_disable(&pdev->dev); | 1062 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index c0eafa6fd403..044778884585 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/usb/ch9.h> | 30 | #include <linux/usb/ch9.h> |
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 | #include <linux/ulpi/interface.h> | ||
33 | 34 | ||
34 | #include <linux/phy/phy.h> | 35 | #include <linux/phy/phy.h> |
35 | 36 | ||
@@ -173,6 +174,15 @@ | |||
173 | /* Global USB2 PHY Configuration Register */ | 174 | /* Global USB2 PHY Configuration Register */ |
174 | #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) | 175 | #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) |
175 | #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) | 176 | #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) |
177 | #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4) | ||
178 | |||
179 | /* Global USB2 PHY Vendor Control Register */ | ||
180 | #define DWC3_GUSB2PHYACC_NEWREGREQ (1 << 25) | ||
181 | #define DWC3_GUSB2PHYACC_BUSY (1 << 23) | ||
182 | #define DWC3_GUSB2PHYACC_WRITE (1 << 22) | ||
183 | #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) | ||
184 | #define DWC3_GUSB2PHYACC_EXTEND_ADDR(n) (n << 8) | ||
185 | #define DWC3_GUSB2PHYACC_DATA(n) (n & 0xff) | ||
176 | 186 | ||
177 | /* Global USB3 PIPE Control Register */ | 187 | /* Global USB3 PIPE Control Register */ |
178 | #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) | 188 | #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) |
@@ -652,6 +662,7 @@ struct dwc3_scratchpad_array { | |||
652 | * @usb3_phy: pointer to USB3 PHY | 662 | * @usb3_phy: pointer to USB3 PHY |
653 | * @usb2_generic_phy: pointer to USB2 PHY | 663 | * @usb2_generic_phy: pointer to USB2 PHY |
654 | * @usb3_generic_phy: pointer to USB3 PHY | 664 | * @usb3_generic_phy: pointer to USB3 PHY |
665 | * @ulpi: pointer to ulpi interface | ||
655 | * @dcfg: saved contents of DCFG register | 666 | * @dcfg: saved contents of DCFG register |
656 | * @gctl: saved contents of GCTL register | 667 | * @gctl: saved contents of GCTL register |
657 | * @isoch_delay: wValue from Set Isochronous Delay request; | 668 | * @isoch_delay: wValue from Set Isochronous Delay request; |
@@ -673,6 +684,7 @@ struct dwc3_scratchpad_array { | |||
673 | * @test_mode_nr: test feature selector | 684 | * @test_mode_nr: test feature selector |
674 | * @lpm_nyet_threshold: LPM NYET response threshold | 685 | * @lpm_nyet_threshold: LPM NYET response threshold |
675 | * @hird_threshold: HIRD threshold | 686 | * @hird_threshold: HIRD threshold |
687 | * @hsphy_interface: "utmi" or "ulpi" | ||
676 | * @delayed_status: true when gadget driver asks for delayed status | 688 | * @delayed_status: true when gadget driver asks for delayed status |
677 | * @ep0_bounced: true when we used bounce buffer | 689 | * @ep0_bounced: true when we used bounce buffer |
678 | * @ep0_expect_in: true when we expect a DATA IN transfer | 690 | * @ep0_expect_in: true when we expect a DATA IN transfer |
@@ -739,6 +751,8 @@ struct dwc3 { | |||
739 | struct phy *usb2_generic_phy; | 751 | struct phy *usb2_generic_phy; |
740 | struct phy *usb3_generic_phy; | 752 | struct phy *usb3_generic_phy; |
741 | 753 | ||
754 | struct ulpi *ulpi; | ||
755 | |||
742 | void __iomem *regs; | 756 | void __iomem *regs; |
743 | size_t regs_size; | 757 | size_t regs_size; |
744 | 758 | ||
@@ -800,6 +814,8 @@ struct dwc3 { | |||
800 | u8 lpm_nyet_threshold; | 814 | u8 lpm_nyet_threshold; |
801 | u8 hird_threshold; | 815 | u8 hird_threshold; |
802 | 816 | ||
817 | const char *hsphy_interface; | ||
818 | |||
803 | unsigned delayed_status:1; | 819 | unsigned delayed_status:1; |
804 | unsigned ep0_bounced:1; | 820 | unsigned ep0_bounced:1; |
805 | unsigned ep0_expect_in:1; | 821 | unsigned ep0_expect_in:1; |
@@ -1035,4 +1051,14 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc) | |||
1035 | } | 1051 | } |
1036 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ | 1052 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ |
1037 | 1053 | ||
1054 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) | ||
1055 | int dwc3_ulpi_init(struct dwc3 *dwc); | ||
1056 | void dwc3_ulpi_exit(struct dwc3 *dwc); | ||
1057 | #else | ||
1058 | static inline int dwc3_ulpi_init(struct dwc3 *dwc) | ||
1059 | { return 0; } | ||
1060 | static inline void dwc3_ulpi_exit(struct dwc3 *dwc) | ||
1061 | { } | ||
1062 | #endif | ||
1063 | |||
1038 | #endif /* __DRIVERS_USB_DWC3_CORE_H */ | 1064 | #endif /* __DRIVERS_USB_DWC3_CORE_H */ |
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b773fb53d6a7..27e4fc896e9d 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/gpio/consumer.h> | ||
25 | #include <linux/acpi.h> | ||
24 | 26 | ||
25 | #include "platform_data.h" | 27 | #include "platform_data.h" |
26 | 28 | ||
@@ -31,6 +33,15 @@ | |||
31 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 | 33 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 |
32 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 | 34 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 |
33 | 35 | ||
36 | static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; | ||
37 | static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; | ||
38 | |||
39 | static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = { | ||
40 | { "reset-gpios", &reset_gpios, 1 }, | ||
41 | { "cs-gpios", &cs_gpios, 1 }, | ||
42 | { }, | ||
43 | }; | ||
44 | |||
34 | static int dwc3_pci_quirks(struct pci_dev *pdev) | 45 | static int dwc3_pci_quirks(struct pci_dev *pdev) |
35 | { | 46 | { |
36 | if (pdev->vendor == PCI_VENDOR_ID_AMD && | 47 | if (pdev->vendor == PCI_VENDOR_ID_AMD && |
@@ -65,6 +76,30 @@ static int dwc3_pci_quirks(struct pci_dev *pdev) | |||
65 | sizeof(pdata)); | 76 | sizeof(pdata)); |
66 | } | 77 | } |
67 | 78 | ||
79 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
80 | pdev->device == PCI_DEVICE_ID_INTEL_BYT) { | ||
81 | struct gpio_desc *gpio; | ||
82 | |||
83 | acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), | ||
84 | acpi_dwc3_byt_gpios); | ||
85 | |||
86 | /* These GPIOs will turn on the USB2 PHY */ | ||
87 | gpio = gpiod_get(&pdev->dev, "cs"); | ||
88 | if (!IS_ERR(gpio)) { | ||
89 | gpiod_direction_output(gpio, 0); | ||
90 | gpiod_set_value_cansleep(gpio, 1); | ||
91 | gpiod_put(gpio); | ||
92 | } | ||
93 | |||
94 | gpio = gpiod_get(&pdev->dev, "reset"); | ||
95 | if (!IS_ERR(gpio)) { | ||
96 | gpiod_direction_output(gpio, 0); | ||
97 | gpiod_set_value_cansleep(gpio, 1); | ||
98 | gpiod_put(gpio); | ||
99 | usleep_range(10000, 11000); | ||
100 | } | ||
101 | } | ||
102 | |||
68 | return 0; | 103 | return 0; |
69 | } | 104 | } |
70 | 105 | ||
@@ -128,6 +163,7 @@ err: | |||
128 | 163 | ||
129 | static void dwc3_pci_remove(struct pci_dev *pci) | 164 | static void dwc3_pci_remove(struct pci_dev *pci) |
130 | { | 165 | { |
166 | acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev)); | ||
131 | platform_device_unregister(pci_get_drvdata(pci)); | 167 | platform_device_unregister(pci_get_drvdata(pci)); |
132 | } | 168 | } |
133 | 169 | ||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8946c32047e9..333a7c0078fc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -291,6 +291,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param) | |||
291 | dwc3_trace(trace_dwc3_gadget, | 291 | dwc3_trace(trace_dwc3_gadget, |
292 | "Command Complete --> %d", | 292 | "Command Complete --> %d", |
293 | DWC3_DGCMD_STATUS(reg)); | 293 | DWC3_DGCMD_STATUS(reg)); |
294 | if (DWC3_DGCMD_STATUS(reg)) | ||
295 | return -EINVAL; | ||
294 | return 0; | 296 | return 0; |
295 | } | 297 | } |
296 | 298 | ||
@@ -328,6 +330,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | |||
328 | dwc3_trace(trace_dwc3_gadget, | 330 | dwc3_trace(trace_dwc3_gadget, |
329 | "Command Complete --> %d", | 331 | "Command Complete --> %d", |
330 | DWC3_DEPCMD_STATUS(reg)); | 332 | DWC3_DEPCMD_STATUS(reg)); |
333 | if (DWC3_DEPCMD_STATUS(reg)) | ||
334 | return -EINVAL; | ||
331 | return 0; | 335 | return 0; |
332 | } | 336 | } |
333 | 337 | ||
@@ -1902,12 +1906,16 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | |||
1902 | { | 1906 | { |
1903 | unsigned status = 0; | 1907 | unsigned status = 0; |
1904 | int clean_busy; | 1908 | int clean_busy; |
1909 | u32 is_xfer_complete; | ||
1910 | |||
1911 | is_xfer_complete = (event->endpoint_event == DWC3_DEPEVT_XFERCOMPLETE); | ||
1905 | 1912 | ||
1906 | if (event->status & DEPEVT_STATUS_BUSERR) | 1913 | if (event->status & DEPEVT_STATUS_BUSERR) |
1907 | status = -ECONNRESET; | 1914 | status = -ECONNRESET; |
1908 | 1915 | ||
1909 | clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); | 1916 | clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); |
1910 | if (clean_busy) | 1917 | if (clean_busy && (is_xfer_complete || |
1918 | usb_endpoint_xfer_isoc(dep->endpoint.desc))) | ||
1911 | dep->flags &= ~DWC3_EP_BUSY; | 1919 | dep->flags &= ~DWC3_EP_BUSY; |
1912 | 1920 | ||
1913 | /* | 1921 | /* |
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index a2bd464be828..d3614ecbb9ca 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h | |||
@@ -45,4 +45,6 @@ struct dwc3_platform_data { | |||
45 | 45 | ||
46 | unsigned tx_de_emphasis_quirk:1; | 46 | unsigned tx_de_emphasis_quirk:1; |
47 | unsigned tx_de_emphasis:2; | 47 | unsigned tx_de_emphasis:2; |
48 | |||
49 | const char *hsphy_interface; | ||
48 | }; | 50 | }; |
diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c new file mode 100644 index 000000000000..ec004c6d76f2 --- /dev/null +++ b/drivers/usb/dwc3/ulpi.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /** | ||
2 | * ulpi.c - DesignWare USB3 Controller's ULPI PHY interface | ||
3 | * | ||
4 | * Copyright (C) 2015 Intel Corporation | ||
5 | * | ||
6 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.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/ulpi/regs.h> | ||
14 | |||
15 | #include "core.h" | ||
16 | #include "io.h" | ||
17 | |||
18 | #define DWC3_ULPI_ADDR(a) \ | ||
19 | ((a >= ULPI_EXT_VENDOR_SPECIFIC) ? \ | ||
20 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ | ||
21 | DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) | ||
22 | |||
23 | static int dwc3_ulpi_busyloop(struct dwc3 *dwc) | ||
24 | { | ||
25 | unsigned count = 1000; | ||
26 | u32 reg; | ||
27 | |||
28 | while (count--) { | ||
29 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | ||
30 | if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | ||
31 | return 0; | ||
32 | cpu_relax(); | ||
33 | } | ||
34 | |||
35 | return -ETIMEDOUT; | ||
36 | } | ||
37 | |||
38 | static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr) | ||
39 | { | ||
40 | struct dwc3 *dwc = dev_get_drvdata(ops->dev); | ||
41 | u32 reg; | ||
42 | int ret; | ||
43 | |||
44 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | ||
45 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | ||
46 | |||
47 | ret = dwc3_ulpi_busyloop(dwc); | ||
48 | if (ret) | ||
49 | return ret; | ||
50 | |||
51 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | ||
52 | |||
53 | return DWC3_GUSB2PHYACC_DATA(reg); | ||
54 | } | ||
55 | |||
56 | static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val) | ||
57 | { | ||
58 | struct dwc3 *dwc = dev_get_drvdata(ops->dev); | ||
59 | u32 reg; | ||
60 | |||
61 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | ||
62 | reg |= DWC3_GUSB2PHYACC_WRITE | val; | ||
63 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | ||
64 | |||
65 | return dwc3_ulpi_busyloop(dwc); | ||
66 | } | ||
67 | |||
68 | static struct ulpi_ops dwc3_ulpi_ops = { | ||
69 | .read = dwc3_ulpi_read, | ||
70 | .write = dwc3_ulpi_write, | ||
71 | }; | ||
72 | |||
73 | int dwc3_ulpi_init(struct dwc3 *dwc) | ||
74 | { | ||
75 | /* Register the interface */ | ||
76 | dwc->ulpi = ulpi_register_interface(dwc->dev, &dwc3_ulpi_ops); | ||
77 | if (IS_ERR(dwc->ulpi)) { | ||
78 | dev_err(dwc->dev, "failed to register ULPI interface"); | ||
79 | return PTR_ERR(dwc->ulpi); | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | void dwc3_ulpi_exit(struct dwc3 *dwc) | ||
86 | { | ||
87 | if (dwc->ulpi) { | ||
88 | ulpi_unregister_interface(dwc->ulpi); | ||
89 | dwc->ulpi = NULL; | ||
90 | } | ||
91 | } | ||
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 0567cca1465e..919cdfdda78b 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -258,15 +258,25 @@ struct usb_ep *usb_ep_autoconfig_ss( | |||
258 | /* First, apply chip-specific "best usage" knowledge. | 258 | /* First, apply chip-specific "best usage" knowledge. |
259 | * This might make a good usb_gadget_ops hook ... | 259 | * This might make a good usb_gadget_ops hook ... |
260 | */ | 260 | */ |
261 | if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) { | 261 | if (gadget_is_net2280(gadget)) { |
262 | /* ep-e, ep-f are PIO with only 64 byte fifos */ | 262 | char name[8]; |
263 | ep = find_ep (gadget, "ep-e"); | 263 | |
264 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 264 | if (type == USB_ENDPOINT_XFER_INT) { |
265 | goto found_ep; | 265 | /* ep-e, ep-f are PIO with only 64 byte fifos */ |
266 | ep = find_ep (gadget, "ep-f"); | 266 | ep = find_ep(gadget, "ep-e"); |
267 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | ||
268 | goto found_ep; | ||
269 | ep = find_ep(gadget, "ep-f"); | ||
270 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | ||
271 | goto found_ep; | ||
272 | } | ||
273 | |||
274 | /* USB3380: use same address for usb and hardware endpoints */ | ||
275 | snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc), | ||
276 | usb_endpoint_dir_in(desc) ? "in" : "out"); | ||
277 | ep = find_ep(gadget, name); | ||
267 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) | 278 | if (ep && ep_matches(gadget, ep, desc, ep_comp)) |
268 | goto found_ep; | 279 | goto found_ep; |
269 | |||
270 | } else if (gadget_is_goku (gadget)) { | 280 | } else if (gadget_is_goku (gadget)) { |
271 | if (USB_ENDPOINT_XFER_INT == type) { | 281 | if (USB_ENDPOINT_XFER_INT == type) { |
272 | /* single buffering is enough */ | 282 | /* single buffering is enough */ |
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 3507f880eb74..45b8c8b338df 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -3435,6 +3435,7 @@ done: | |||
3435 | static void ffs_closed(struct ffs_data *ffs) | 3435 | static void ffs_closed(struct ffs_data *ffs) |
3436 | { | 3436 | { |
3437 | struct ffs_dev *ffs_obj; | 3437 | struct ffs_dev *ffs_obj; |
3438 | struct f_fs_opts *opts; | ||
3438 | 3439 | ||
3439 | ENTER(); | 3440 | ENTER(); |
3440 | ffs_dev_lock(); | 3441 | ffs_dev_lock(); |
@@ -3449,8 +3450,13 @@ static void ffs_closed(struct ffs_data *ffs) | |||
3449 | ffs_obj->ffs_closed_callback) | 3450 | ffs_obj->ffs_closed_callback) |
3450 | ffs_obj->ffs_closed_callback(ffs); | 3451 | ffs_obj->ffs_closed_callback(ffs); |
3451 | 3452 | ||
3452 | if (!ffs_obj->opts || ffs_obj->opts->no_configfs | 3453 | if (ffs_obj->opts) |
3453 | || !ffs_obj->opts->func_inst.group.cg_item.ci_parent) | 3454 | opts = ffs_obj->opts; |
3455 | else | ||
3456 | goto done; | ||
3457 | |||
3458 | if (opts->no_configfs || !opts->func_inst.group.cg_item.ci_parent | ||
3459 | || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount)) | ||
3454 | goto done; | 3460 | goto done; |
3455 | 3461 | ||
3456 | unregister_gadget_item(ffs_obj->opts-> | 3462 | unregister_gadget_item(ffs_obj->opts-> |
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 829edf878dac..32985dade838 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c | |||
@@ -76,7 +76,7 @@ struct f_rndis { | |||
76 | u8 ethaddr[ETH_ALEN]; | 76 | u8 ethaddr[ETH_ALEN]; |
77 | u32 vendorID; | 77 | u32 vendorID; |
78 | const char *manufacturer; | 78 | const char *manufacturer; |
79 | int config; | 79 | struct rndis_params *params; |
80 | 80 | ||
81 | struct usb_ep *notify; | 81 | struct usb_ep *notify; |
82 | struct usb_request *notify_req; | 82 | struct usb_request *notify_req; |
@@ -453,7 +453,7 @@ static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req) | |||
453 | 453 | ||
454 | /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ | 454 | /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ |
455 | // spin_lock(&dev->lock); | 455 | // spin_lock(&dev->lock); |
456 | status = rndis_msg_parser(rndis->config, (u8 *) req->buf); | 456 | status = rndis_msg_parser(rndis->params, (u8 *) req->buf); |
457 | if (status < 0) | 457 | if (status < 0) |
458 | pr_err("RNDIS command error %d, %d/%d\n", | 458 | pr_err("RNDIS command error %d, %d/%d\n", |
459 | status, req->actual, req->length); | 459 | status, req->actual, req->length); |
@@ -499,12 +499,12 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
499 | u32 n; | 499 | u32 n; |
500 | 500 | ||
501 | /* return the result */ | 501 | /* return the result */ |
502 | buf = rndis_get_next_response(rndis->config, &n); | 502 | buf = rndis_get_next_response(rndis->params, &n); |
503 | if (buf) { | 503 | if (buf) { |
504 | memcpy(req->buf, buf, n); | 504 | memcpy(req->buf, buf, n); |
505 | req->complete = rndis_response_complete; | 505 | req->complete = rndis_response_complete; |
506 | req->context = rndis; | 506 | req->context = rndis; |
507 | rndis_free_response(rndis->config, buf); | 507 | rndis_free_response(rndis->params, buf); |
508 | value = n; | 508 | value = n; |
509 | } | 509 | } |
510 | /* else stalls ... spec says to avoid that */ | 510 | /* else stalls ... spec says to avoid that */ |
@@ -597,7 +597,7 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
597 | if (IS_ERR(net)) | 597 | if (IS_ERR(net)) |
598 | return PTR_ERR(net); | 598 | return PTR_ERR(net); |
599 | 599 | ||
600 | rndis_set_param_dev(rndis->config, net, | 600 | rndis_set_param_dev(rndis->params, net, |
601 | &rndis->port.cdc_filter); | 601 | &rndis->port.cdc_filter); |
602 | } else | 602 | } else |
603 | goto fail; | 603 | goto fail; |
@@ -617,7 +617,7 @@ static void rndis_disable(struct usb_function *f) | |||
617 | 617 | ||
618 | DBG(cdev, "rndis deactivated\n"); | 618 | DBG(cdev, "rndis deactivated\n"); |
619 | 619 | ||
620 | rndis_uninit(rndis->config); | 620 | rndis_uninit(rndis->params); |
621 | gether_disconnect(&rndis->port); | 621 | gether_disconnect(&rndis->port); |
622 | 622 | ||
623 | usb_ep_disable(rndis->notify); | 623 | usb_ep_disable(rndis->notify); |
@@ -640,9 +640,9 @@ static void rndis_open(struct gether *geth) | |||
640 | 640 | ||
641 | DBG(cdev, "%s\n", __func__); | 641 | DBG(cdev, "%s\n", __func__); |
642 | 642 | ||
643 | rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, | 643 | rndis_set_param_medium(rndis->params, RNDIS_MEDIUM_802_3, |
644 | bitrate(cdev->gadget) / 100); | 644 | bitrate(cdev->gadget) / 100); |
645 | rndis_signal_connect(rndis->config); | 645 | rndis_signal_connect(rndis->params); |
646 | } | 646 | } |
647 | 647 | ||
648 | static void rndis_close(struct gether *geth) | 648 | static void rndis_close(struct gether *geth) |
@@ -651,8 +651,8 @@ static void rndis_close(struct gether *geth) | |||
651 | 651 | ||
652 | DBG(geth->func.config->cdev, "%s\n", __func__); | 652 | DBG(geth->func.config->cdev, "%s\n", __func__); |
653 | 653 | ||
654 | rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); | 654 | rndis_set_param_medium(rndis->params, RNDIS_MEDIUM_802_3, 0); |
655 | rndis_signal_disconnect(rndis->config); | 655 | rndis_signal_disconnect(rndis->params); |
656 | } | 656 | } |
657 | 657 | ||
658 | /*-------------------------------------------------------------------------*/ | 658 | /*-------------------------------------------------------------------------*/ |
@@ -796,11 +796,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) | |||
796 | rndis->port.open = rndis_open; | 796 | rndis->port.open = rndis_open; |
797 | rndis->port.close = rndis_close; | 797 | rndis->port.close = rndis_close; |
798 | 798 | ||
799 | rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0); | 799 | rndis_set_param_medium(rndis->params, RNDIS_MEDIUM_802_3, 0); |
800 | rndis_set_host_mac(rndis->config, rndis->ethaddr); | 800 | rndis_set_host_mac(rndis->params, rndis->ethaddr); |
801 | 801 | ||
802 | if (rndis->manufacturer && rndis->vendorID && | 802 | if (rndis->manufacturer && rndis->vendorID && |
803 | rndis_set_param_vendor(rndis->config, rndis->vendorID, | 803 | rndis_set_param_vendor(rndis->params, rndis->vendorID, |
804 | rndis->manufacturer)) { | 804 | rndis->manufacturer)) { |
805 | status = -EINVAL; | 805 | status = -EINVAL; |
806 | goto fail_free_descs; | 806 | goto fail_free_descs; |
@@ -944,7 +944,7 @@ static void rndis_free(struct usb_function *f) | |||
944 | struct f_rndis_opts *opts; | 944 | struct f_rndis_opts *opts; |
945 | 945 | ||
946 | rndis = func_to_rndis(f); | 946 | rndis = func_to_rndis(f); |
947 | rndis_deregister(rndis->config); | 947 | rndis_deregister(rndis->params); |
948 | opts = container_of(f->fi, struct f_rndis_opts, func_inst); | 948 | opts = container_of(f->fi, struct f_rndis_opts, func_inst); |
949 | kfree(rndis); | 949 | kfree(rndis); |
950 | mutex_lock(&opts->lock); | 950 | mutex_lock(&opts->lock); |
@@ -968,7 +968,7 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi) | |||
968 | { | 968 | { |
969 | struct f_rndis *rndis; | 969 | struct f_rndis *rndis; |
970 | struct f_rndis_opts *opts; | 970 | struct f_rndis_opts *opts; |
971 | int status; | 971 | struct rndis_params *params; |
972 | 972 | ||
973 | /* allocate and initialize one new instance */ | 973 | /* allocate and initialize one new instance */ |
974 | rndis = kzalloc(sizeof(*rndis), GFP_KERNEL); | 974 | rndis = kzalloc(sizeof(*rndis), GFP_KERNEL); |
@@ -1002,36 +1002,16 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi) | |||
1002 | rndis->port.func.disable = rndis_disable; | 1002 | rndis->port.func.disable = rndis_disable; |
1003 | rndis->port.func.free_func = rndis_free; | 1003 | rndis->port.func.free_func = rndis_free; |
1004 | 1004 | ||
1005 | status = rndis_register(rndis_response_available, rndis); | 1005 | params = rndis_register(rndis_response_available, rndis); |
1006 | if (status < 0) { | 1006 | if (IS_ERR(params)) { |
1007 | kfree(rndis); | 1007 | kfree(rndis); |
1008 | return ERR_PTR(status); | 1008 | return ERR_CAST(params); |
1009 | } | 1009 | } |
1010 | rndis->config = status; | 1010 | rndis->params = params; |
1011 | 1011 | ||
1012 | return &rndis->port.func; | 1012 | return &rndis->port.func; |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | DECLARE_USB_FUNCTION(rndis, rndis_alloc_inst, rndis_alloc); | 1015 | DECLARE_USB_FUNCTION_INIT(rndis, rndis_alloc_inst, rndis_alloc); |
1016 | |||
1017 | static int __init rndis_mod_init(void) | ||
1018 | { | ||
1019 | int ret; | ||
1020 | |||
1021 | ret = rndis_init(); | ||
1022 | if (ret) | ||
1023 | return ret; | ||
1024 | |||
1025 | return usb_function_register(&rndisusb_func); | ||
1026 | } | ||
1027 | module_init(rndis_mod_init); | ||
1028 | |||
1029 | static void __exit rndis_mod_exit(void) | ||
1030 | { | ||
1031 | usb_function_unregister(&rndisusb_func); | ||
1032 | rndis_exit(); | ||
1033 | } | ||
1034 | module_exit(rndis_mod_exit); | ||
1035 | |||
1036 | MODULE_LICENSE("GPL"); | 1016 | MODULE_LICENSE("GPL"); |
1037 | MODULE_AUTHOR("David Brownell"); | 1017 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 95d2324f6977..70d3917cc003 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/idr.h> | ||
28 | #include <linux/list.h> | 29 | #include <linux/list.h> |
29 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
@@ -57,17 +58,26 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); | |||
57 | #define rndis_debug 0 | 58 | #define rndis_debug 0 |
58 | #endif | 59 | #endif |
59 | 60 | ||
60 | #define RNDIS_MAX_CONFIGS 1 | 61 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
61 | 62 | ||
63 | #define NAME_TEMPLATE "driver/rndis-%03d" | ||
62 | 64 | ||
63 | static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; | 65 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ |
66 | |||
67 | static DEFINE_IDA(rndis_ida); | ||
64 | 68 | ||
65 | /* Driver Version */ | 69 | /* Driver Version */ |
66 | static const __le32 rndis_driver_version = cpu_to_le32(1); | 70 | static const __le32 rndis_driver_version = cpu_to_le32(1); |
67 | 71 | ||
68 | /* Function Prototypes */ | 72 | /* Function Prototypes */ |
69 | static rndis_resp_t *rndis_add_response(int configNr, u32 length); | 73 | static rndis_resp_t *rndis_add_response(struct rndis_params *params, |
74 | u32 length); | ||
75 | |||
76 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
77 | |||
78 | static const struct file_operations rndis_proc_fops; | ||
70 | 79 | ||
80 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ | ||
71 | 81 | ||
72 | /* supported OIDs */ | 82 | /* supported OIDs */ |
73 | static const u32 oid_supported_list[] = | 83 | static const u32 oid_supported_list[] = |
@@ -160,7 +170,7 @@ static const u32 oid_supported_list[] = | |||
160 | 170 | ||
161 | 171 | ||
162 | /* NDIS Functions */ | 172 | /* NDIS Functions */ |
163 | static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | 173 | static int gen_ndis_query_resp(struct rndis_params *params, u32 OID, u8 *buf, |
164 | unsigned buf_len, rndis_resp_t *r) | 174 | unsigned buf_len, rndis_resp_t *r) |
165 | { | 175 | { |
166 | int retval = -ENOTSUPP; | 176 | int retval = -ENOTSUPP; |
@@ -192,7 +202,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
192 | outbuf = (__le32 *)&resp[1]; | 202 | outbuf = (__le32 *)&resp[1]; |
193 | resp->InformationBufferOffset = cpu_to_le32(16); | 203 | resp->InformationBufferOffset = cpu_to_le32(16); |
194 | 204 | ||
195 | net = rndis_per_dev_params[configNr].dev; | 205 | net = params->dev; |
196 | stats = dev_get_stats(net, &temp); | 206 | stats = dev_get_stats(net, &temp); |
197 | 207 | ||
198 | switch (OID) { | 208 | switch (OID) { |
@@ -225,7 +235,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
225 | /* mandatory */ | 235 | /* mandatory */ |
226 | case RNDIS_OID_GEN_MEDIA_SUPPORTED: | 236 | case RNDIS_OID_GEN_MEDIA_SUPPORTED: |
227 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); | 237 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); |
228 | *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); | 238 | *outbuf = cpu_to_le32(params->medium); |
229 | retval = 0; | 239 | retval = 0; |
230 | break; | 240 | break; |
231 | 241 | ||
@@ -233,16 +243,15 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
233 | case RNDIS_OID_GEN_MEDIA_IN_USE: | 243 | case RNDIS_OID_GEN_MEDIA_IN_USE: |
234 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); | 244 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); |
235 | /* one medium, one transport... (maybe you do it better) */ | 245 | /* one medium, one transport... (maybe you do it better) */ |
236 | *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); | 246 | *outbuf = cpu_to_le32(params->medium); |
237 | retval = 0; | 247 | retval = 0; |
238 | break; | 248 | break; |
239 | 249 | ||
240 | /* mandatory */ | 250 | /* mandatory */ |
241 | case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: | 251 | case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: |
242 | pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); | 252 | pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); |
243 | if (rndis_per_dev_params[configNr].dev) { | 253 | if (params->dev) { |
244 | *outbuf = cpu_to_le32( | 254 | *outbuf = cpu_to_le32(params->dev->mtu); |
245 | rndis_per_dev_params[configNr].dev->mtu); | ||
246 | retval = 0; | 255 | retval = 0; |
247 | } | 256 | } |
248 | break; | 257 | break; |
@@ -251,21 +260,18 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
251 | case RNDIS_OID_GEN_LINK_SPEED: | 260 | case RNDIS_OID_GEN_LINK_SPEED: |
252 | if (rndis_debug > 1) | 261 | if (rndis_debug > 1) |
253 | pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); | 262 | pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); |
254 | if (rndis_per_dev_params[configNr].media_state | 263 | if (params->media_state == RNDIS_MEDIA_STATE_DISCONNECTED) |
255 | == RNDIS_MEDIA_STATE_DISCONNECTED) | ||
256 | *outbuf = cpu_to_le32(0); | 264 | *outbuf = cpu_to_le32(0); |
257 | else | 265 | else |
258 | *outbuf = cpu_to_le32( | 266 | *outbuf = cpu_to_le32(params->speed); |
259 | rndis_per_dev_params[configNr].speed); | ||
260 | retval = 0; | 267 | retval = 0; |
261 | break; | 268 | break; |
262 | 269 | ||
263 | /* mandatory */ | 270 | /* mandatory */ |
264 | case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: | 271 | case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: |
265 | pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); | 272 | pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); |
266 | if (rndis_per_dev_params[configNr].dev) { | 273 | if (params->dev) { |
267 | *outbuf = cpu_to_le32( | 274 | *outbuf = cpu_to_le32(params->dev->mtu); |
268 | rndis_per_dev_params[configNr].dev->mtu); | ||
269 | retval = 0; | 275 | retval = 0; |
270 | } | 276 | } |
271 | break; | 277 | break; |
@@ -273,9 +279,8 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
273 | /* mandatory */ | 279 | /* mandatory */ |
274 | case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: | 280 | case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: |
275 | pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); | 281 | pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); |
276 | if (rndis_per_dev_params[configNr].dev) { | 282 | if (params->dev) { |
277 | *outbuf = cpu_to_le32( | 283 | *outbuf = cpu_to_le32(params->dev->mtu); |
278 | rndis_per_dev_params[configNr].dev->mtu); | ||
279 | retval = 0; | 284 | retval = 0; |
280 | } | 285 | } |
281 | break; | 286 | break; |
@@ -283,20 +288,16 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
283 | /* mandatory */ | 288 | /* mandatory */ |
284 | case RNDIS_OID_GEN_VENDOR_ID: | 289 | case RNDIS_OID_GEN_VENDOR_ID: |
285 | pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); | 290 | pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); |
286 | *outbuf = cpu_to_le32( | 291 | *outbuf = cpu_to_le32(params->vendorID); |
287 | rndis_per_dev_params[configNr].vendorID); | ||
288 | retval = 0; | 292 | retval = 0; |
289 | break; | 293 | break; |
290 | 294 | ||
291 | /* mandatory */ | 295 | /* mandatory */ |
292 | case RNDIS_OID_GEN_VENDOR_DESCRIPTION: | 296 | case RNDIS_OID_GEN_VENDOR_DESCRIPTION: |
293 | pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); | 297 | pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); |
294 | if (rndis_per_dev_params[configNr].vendorDescr) { | 298 | if (params->vendorDescr) { |
295 | length = strlen(rndis_per_dev_params[configNr]. | 299 | length = strlen(params->vendorDescr); |
296 | vendorDescr); | 300 | memcpy(outbuf, params->vendorDescr, length); |
297 | memcpy(outbuf, | ||
298 | rndis_per_dev_params[configNr].vendorDescr, | ||
299 | length); | ||
300 | } else { | 301 | } else { |
301 | outbuf[0] = 0; | 302 | outbuf[0] = 0; |
302 | } | 303 | } |
@@ -313,7 +314,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
313 | /* mandatory */ | 314 | /* mandatory */ |
314 | case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: | 315 | case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: |
315 | pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); | 316 | pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); |
316 | *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); | 317 | *outbuf = cpu_to_le32(*params->filter); |
317 | retval = 0; | 318 | retval = 0; |
318 | break; | 319 | break; |
319 | 320 | ||
@@ -328,8 +329,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
328 | case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: | 329 | case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: |
329 | if (rndis_debug > 1) | 330 | if (rndis_debug > 1) |
330 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); | 331 | pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); |
331 | *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] | 332 | *outbuf = cpu_to_le32(params->media_state); |
332 | .media_state); | ||
333 | retval = 0; | 333 | retval = 0; |
334 | break; | 334 | break; |
335 | 335 | ||
@@ -409,11 +409,9 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
409 | /* mandatory */ | 409 | /* mandatory */ |
410 | case RNDIS_OID_802_3_PERMANENT_ADDRESS: | 410 | case RNDIS_OID_802_3_PERMANENT_ADDRESS: |
411 | pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); | 411 | pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); |
412 | if (rndis_per_dev_params[configNr].dev) { | 412 | if (params->dev) { |
413 | length = ETH_ALEN; | 413 | length = ETH_ALEN; |
414 | memcpy(outbuf, | 414 | memcpy(outbuf, params->host_mac, length); |
415 | rndis_per_dev_params[configNr].host_mac, | ||
416 | length); | ||
417 | retval = 0; | 415 | retval = 0; |
418 | } | 416 | } |
419 | break; | 417 | break; |
@@ -421,11 +419,9 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
421 | /* mandatory */ | 419 | /* mandatory */ |
422 | case RNDIS_OID_802_3_CURRENT_ADDRESS: | 420 | case RNDIS_OID_802_3_CURRENT_ADDRESS: |
423 | pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); | 421 | pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); |
424 | if (rndis_per_dev_params[configNr].dev) { | 422 | if (params->dev) { |
425 | length = ETH_ALEN; | 423 | length = ETH_ALEN; |
426 | memcpy(outbuf, | 424 | memcpy(outbuf, params->host_mac, length); |
427 | rndis_per_dev_params [configNr].host_mac, | ||
428 | length); | ||
429 | retval = 0; | 425 | retval = 0; |
430 | } | 426 | } |
431 | break; | 427 | break; |
@@ -490,12 +486,11 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, | |||
490 | return retval; | 486 | return retval; |
491 | } | 487 | } |
492 | 488 | ||
493 | static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, | 489 | static int gen_ndis_set_resp(struct rndis_params *params, u32 OID, |
494 | rndis_resp_t *r) | 490 | u8 *buf, u32 buf_len, rndis_resp_t *r) |
495 | { | 491 | { |
496 | rndis_set_cmplt_type *resp; | 492 | rndis_set_cmplt_type *resp; |
497 | int i, retval = -ENOTSUPP; | 493 | int i, retval = -ENOTSUPP; |
498 | struct rndis_params *params; | ||
499 | 494 | ||
500 | if (!r) | 495 | if (!r) |
501 | return -ENOMEM; | 496 | return -ENOMEM; |
@@ -514,7 +509,6 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
514 | } | 509 | } |
515 | } | 510 | } |
516 | 511 | ||
517 | params = &rndis_per_dev_params[configNr]; | ||
518 | switch (OID) { | 512 | switch (OID) { |
519 | case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: | 513 | case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: |
520 | 514 | ||
@@ -563,16 +557,16 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
563 | * Response Functions | 557 | * Response Functions |
564 | */ | 558 | */ |
565 | 559 | ||
566 | static int rndis_init_response(int configNr, rndis_init_msg_type *buf) | 560 | static int rndis_init_response(struct rndis_params *params, |
561 | rndis_init_msg_type *buf) | ||
567 | { | 562 | { |
568 | rndis_init_cmplt_type *resp; | 563 | rndis_init_cmplt_type *resp; |
569 | rndis_resp_t *r; | 564 | rndis_resp_t *r; |
570 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
571 | 565 | ||
572 | if (!params->dev) | 566 | if (!params->dev) |
573 | return -ENOTSUPP; | 567 | return -ENOTSUPP; |
574 | 568 | ||
575 | r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type)); | 569 | r = rndis_add_response(params, sizeof(rndis_init_cmplt_type)); |
576 | if (!r) | 570 | if (!r) |
577 | return -ENOMEM; | 571 | return -ENOMEM; |
578 | resp = (rndis_init_cmplt_type *)r->buf; | 572 | resp = (rndis_init_cmplt_type *)r->buf; |
@@ -599,11 +593,11 @@ static int rndis_init_response(int configNr, rndis_init_msg_type *buf) | |||
599 | return 0; | 593 | return 0; |
600 | } | 594 | } |
601 | 595 | ||
602 | static int rndis_query_response(int configNr, rndis_query_msg_type *buf) | 596 | static int rndis_query_response(struct rndis_params *params, |
597 | rndis_query_msg_type *buf) | ||
603 | { | 598 | { |
604 | rndis_query_cmplt_type *resp; | 599 | rndis_query_cmplt_type *resp; |
605 | rndis_resp_t *r; | 600 | rndis_resp_t *r; |
606 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
607 | 601 | ||
608 | /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ | 602 | /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ |
609 | if (!params->dev) | 603 | if (!params->dev) |
@@ -615,7 +609,7 @@ static int rndis_query_response(int configNr, rndis_query_msg_type *buf) | |||
615 | * rndis_query_cmplt_type followed by data. | 609 | * rndis_query_cmplt_type followed by data. |
616 | * oid_supported_list is the largest data reply | 610 | * oid_supported_list is the largest data reply |
617 | */ | 611 | */ |
618 | r = rndis_add_response(configNr, | 612 | r = rndis_add_response(params, |
619 | sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type)); | 613 | sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type)); |
620 | if (!r) | 614 | if (!r) |
621 | return -ENOMEM; | 615 | return -ENOMEM; |
@@ -624,7 +618,7 @@ static int rndis_query_response(int configNr, rndis_query_msg_type *buf) | |||
624 | resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); | 618 | resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); |
625 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 619 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
626 | 620 | ||
627 | if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), | 621 | if (gen_ndis_query_resp(params, le32_to_cpu(buf->OID), |
628 | le32_to_cpu(buf->InformationBufferOffset) | 622 | le32_to_cpu(buf->InformationBufferOffset) |
629 | + 8 + (u8 *)buf, | 623 | + 8 + (u8 *)buf, |
630 | le32_to_cpu(buf->InformationBufferLength), | 624 | le32_to_cpu(buf->InformationBufferLength), |
@@ -641,14 +635,14 @@ static int rndis_query_response(int configNr, rndis_query_msg_type *buf) | |||
641 | return 0; | 635 | return 0; |
642 | } | 636 | } |
643 | 637 | ||
644 | static int rndis_set_response(int configNr, rndis_set_msg_type *buf) | 638 | static int rndis_set_response(struct rndis_params *params, |
639 | rndis_set_msg_type *buf) | ||
645 | { | 640 | { |
646 | u32 BufLength, BufOffset; | 641 | u32 BufLength, BufOffset; |
647 | rndis_set_cmplt_type *resp; | 642 | rndis_set_cmplt_type *resp; |
648 | rndis_resp_t *r; | 643 | rndis_resp_t *r; |
649 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
650 | 644 | ||
651 | r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type)); | 645 | r = rndis_add_response(params, sizeof(rndis_set_cmplt_type)); |
652 | if (!r) | 646 | if (!r) |
653 | return -ENOMEM; | 647 | return -ENOMEM; |
654 | resp = (rndis_set_cmplt_type *)r->buf; | 648 | resp = (rndis_set_cmplt_type *)r->buf; |
@@ -671,7 +665,7 @@ static int rndis_set_response(int configNr, rndis_set_msg_type *buf) | |||
671 | resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); | 665 | resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); |
672 | resp->MessageLength = cpu_to_le32(16); | 666 | resp->MessageLength = cpu_to_le32(16); |
673 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 667 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
674 | if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), | 668 | if (gen_ndis_set_resp(params, le32_to_cpu(buf->OID), |
675 | ((u8 *)buf) + 8 + BufOffset, BufLength, r)) | 669 | ((u8 *)buf) + 8 + BufOffset, BufLength, r)) |
676 | resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); | 670 | resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); |
677 | else | 671 | else |
@@ -681,13 +675,13 @@ static int rndis_set_response(int configNr, rndis_set_msg_type *buf) | |||
681 | return 0; | 675 | return 0; |
682 | } | 676 | } |
683 | 677 | ||
684 | static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) | 678 | static int rndis_reset_response(struct rndis_params *params, |
679 | rndis_reset_msg_type *buf) | ||
685 | { | 680 | { |
686 | rndis_reset_cmplt_type *resp; | 681 | rndis_reset_cmplt_type *resp; |
687 | rndis_resp_t *r; | 682 | rndis_resp_t *r; |
688 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
689 | 683 | ||
690 | r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type)); | 684 | r = rndis_add_response(params, sizeof(rndis_reset_cmplt_type)); |
691 | if (!r) | 685 | if (!r) |
692 | return -ENOMEM; | 686 | return -ENOMEM; |
693 | resp = (rndis_reset_cmplt_type *)r->buf; | 687 | resp = (rndis_reset_cmplt_type *)r->buf; |
@@ -702,16 +696,15 @@ static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) | |||
702 | return 0; | 696 | return 0; |
703 | } | 697 | } |
704 | 698 | ||
705 | static int rndis_keepalive_response(int configNr, | 699 | static int rndis_keepalive_response(struct rndis_params *params, |
706 | rndis_keepalive_msg_type *buf) | 700 | rndis_keepalive_msg_type *buf) |
707 | { | 701 | { |
708 | rndis_keepalive_cmplt_type *resp; | 702 | rndis_keepalive_cmplt_type *resp; |
709 | rndis_resp_t *r; | 703 | rndis_resp_t *r; |
710 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
711 | 704 | ||
712 | /* host "should" check only in RNDIS_DATA_INITIALIZED state */ | 705 | /* host "should" check only in RNDIS_DATA_INITIALIZED state */ |
713 | 706 | ||
714 | r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type)); | 707 | r = rndis_add_response(params, sizeof(rndis_keepalive_cmplt_type)); |
715 | if (!r) | 708 | if (!r) |
716 | return -ENOMEM; | 709 | return -ENOMEM; |
717 | resp = (rndis_keepalive_cmplt_type *)r->buf; | 710 | resp = (rndis_keepalive_cmplt_type *)r->buf; |
@@ -729,17 +722,15 @@ static int rndis_keepalive_response(int configNr, | |||
729 | /* | 722 | /* |
730 | * Device to Host Comunication | 723 | * Device to Host Comunication |
731 | */ | 724 | */ |
732 | static int rndis_indicate_status_msg(int configNr, u32 status) | 725 | static int rndis_indicate_status_msg(struct rndis_params *params, u32 status) |
733 | { | 726 | { |
734 | rndis_indicate_status_msg_type *resp; | 727 | rndis_indicate_status_msg_type *resp; |
735 | rndis_resp_t *r; | 728 | rndis_resp_t *r; |
736 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
737 | 729 | ||
738 | if (params->state == RNDIS_UNINITIALIZED) | 730 | if (params->state == RNDIS_UNINITIALIZED) |
739 | return -ENOTSUPP; | 731 | return -ENOTSUPP; |
740 | 732 | ||
741 | r = rndis_add_response(configNr, | 733 | r = rndis_add_response(params, sizeof(rndis_indicate_status_msg_type)); |
742 | sizeof(rndis_indicate_status_msg_type)); | ||
743 | if (!r) | 734 | if (!r) |
744 | return -ENOMEM; | 735 | return -ENOMEM; |
745 | resp = (rndis_indicate_status_msg_type *)r->buf; | 736 | resp = (rndis_indicate_status_msg_type *)r->buf; |
@@ -754,53 +745,48 @@ static int rndis_indicate_status_msg(int configNr, u32 status) | |||
754 | return 0; | 745 | return 0; |
755 | } | 746 | } |
756 | 747 | ||
757 | int rndis_signal_connect(int configNr) | 748 | int rndis_signal_connect(struct rndis_params *params) |
758 | { | 749 | { |
759 | rndis_per_dev_params[configNr].media_state | 750 | params->media_state = RNDIS_MEDIA_STATE_CONNECTED; |
760 | = RNDIS_MEDIA_STATE_CONNECTED; | 751 | return rndis_indicate_status_msg(params, RNDIS_STATUS_MEDIA_CONNECT); |
761 | return rndis_indicate_status_msg(configNr, | ||
762 | RNDIS_STATUS_MEDIA_CONNECT); | ||
763 | } | 752 | } |
764 | EXPORT_SYMBOL_GPL(rndis_signal_connect); | 753 | EXPORT_SYMBOL_GPL(rndis_signal_connect); |
765 | 754 | ||
766 | int rndis_signal_disconnect(int configNr) | 755 | int rndis_signal_disconnect(struct rndis_params *params) |
767 | { | 756 | { |
768 | rndis_per_dev_params[configNr].media_state | 757 | params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED; |
769 | = RNDIS_MEDIA_STATE_DISCONNECTED; | 758 | return rndis_indicate_status_msg(params, RNDIS_STATUS_MEDIA_DISCONNECT); |
770 | return rndis_indicate_status_msg(configNr, | ||
771 | RNDIS_STATUS_MEDIA_DISCONNECT); | ||
772 | } | 759 | } |
773 | EXPORT_SYMBOL_GPL(rndis_signal_disconnect); | 760 | EXPORT_SYMBOL_GPL(rndis_signal_disconnect); |
774 | 761 | ||
775 | void rndis_uninit(int configNr) | 762 | void rndis_uninit(struct rndis_params *params) |
776 | { | 763 | { |
777 | u8 *buf; | 764 | u8 *buf; |
778 | u32 length; | 765 | u32 length; |
779 | 766 | ||
780 | if (configNr >= RNDIS_MAX_CONFIGS) | 767 | if (!params) |
781 | return; | 768 | return; |
782 | rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED; | 769 | params->state = RNDIS_UNINITIALIZED; |
783 | 770 | ||
784 | /* drain the response queue */ | 771 | /* drain the response queue */ |
785 | while ((buf = rndis_get_next_response(configNr, &length))) | 772 | while ((buf = rndis_get_next_response(params, &length))) |
786 | rndis_free_response(configNr, buf); | 773 | rndis_free_response(params, buf); |
787 | } | 774 | } |
788 | EXPORT_SYMBOL_GPL(rndis_uninit); | 775 | EXPORT_SYMBOL_GPL(rndis_uninit); |
789 | 776 | ||
790 | void rndis_set_host_mac(int configNr, const u8 *addr) | 777 | void rndis_set_host_mac(struct rndis_params *params, const u8 *addr) |
791 | { | 778 | { |
792 | rndis_per_dev_params[configNr].host_mac = addr; | 779 | params->host_mac = addr; |
793 | } | 780 | } |
794 | EXPORT_SYMBOL_GPL(rndis_set_host_mac); | 781 | EXPORT_SYMBOL_GPL(rndis_set_host_mac); |
795 | 782 | ||
796 | /* | 783 | /* |
797 | * Message Parser | 784 | * Message Parser |
798 | */ | 785 | */ |
799 | int rndis_msg_parser(u8 configNr, u8 *buf) | 786 | int rndis_msg_parser(struct rndis_params *params, u8 *buf) |
800 | { | 787 | { |
801 | u32 MsgType, MsgLength; | 788 | u32 MsgType, MsgLength; |
802 | __le32 *tmp; | 789 | __le32 *tmp; |
803 | struct rndis_params *params; | ||
804 | 790 | ||
805 | if (!buf) | 791 | if (!buf) |
806 | return -ENOMEM; | 792 | return -ENOMEM; |
@@ -809,9 +795,8 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
809 | MsgType = get_unaligned_le32(tmp++); | 795 | MsgType = get_unaligned_le32(tmp++); |
810 | MsgLength = get_unaligned_le32(tmp++); | 796 | MsgLength = get_unaligned_le32(tmp++); |
811 | 797 | ||
812 | if (configNr >= RNDIS_MAX_CONFIGS) | 798 | if (!params) |
813 | return -ENOTSUPP; | 799 | return -ENOTSUPP; |
814 | params = &rndis_per_dev_params[configNr]; | ||
815 | 800 | ||
816 | /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for | 801 | /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for |
817 | * rx/tx statistics and link status, in addition to KEEPALIVE traffic | 802 | * rx/tx statistics and link status, in addition to KEEPALIVE traffic |
@@ -824,8 +809,7 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
824 | pr_debug("%s: RNDIS_MSG_INIT\n", | 809 | pr_debug("%s: RNDIS_MSG_INIT\n", |
825 | __func__); | 810 | __func__); |
826 | params->state = RNDIS_INITIALIZED; | 811 | params->state = RNDIS_INITIALIZED; |
827 | return rndis_init_response(configNr, | 812 | return rndis_init_response(params, (rndis_init_msg_type *)buf); |
828 | (rndis_init_msg_type *)buf); | ||
829 | 813 | ||
830 | case RNDIS_MSG_HALT: | 814 | case RNDIS_MSG_HALT: |
831 | pr_debug("%s: RNDIS_MSG_HALT\n", | 815 | pr_debug("%s: RNDIS_MSG_HALT\n", |
@@ -838,17 +822,16 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
838 | return 0; | 822 | return 0; |
839 | 823 | ||
840 | case RNDIS_MSG_QUERY: | 824 | case RNDIS_MSG_QUERY: |
841 | return rndis_query_response(configNr, | 825 | return rndis_query_response(params, |
842 | (rndis_query_msg_type *)buf); | 826 | (rndis_query_msg_type *)buf); |
843 | 827 | ||
844 | case RNDIS_MSG_SET: | 828 | case RNDIS_MSG_SET: |
845 | return rndis_set_response(configNr, | 829 | return rndis_set_response(params, (rndis_set_msg_type *)buf); |
846 | (rndis_set_msg_type *)buf); | ||
847 | 830 | ||
848 | case RNDIS_MSG_RESET: | 831 | case RNDIS_MSG_RESET: |
849 | pr_debug("%s: RNDIS_MSG_RESET\n", | 832 | pr_debug("%s: RNDIS_MSG_RESET\n", |
850 | __func__); | 833 | __func__); |
851 | return rndis_reset_response(configNr, | 834 | return rndis_reset_response(params, |
852 | (rndis_reset_msg_type *)buf); | 835 | (rndis_reset_msg_type *)buf); |
853 | 836 | ||
854 | case RNDIS_MSG_KEEPALIVE: | 837 | case RNDIS_MSG_KEEPALIVE: |
@@ -856,7 +839,7 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
856 | if (rndis_debug > 1) | 839 | if (rndis_debug > 1) |
857 | pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", | 840 | pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", |
858 | __func__); | 841 | __func__); |
859 | return rndis_keepalive_response(configNr, | 842 | return rndis_keepalive_response(params, |
860 | (rndis_keepalive_msg_type *) | 843 | (rndis_keepalive_msg_type *) |
861 | buf); | 844 | buf); |
862 | 845 | ||
@@ -876,71 +859,131 @@ int rndis_msg_parser(u8 configNr, u8 *buf) | |||
876 | } | 859 | } |
877 | EXPORT_SYMBOL_GPL(rndis_msg_parser); | 860 | EXPORT_SYMBOL_GPL(rndis_msg_parser); |
878 | 861 | ||
879 | int rndis_register(void (*resp_avail)(void *v), void *v) | 862 | static inline int rndis_get_nr(void) |
880 | { | 863 | { |
881 | u8 i; | 864 | return ida_simple_get(&rndis_ida, 0, 0, GFP_KERNEL); |
865 | } | ||
866 | |||
867 | static inline void rndis_put_nr(int nr) | ||
868 | { | ||
869 | ida_simple_remove(&rndis_ida, nr); | ||
870 | } | ||
871 | |||
872 | struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) | ||
873 | { | ||
874 | struct rndis_params *params; | ||
875 | int i; | ||
882 | 876 | ||
883 | if (!resp_avail) | 877 | if (!resp_avail) |
884 | return -EINVAL; | 878 | return ERR_PTR(-EINVAL); |
879 | |||
880 | i = rndis_get_nr(); | ||
881 | if (i < 0) { | ||
882 | pr_debug("failed\n"); | ||
883 | |||
884 | return ERR_PTR(-ENODEV); | ||
885 | } | ||
886 | |||
887 | params = kzalloc(sizeof(*params), GFP_KERNEL); | ||
888 | if (!params) { | ||
889 | rndis_put_nr(i); | ||
885 | 890 | ||
886 | for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { | 891 | return ERR_PTR(-ENOMEM); |
887 | if (!rndis_per_dev_params[i].used) { | 892 | } |
888 | rndis_per_dev_params[i].used = 1; | 893 | |
889 | rndis_per_dev_params[i].resp_avail = resp_avail; | 894 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
890 | rndis_per_dev_params[i].v = v; | 895 | { |
891 | pr_debug("%s: configNr = %d\n", __func__, i); | 896 | struct proc_dir_entry *proc_entry; |
892 | return i; | 897 | char name[20]; |
898 | |||
899 | sprintf(name, NAME_TEMPLATE, i); | ||
900 | proc_entry = proc_create_data(name, 0660, NULL, | ||
901 | &rndis_proc_fops, params); | ||
902 | if (!proc_entry) { | ||
903 | kfree(params); | ||
904 | rndis_put_nr(i); | ||
905 | |||
906 | return ERR_PTR(-EIO); | ||
893 | } | 907 | } |
894 | } | 908 | } |
895 | pr_debug("failed\n"); | 909 | #endif |
910 | |||
911 | params->confignr = i; | ||
912 | params->used = 1; | ||
913 | params->state = RNDIS_UNINITIALIZED; | ||
914 | params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED; | ||
915 | params->resp_avail = resp_avail; | ||
916 | params->v = v; | ||
917 | INIT_LIST_HEAD(&(params->resp_queue)); | ||
918 | pr_debug("%s: configNr = %d\n", __func__, i); | ||
896 | 919 | ||
897 | return -ENODEV; | 920 | return params; |
898 | } | 921 | } |
899 | EXPORT_SYMBOL_GPL(rndis_register); | 922 | EXPORT_SYMBOL_GPL(rndis_register); |
900 | 923 | ||
901 | void rndis_deregister(int configNr) | 924 | void rndis_deregister(struct rndis_params *params) |
902 | { | 925 | { |
926 | int i; | ||
927 | |||
903 | pr_debug("%s:\n", __func__); | 928 | pr_debug("%s:\n", __func__); |
904 | 929 | ||
905 | if (configNr >= RNDIS_MAX_CONFIGS) return; | 930 | if (!params) |
906 | rndis_per_dev_params[configNr].used = 0; | 931 | return; |
932 | |||
933 | i = params->confignr; | ||
934 | |||
935 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
936 | { | ||
937 | char name[20]; | ||
938 | |||
939 | sprintf(name, NAME_TEMPLATE, i); | ||
940 | remove_proc_entry(name, NULL); | ||
941 | } | ||
942 | #endif | ||
943 | |||
944 | kfree(params); | ||
945 | rndis_put_nr(i); | ||
907 | } | 946 | } |
908 | EXPORT_SYMBOL_GPL(rndis_deregister); | 947 | EXPORT_SYMBOL_GPL(rndis_deregister); |
909 | 948 | int rndis_set_param_dev(struct rndis_params *params, struct net_device *dev, | |
910 | int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) | 949 | u16 *cdc_filter) |
911 | { | 950 | { |
912 | pr_debug("%s:\n", __func__); | 951 | pr_debug("%s:\n", __func__); |
913 | if (!dev) | 952 | if (!dev) |
914 | return -EINVAL; | 953 | return -EINVAL; |
915 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 954 | if (!params) |
955 | return -1; | ||
916 | 956 | ||
917 | rndis_per_dev_params[configNr].dev = dev; | 957 | params->dev = dev; |
918 | rndis_per_dev_params[configNr].filter = cdc_filter; | 958 | params->filter = cdc_filter; |
919 | 959 | ||
920 | return 0; | 960 | return 0; |
921 | } | 961 | } |
922 | EXPORT_SYMBOL_GPL(rndis_set_param_dev); | 962 | EXPORT_SYMBOL_GPL(rndis_set_param_dev); |
923 | 963 | ||
924 | int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) | 964 | int rndis_set_param_vendor(struct rndis_params *params, u32 vendorID, |
965 | const char *vendorDescr) | ||
925 | { | 966 | { |
926 | pr_debug("%s:\n", __func__); | 967 | pr_debug("%s:\n", __func__); |
927 | if (!vendorDescr) return -1; | 968 | if (!vendorDescr) return -1; |
928 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 969 | if (!params) |
970 | return -1; | ||
929 | 971 | ||
930 | rndis_per_dev_params[configNr].vendorID = vendorID; | 972 | params->vendorID = vendorID; |
931 | rndis_per_dev_params[configNr].vendorDescr = vendorDescr; | 973 | params->vendorDescr = vendorDescr; |
932 | 974 | ||
933 | return 0; | 975 | return 0; |
934 | } | 976 | } |
935 | EXPORT_SYMBOL_GPL(rndis_set_param_vendor); | 977 | EXPORT_SYMBOL_GPL(rndis_set_param_vendor); |
936 | 978 | ||
937 | int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) | 979 | int rndis_set_param_medium(struct rndis_params *params, u32 medium, u32 speed) |
938 | { | 980 | { |
939 | pr_debug("%s: %u %u\n", __func__, medium, speed); | 981 | pr_debug("%s: %u %u\n", __func__, medium, speed); |
940 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 982 | if (!params) |
983 | return -1; | ||
941 | 984 | ||
942 | rndis_per_dev_params[configNr].medium = medium; | 985 | params->medium = medium; |
943 | rndis_per_dev_params[configNr].speed = speed; | 986 | params->speed = speed; |
944 | 987 | ||
945 | return 0; | 988 | return 0; |
946 | } | 989 | } |
@@ -961,13 +1004,12 @@ void rndis_add_hdr(struct sk_buff *skb) | |||
961 | } | 1004 | } |
962 | EXPORT_SYMBOL_GPL(rndis_add_hdr); | 1005 | EXPORT_SYMBOL_GPL(rndis_add_hdr); |
963 | 1006 | ||
964 | void rndis_free_response(int configNr, u8 *buf) | 1007 | void rndis_free_response(struct rndis_params *params, u8 *buf) |
965 | { | 1008 | { |
966 | rndis_resp_t *r; | 1009 | rndis_resp_t *r; |
967 | struct list_head *act, *tmp; | 1010 | struct list_head *act, *tmp; |
968 | 1011 | ||
969 | list_for_each_safe(act, tmp, | 1012 | list_for_each_safe(act, tmp, &(params->resp_queue)) |
970 | &(rndis_per_dev_params[configNr].resp_queue)) | ||
971 | { | 1013 | { |
972 | r = list_entry(act, rndis_resp_t, list); | 1014 | r = list_entry(act, rndis_resp_t, list); |
973 | if (r && r->buf == buf) { | 1015 | if (r && r->buf == buf) { |
@@ -978,15 +1020,14 @@ void rndis_free_response(int configNr, u8 *buf) | |||
978 | } | 1020 | } |
979 | EXPORT_SYMBOL_GPL(rndis_free_response); | 1021 | EXPORT_SYMBOL_GPL(rndis_free_response); |
980 | 1022 | ||
981 | u8 *rndis_get_next_response(int configNr, u32 *length) | 1023 | u8 *rndis_get_next_response(struct rndis_params *params, u32 *length) |
982 | { | 1024 | { |
983 | rndis_resp_t *r; | 1025 | rndis_resp_t *r; |
984 | struct list_head *act, *tmp; | 1026 | struct list_head *act, *tmp; |
985 | 1027 | ||
986 | if (!length) return NULL; | 1028 | if (!length) return NULL; |
987 | 1029 | ||
988 | list_for_each_safe(act, tmp, | 1030 | list_for_each_safe(act, tmp, &(params->resp_queue)) |
989 | &(rndis_per_dev_params[configNr].resp_queue)) | ||
990 | { | 1031 | { |
991 | r = list_entry(act, rndis_resp_t, list); | 1032 | r = list_entry(act, rndis_resp_t, list); |
992 | if (!r->send) { | 1033 | if (!r->send) { |
@@ -1000,7 +1041,7 @@ u8 *rndis_get_next_response(int configNr, u32 *length) | |||
1000 | } | 1041 | } |
1001 | EXPORT_SYMBOL_GPL(rndis_get_next_response); | 1042 | EXPORT_SYMBOL_GPL(rndis_get_next_response); |
1002 | 1043 | ||
1003 | static rndis_resp_t *rndis_add_response(int configNr, u32 length) | 1044 | static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length) |
1004 | { | 1045 | { |
1005 | rndis_resp_t *r; | 1046 | rndis_resp_t *r; |
1006 | 1047 | ||
@@ -1012,8 +1053,7 @@ static rndis_resp_t *rndis_add_response(int configNr, u32 length) | |||
1012 | r->length = length; | 1053 | r->length = length; |
1013 | r->send = 0; | 1054 | r->send = 0; |
1014 | 1055 | ||
1015 | list_add_tail(&r->list, | 1056 | list_add_tail(&r->list, &(params->resp_queue)); |
1016 | &(rndis_per_dev_params[configNr].resp_queue)); | ||
1017 | return r; | 1057 | return r; |
1018 | } | 1058 | } |
1019 | 1059 | ||
@@ -1103,11 +1143,11 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, | |||
1103 | break; | 1143 | break; |
1104 | case 'C': | 1144 | case 'C': |
1105 | case 'c': | 1145 | case 'c': |
1106 | rndis_signal_connect(p->confignr); | 1146 | rndis_signal_connect(p); |
1107 | break; | 1147 | break; |
1108 | case 'D': | 1148 | case 'D': |
1109 | case 'd': | 1149 | case 'd': |
1110 | rndis_signal_disconnect(p->confignr); | 1150 | rndis_signal_disconnect(p); |
1111 | break; | 1151 | break; |
1112 | default: | 1152 | default: |
1113 | if (fl_speed) p->speed = speed; | 1153 | if (fl_speed) p->speed = speed; |
@@ -1137,54 +1177,4 @@ static const struct file_operations rndis_proc_fops = { | |||
1137 | 1177 | ||
1138 | #define NAME_TEMPLATE "driver/rndis-%03d" | 1178 | #define NAME_TEMPLATE "driver/rndis-%03d" |
1139 | 1179 | ||
1140 | static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; | ||
1141 | |||
1142 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ | 1180 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ |
1143 | |||
1144 | |||
1145 | int rndis_init(void) | ||
1146 | { | ||
1147 | u8 i; | ||
1148 | |||
1149 | for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { | ||
1150 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
1151 | char name [20]; | ||
1152 | |||
1153 | sprintf(name, NAME_TEMPLATE, i); | ||
1154 | rndis_connect_state[i] = proc_create_data(name, 0660, NULL, | ||
1155 | &rndis_proc_fops, | ||
1156 | (void *)(rndis_per_dev_params + i)); | ||
1157 | if (!rndis_connect_state[i]) { | ||
1158 | pr_debug("%s: remove entries", __func__); | ||
1159 | while (i) { | ||
1160 | sprintf(name, NAME_TEMPLATE, --i); | ||
1161 | remove_proc_entry(name, NULL); | ||
1162 | } | ||
1163 | pr_debug("\n"); | ||
1164 | return -EIO; | ||
1165 | } | ||
1166 | #endif | ||
1167 | rndis_per_dev_params[i].confignr = i; | ||
1168 | rndis_per_dev_params[i].used = 0; | ||
1169 | rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; | ||
1170 | rndis_per_dev_params[i].media_state | ||
1171 | = RNDIS_MEDIA_STATE_DISCONNECTED; | ||
1172 | INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); | ||
1173 | } | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | void rndis_exit(void) | ||
1179 | { | ||
1180 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
1181 | u8 i; | ||
1182 | char name[20]; | ||
1183 | |||
1184 | for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { | ||
1185 | sprintf(name, NAME_TEMPLATE, i); | ||
1186 | remove_proc_entry(name, NULL); | ||
1187 | } | ||
1188 | #endif | ||
1189 | } | ||
1190 | |||
diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h index 0f4abb4c3775..ef92eb66d8ad 100644 --- a/drivers/usb/gadget/function/rndis.h +++ b/drivers/usb/gadget/function/rndis.h | |||
@@ -177,7 +177,7 @@ typedef struct rndis_resp_t | |||
177 | 177 | ||
178 | typedef struct rndis_params | 178 | typedef struct rndis_params |
179 | { | 179 | { |
180 | u8 confignr; | 180 | int confignr; |
181 | u8 used; | 181 | u8 used; |
182 | u16 saved_filter; | 182 | u16 saved_filter; |
183 | enum rndis_state state; | 183 | enum rndis_state state; |
@@ -197,24 +197,25 @@ typedef struct rndis_params | |||
197 | } rndis_params; | 197 | } rndis_params; |
198 | 198 | ||
199 | /* RNDIS Message parser and other useless functions */ | 199 | /* RNDIS Message parser and other useless functions */ |
200 | int rndis_msg_parser (u8 configNr, u8 *buf); | 200 | int rndis_msg_parser(struct rndis_params *params, u8 *buf); |
201 | int rndis_register(void (*resp_avail)(void *v), void *v); | 201 | struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v); |
202 | void rndis_deregister (int configNr); | 202 | void rndis_deregister(struct rndis_params *params); |
203 | int rndis_set_param_dev (u8 configNr, struct net_device *dev, | 203 | int rndis_set_param_dev(struct rndis_params *params, struct net_device *dev, |
204 | u16 *cdc_filter); | 204 | u16 *cdc_filter); |
205 | int rndis_set_param_vendor (u8 configNr, u32 vendorID, | 205 | int rndis_set_param_vendor(struct rndis_params *params, u32 vendorID, |
206 | const char *vendorDescr); | 206 | const char *vendorDescr); |
207 | int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); | 207 | int rndis_set_param_medium(struct rndis_params *params, u32 medium, |
208 | void rndis_add_hdr (struct sk_buff *skb); | 208 | u32 speed); |
209 | void rndis_add_hdr(struct sk_buff *skb); | ||
209 | int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, | 210 | int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, |
210 | struct sk_buff_head *list); | 211 | struct sk_buff_head *list); |
211 | u8 *rndis_get_next_response (int configNr, u32 *length); | 212 | u8 *rndis_get_next_response(struct rndis_params *params, u32 *length); |
212 | void rndis_free_response (int configNr, u8 *buf); | 213 | void rndis_free_response(struct rndis_params *params, u8 *buf); |
213 | 214 | ||
214 | void rndis_uninit (int configNr); | 215 | void rndis_uninit(struct rndis_params *params); |
215 | int rndis_signal_connect (int configNr); | 216 | int rndis_signal_connect(struct rndis_params *params); |
216 | int rndis_signal_disconnect (int configNr); | 217 | int rndis_signal_disconnect(struct rndis_params *params); |
217 | int rndis_state (int configNr); | 218 | int rndis_state(struct rndis_params *params); |
218 | extern void rndis_set_host_mac (int configNr, const u8 *addr); | 219 | extern void rndis_set_host_mac(struct rndis_params *params, const u8 *addr); |
219 | 220 | ||
220 | #endif /* _LINUX_RNDIS_H */ | 221 | #endif /* _LINUX_RNDIS_H */ |
diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index e902aa42a297..4eafd5050545 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h | |||
@@ -39,8 +39,6 @@ struct f_rndis_opts { | |||
39 | int refcnt; | 39 | int refcnt; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | int rndis_init(void); | ||
43 | void rndis_exit(void); | ||
44 | void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); | 42 | void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); |
45 | 43 | ||
46 | #endif /* U_RNDIS_H */ | 44 | #endif /* U_RNDIS_H */ |
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index ebe409b9e419..7d3bb6272e06 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h | |||
@@ -56,7 +56,6 @@ struct uvc_event | |||
56 | #include <linux/usb/composite.h> | 56 | #include <linux/usb/composite.h> |
57 | #include <linux/usb/gadget.h> | 57 | #include <linux/usb/gadget.h> |
58 | #include <linux/videodev2.h> | 58 | #include <linux/videodev2.h> |
59 | #include <linux/version.h> | ||
60 | #include <media/v4l2-fh.h> | 59 | #include <media/v4l2-fh.h> |
61 | #include <media/v4l2-device.h> | 60 | #include <media/v4l2-device.h> |
62 | 61 | ||
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 2030565c6789..f454c7af489c 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -769,9 +769,12 @@ ep_config (struct ep_data *data, const char *buf, size_t len) | |||
769 | if (data->dev->state == STATE_DEV_UNBOUND) { | 769 | if (data->dev->state == STATE_DEV_UNBOUND) { |
770 | value = -ENOENT; | 770 | value = -ENOENT; |
771 | goto gone; | 771 | goto gone; |
772 | } else if ((ep = data->ep) == NULL) { | 772 | } else { |
773 | value = -ENODEV; | 773 | ep = data->ep; |
774 | goto gone; | 774 | if (ep == NULL) { |
775 | value = -ENODEV; | ||
776 | goto gone; | ||
777 | } | ||
775 | } | 778 | } |
776 | switch (data->dev->gadget->speed) { | 779 | switch (data->dev->gadget->speed) { |
777 | case USB_SPEED_LOW: | 780 | case USB_SPEED_LOW: |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 351d48550c33..4095cce05e6a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -704,8 +704,8 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, | |||
704 | unsigned long flags; | 704 | unsigned long flags; |
705 | int ret; | 705 | int ret; |
706 | 706 | ||
707 | DBG(DBG_DMA, "%s: req l/%u d/%08x %c%c%c\n", | 707 | DBG(DBG_DMA, "%s: req l/%u d/%pad %c%c%c\n", |
708 | ep->ep.name, req->req.length, req->req.dma, | 708 | ep->ep.name, req->req.length, &req->req.dma, |
709 | req->req.zero ? 'Z' : 'z', | 709 | req->req.zero ? 'Z' : 'z', |
710 | req->req.short_not_ok ? 'S' : 's', | 710 | req->req.short_not_ok ? 'S' : 's', |
711 | req->req.no_interrupt ? 'I' : 'i'); | 711 | req->req.no_interrupt ? 'I' : 'i'); |
@@ -2203,7 +2203,7 @@ static int usba_udc_remove(struct platform_device *pdev) | |||
2203 | return 0; | 2203 | return 0; |
2204 | } | 2204 | } |
2205 | 2205 | ||
2206 | #ifdef CONFIG_PM | 2206 | #ifdef CONFIG_PM_SLEEP |
2207 | static int usba_udc_suspend(struct device *dev) | 2207 | static int usba_udc_suspend(struct device *dev) |
2208 | { | 2208 | { |
2209 | struct usba_udc *udc = dev_get_drvdata(dev); | 2209 | struct usba_udc *udc = dev_get_drvdata(dev); |
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 9871b90195ad..2bee912ca65b 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
@@ -123,6 +123,11 @@ static char *type_string(u8 bmAttributes) | |||
123 | #define valid_bit cpu_to_le32(BIT(VALID_BIT)) | 123 | #define valid_bit cpu_to_le32(BIT(VALID_BIT)) |
124 | #define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE)) | 124 | #define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE)) |
125 | 125 | ||
126 | static void ep_clear_seqnum(struct net2280_ep *ep); | ||
127 | static void stop_activity(struct net2280 *dev, | ||
128 | struct usb_gadget_driver *driver); | ||
129 | static void ep0_start(struct net2280 *dev); | ||
130 | |||
126 | /*-------------------------------------------------------------------------*/ | 131 | /*-------------------------------------------------------------------------*/ |
127 | static inline void enable_pciirqenb(struct net2280_ep *ep) | 132 | static inline void enable_pciirqenb(struct net2280_ep *ep) |
128 | { | 133 | { |
@@ -142,7 +147,9 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
142 | { | 147 | { |
143 | struct net2280 *dev; | 148 | struct net2280 *dev; |
144 | struct net2280_ep *ep; | 149 | struct net2280_ep *ep; |
145 | u32 max, tmp; | 150 | u32 max; |
151 | u32 tmp = 0; | ||
152 | u32 type; | ||
146 | unsigned long flags; | 153 | unsigned long flags; |
147 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; | 154 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; |
148 | int ret = 0; | 155 | int ret = 0; |
@@ -198,15 +205,29 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
198 | 205 | ||
199 | /* set type, direction, address; reset fifo counters */ | 206 | /* set type, direction, address; reset fifo counters */ |
200 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); | 207 | writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat); |
201 | tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 208 | |
202 | if (tmp == USB_ENDPOINT_XFER_INT) { | 209 | if ((dev->quirks & PLX_SUPERSPEED) && dev->enhanced_mode) { |
210 | tmp = readl(&ep->cfg->ep_cfg); | ||
211 | /* If USB ep number doesn't match hardware ep number */ | ||
212 | if ((tmp & 0xf) != usb_endpoint_num(desc)) { | ||
213 | ret = -EINVAL; | ||
214 | spin_unlock_irqrestore(&dev->lock, flags); | ||
215 | goto print_err; | ||
216 | } | ||
217 | if (ep->is_in) | ||
218 | tmp &= ~USB3380_EP_CFG_MASK_IN; | ||
219 | else | ||
220 | tmp &= ~USB3380_EP_CFG_MASK_OUT; | ||
221 | } | ||
222 | type = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
223 | if (type == USB_ENDPOINT_XFER_INT) { | ||
203 | /* erratum 0105 workaround prevents hs NYET */ | 224 | /* erratum 0105 workaround prevents hs NYET */ |
204 | if (dev->chiprev == 0100 && | 225 | if (dev->chiprev == 0100 && |
205 | dev->gadget.speed == USB_SPEED_HIGH && | 226 | dev->gadget.speed == USB_SPEED_HIGH && |
206 | !(desc->bEndpointAddress & USB_DIR_IN)) | 227 | !(desc->bEndpointAddress & USB_DIR_IN)) |
207 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE), | 228 | writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE), |
208 | &ep->regs->ep_rsp); | 229 | &ep->regs->ep_rsp); |
209 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | 230 | } else if (type == USB_ENDPOINT_XFER_BULK) { |
210 | /* catch some particularly blatant driver bugs */ | 231 | /* catch some particularly blatant driver bugs */ |
211 | if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) || | 232 | if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) || |
212 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || | 233 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || |
@@ -216,10 +237,10 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
216 | goto print_err; | 237 | goto print_err; |
217 | } | 238 | } |
218 | } | 239 | } |
219 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC); | 240 | ep->is_iso = (type == USB_ENDPOINT_XFER_ISOC); |
220 | /* Enable this endpoint */ | 241 | /* Enable this endpoint */ |
221 | if (dev->quirks & PLX_LEGACY) { | 242 | if (dev->quirks & PLX_LEGACY) { |
222 | tmp <<= ENDPOINT_TYPE; | 243 | tmp |= type << ENDPOINT_TYPE; |
223 | tmp |= desc->bEndpointAddress; | 244 | tmp |= desc->bEndpointAddress; |
224 | /* default full fifo lines */ | 245 | /* default full fifo lines */ |
225 | tmp |= (4 << ENDPOINT_BYTE_COUNT); | 246 | tmp |= (4 << ENDPOINT_BYTE_COUNT); |
@@ -228,17 +249,17 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
228 | } else { | 249 | } else { |
229 | /* In Legacy mode, only OUT endpoints are used */ | 250 | /* In Legacy mode, only OUT endpoints are used */ |
230 | if (dev->enhanced_mode && ep->is_in) { | 251 | if (dev->enhanced_mode && ep->is_in) { |
231 | tmp <<= IN_ENDPOINT_TYPE; | 252 | tmp |= type << IN_ENDPOINT_TYPE; |
232 | tmp |= BIT(IN_ENDPOINT_ENABLE); | 253 | tmp |= BIT(IN_ENDPOINT_ENABLE); |
233 | /* Not applicable to Legacy */ | ||
234 | tmp |= BIT(ENDPOINT_DIRECTION); | ||
235 | } else { | 254 | } else { |
236 | tmp <<= OUT_ENDPOINT_TYPE; | 255 | tmp |= type << OUT_ENDPOINT_TYPE; |
237 | tmp |= BIT(OUT_ENDPOINT_ENABLE); | 256 | tmp |= BIT(OUT_ENDPOINT_ENABLE); |
238 | tmp |= (ep->is_in << ENDPOINT_DIRECTION); | 257 | tmp |= (ep->is_in << ENDPOINT_DIRECTION); |
239 | } | 258 | } |
240 | 259 | ||
241 | tmp |= usb_endpoint_num(desc); | 260 | tmp |= (4 << ENDPOINT_BYTE_COUNT); |
261 | if (!dev->enhanced_mode) | ||
262 | tmp |= usb_endpoint_num(desc); | ||
242 | tmp |= (ep->ep.maxburst << MAX_BURST_SIZE); | 263 | tmp |= (ep->ep.maxburst << MAX_BURST_SIZE); |
243 | } | 264 | } |
244 | 265 | ||
@@ -256,6 +277,8 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
256 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | 277 | BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); |
257 | } | 278 | } |
258 | 279 | ||
280 | if (dev->quirks & PLX_SUPERSPEED) | ||
281 | ep_clear_seqnum(ep); | ||
259 | writel(tmp, &ep->cfg->ep_cfg); | 282 | writel(tmp, &ep->cfg->ep_cfg); |
260 | 283 | ||
261 | /* enable irqs */ | 284 | /* enable irqs */ |
@@ -441,6 +464,13 @@ static void ep_reset_338x(struct net2280_regs __iomem *regs, | |||
441 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | | 464 | BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) | |
442 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | | 465 | BIT(DATA_OUT_PING_TOKEN_INTERRUPT) | |
443 | BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat); | 466 | BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat); |
467 | |||
468 | tmp = readl(&ep->cfg->ep_cfg); | ||
469 | if (ep->is_in) | ||
470 | tmp &= ~USB3380_EP_CFG_MASK_IN; | ||
471 | else | ||
472 | tmp &= ~USB3380_EP_CFG_MASK_OUT; | ||
473 | writel(tmp, &ep->cfg->ep_cfg); | ||
444 | } | 474 | } |
445 | 475 | ||
446 | static void nuke(struct net2280_ep *); | 476 | static void nuke(struct net2280_ep *); |
@@ -1468,11 +1498,14 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | |||
1468 | spin_lock_irqsave(&dev->lock, flags); | 1498 | spin_lock_irqsave(&dev->lock, flags); |
1469 | tmp = readl(&dev->usb->usbctl); | 1499 | tmp = readl(&dev->usb->usbctl); |
1470 | dev->softconnect = (is_on != 0); | 1500 | dev->softconnect = (is_on != 0); |
1471 | if (is_on) | 1501 | if (is_on) { |
1472 | tmp |= BIT(USB_DETECT_ENABLE); | 1502 | ep0_start(dev); |
1473 | else | 1503 | writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); |
1474 | tmp &= ~BIT(USB_DETECT_ENABLE); | 1504 | } else { |
1475 | writel(tmp, &dev->usb->usbctl); | 1505 | writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); |
1506 | stop_activity(dev, dev->driver); | ||
1507 | } | ||
1508 | |||
1476 | spin_unlock_irqrestore(&dev->lock, flags); | 1509 | spin_unlock_irqrestore(&dev->lock, flags); |
1477 | 1510 | ||
1478 | return 0; | 1511 | return 0; |
@@ -1860,8 +1893,8 @@ static void defect7374_enable_data_eps_zero(struct net2280 *dev) | |||
1860 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | | 1893 | tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) | |
1861 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | | 1894 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | |
1862 | ((dev->enhanced_mode) ? | 1895 | ((dev->enhanced_mode) ? |
1863 | BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) | | 1896 | BIT(OUT_ENDPOINT_ENABLE) | BIT(IN_ENDPOINT_ENABLE) : |
1864 | BIT(IN_ENDPOINT_ENABLE)); | 1897 | BIT(ENDPOINT_ENABLE))); |
1865 | 1898 | ||
1866 | for (i = 1; i < 5; i++) | 1899 | for (i = 1; i < 5; i++) |
1867 | writel(tmp, &dev->ep[i].cfg->ep_cfg); | 1900 | writel(tmp, &dev->ep[i].cfg->ep_cfg); |
@@ -1975,9 +2008,15 @@ static void usb_reset_338x(struct net2280 *dev) | |||
1975 | /* clear old dma and irq state */ | 2008 | /* clear old dma and irq state */ |
1976 | for (tmp = 0; tmp < 4; tmp++) { | 2009 | for (tmp = 0; tmp < 4; tmp++) { |
1977 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | 2010 | struct net2280_ep *ep = &dev->ep[tmp + 1]; |
2011 | struct net2280_dma_regs __iomem *dma; | ||
1978 | 2012 | ||
1979 | if (ep->dma) | 2013 | if (ep->dma) { |
1980 | abort_dma(ep); | 2014 | abort_dma(ep); |
2015 | } else { | ||
2016 | dma = &dev->dma[tmp]; | ||
2017 | writel(BIT(DMA_ABORT), &dma->dmastat); | ||
2018 | writel(0, &dma->dmactl); | ||
2019 | } | ||
1981 | } | 2020 | } |
1982 | 2021 | ||
1983 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); | 2022 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); |
@@ -2065,6 +2104,12 @@ static void usb_reinit_338x(struct net2280 *dev) | |||
2065 | 2104 | ||
2066 | if (dev->enhanced_mode) { | 2105 | if (dev->enhanced_mode) { |
2067 | ep->cfg = &dev->epregs[ne[i]]; | 2106 | ep->cfg = &dev->epregs[ne[i]]; |
2107 | /* | ||
2108 | * Set USB endpoint number, hardware allows same number | ||
2109 | * in both directions. | ||
2110 | */ | ||
2111 | if (i > 0 && i < 5) | ||
2112 | writel(ne[i], &ep->cfg->ep_cfg); | ||
2068 | ep->regs = (struct net2280_ep_regs __iomem *) | 2113 | ep->regs = (struct net2280_ep_regs __iomem *) |
2069 | (((void __iomem *)&dev->epregs[ne[i]]) + | 2114 | (((void __iomem *)&dev->epregs[ne[i]]) + |
2070 | ep_reg_addr[i]); | 2115 | ep_reg_addr[i]); |
@@ -2874,6 +2919,26 @@ next_endpoints3: | |||
2874 | return; | 2919 | return; |
2875 | } | 2920 | } |
2876 | 2921 | ||
2922 | static void usb338x_handle_ep_intr(struct net2280 *dev, u32 stat0) | ||
2923 | { | ||
2924 | u32 index; | ||
2925 | u32 bit; | ||
2926 | |||
2927 | for (index = 0; index < ARRAY_SIZE(ep_bit); index++) { | ||
2928 | bit = BIT(ep_bit[index]); | ||
2929 | |||
2930 | if (!stat0) | ||
2931 | break; | ||
2932 | |||
2933 | if (!(stat0 & bit)) | ||
2934 | continue; | ||
2935 | |||
2936 | stat0 &= ~bit; | ||
2937 | |||
2938 | handle_ep_small(&dev->ep[index]); | ||
2939 | } | ||
2940 | } | ||
2941 | |||
2877 | static void handle_stat0_irqs(struct net2280 *dev, u32 stat) | 2942 | static void handle_stat0_irqs(struct net2280 *dev, u32 stat) |
2878 | { | 2943 | { |
2879 | struct net2280_ep *ep; | 2944 | struct net2280_ep *ep; |
@@ -3098,20 +3163,31 @@ do_stall: | |||
3098 | #undef w_length | 3163 | #undef w_length |
3099 | 3164 | ||
3100 | next_endpoints: | 3165 | next_endpoints: |
3101 | /* endpoint data irq ? */ | 3166 | if ((dev->quirks & PLX_SUPERSPEED) && dev->enhanced_mode) { |
3102 | scratch = stat & 0x7f; | 3167 | u32 mask = (BIT(ENDPOINT_0_INTERRUPT) | |
3103 | stat &= ~0x7f; | 3168 | USB3380_IRQSTAT0_EP_INTR_MASK_IN | |
3104 | for (num = 0; scratch; num++) { | 3169 | USB3380_IRQSTAT0_EP_INTR_MASK_OUT); |
3105 | u32 t; | 3170 | |
3106 | 3171 | if (stat & mask) { | |
3107 | /* do this endpoint's FIFO and queue need tending? */ | 3172 | usb338x_handle_ep_intr(dev, stat & mask); |
3108 | t = BIT(num); | 3173 | stat &= ~mask; |
3109 | if ((scratch & t) == 0) | 3174 | } |
3110 | continue; | 3175 | } else { |
3111 | scratch ^= t; | 3176 | /* endpoint data irq ? */ |
3177 | scratch = stat & 0x7f; | ||
3178 | stat &= ~0x7f; | ||
3179 | for (num = 0; scratch; num++) { | ||
3180 | u32 t; | ||
3181 | |||
3182 | /* do this endpoint's FIFO and queue need tending? */ | ||
3183 | t = BIT(num); | ||
3184 | if ((scratch & t) == 0) | ||
3185 | continue; | ||
3186 | scratch ^= t; | ||
3112 | 3187 | ||
3113 | ep = &dev->ep[num]; | 3188 | ep = &dev->ep[num]; |
3114 | handle_ep_small(ep); | 3189 | handle_ep_small(ep); |
3190 | } | ||
3115 | } | 3191 | } |
3116 | 3192 | ||
3117 | if (stat) | 3193 | if (stat) |
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 99fd9a5667df..5d9aa81969b4 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c | |||
@@ -92,40 +92,38 @@ static struct s3c2410_udc_mach_info *udc_info; | |||
92 | 92 | ||
93 | static uint32_t s3c2410_ticks = 0; | 93 | static uint32_t s3c2410_ticks = 0; |
94 | 94 | ||
95 | static int dprintk(int level, const char *fmt, ...) | 95 | __printf(2, 3) |
96 | static void dprintk(int level, const char *fmt, ...) | ||
96 | { | 97 | { |
97 | static char printk_buf[1024]; | ||
98 | static long prevticks; | 98 | static long prevticks; |
99 | static int invocation; | 99 | static int invocation; |
100 | struct va_format vaf; | ||
100 | va_list args; | 101 | va_list args; |
101 | int len; | ||
102 | 102 | ||
103 | if (level > USB_S3C2410_DEBUG_LEVEL) | 103 | if (level > USB_S3C2410_DEBUG_LEVEL) |
104 | return 0; | 104 | return; |
105 | |||
106 | va_start(args, fmt); | ||
107 | |||
108 | vaf.fmt = fmt; | ||
109 | vaf.va = &args; | ||
105 | 110 | ||
106 | if (s3c2410_ticks != prevticks) { | 111 | if (s3c2410_ticks != prevticks) { |
107 | prevticks = s3c2410_ticks; | 112 | prevticks = s3c2410_ticks; |
108 | invocation = 0; | 113 | invocation = 0; |
109 | } | 114 | } |
110 | 115 | ||
111 | len = scnprintf(printk_buf, | 116 | pr_debug("%1lu.%02d USB: %pV", prevticks, invocation++, &vaf); |
112 | sizeof(printk_buf), "%1lu.%02d USB: ", | ||
113 | prevticks, invocation++); | ||
114 | 117 | ||
115 | va_start(args, fmt); | ||
116 | len = vscnprintf(printk_buf+len, | ||
117 | sizeof(printk_buf)-len, fmt, args); | ||
118 | va_end(args); | 118 | va_end(args); |
119 | |||
120 | pr_debug("%s", printk_buf); | ||
121 | return len; | ||
122 | } | 119 | } |
123 | #else | 120 | #else |
124 | static int dprintk(int level, const char *fmt, ...) | 121 | __printf(2, 3) |
122 | static void dprintk(int level, const char *fmt, ...) | ||
125 | { | 123 | { |
126 | return 0; | ||
127 | } | 124 | } |
128 | #endif | 125 | #endif |
126 | |||
129 | static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) | 127 | static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) |
130 | { | 128 | { |
131 | u32 addr_reg, pwr_reg, ep_int_reg, usb_int_reg; | 129 | u32 addr_reg, pwr_reg, ep_int_reg, usb_int_reg; |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 197a6a3e613b..547cee83400b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -137,7 +137,7 @@ config XPS_USB_HCD_XILINX | |||
137 | devices only. | 137 | devices only. |
138 | 138 | ||
139 | config USB_EHCI_FSL | 139 | config USB_EHCI_FSL |
140 | bool "Support for Freescale PPC on-chip EHCI USB controller" | 140 | tristate "Support for Freescale PPC on-chip EHCI USB controller" |
141 | depends on FSL_SOC | 141 | depends on FSL_SOC |
142 | select USB_EHCI_ROOT_HUB_TT | 142 | select USB_EHCI_ROOT_HUB_TT |
143 | select USB_FSL_MPH_DR_OF if OF | 143 | select USB_FSL_MPH_DR_OF if OF |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 65b0b6a58599..754efaa8ccf8 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -24,7 +24,9 @@ endif | |||
24 | 24 | ||
25 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 25 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
26 | 26 | ||
27 | obj-$(CONFIG_PCI) += pci-quirks.o | 27 | ifneq ($(CONFIG_USB), ) |
28 | obj-$(CONFIG_PCI) += pci-quirks.o | ||
29 | endif | ||
28 | 30 | ||
29 | obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o | 31 | obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o |
30 | obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o | 32 | obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o |
@@ -70,6 +72,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o | |||
70 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o | 72 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o |
71 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o | 73 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o |
72 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o | 74 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o |
75 | obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o | ||
73 | obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o | 76 | obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o |
74 | obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o | 77 | obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o |
75 | obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o | 78 | obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 524cbf26d992..b26b96e25a13 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -628,7 +628,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
628 | unsigned i; | 628 | unsigned i; |
629 | __hc32 tag; | 629 | __hc32 tag; |
630 | 630 | ||
631 | if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC))) | 631 | seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC); |
632 | if (!seen) | ||
632 | return 0; | 633 | return 0; |
633 | seen_count = 0; | 634 | seen_count = 0; |
634 | 635 | ||
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index ab4eee3df97a..5352e74b92e2 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2005-2009 MontaVista Software, Inc. | 2 | * Copyright 2005-2009 MontaVista Software, Inc. |
3 | * Copyright 2008,2012 Freescale Semiconductor, Inc. | 3 | * Copyright 2008,2012,2015 Freescale Semiconductor, Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the | 6 | * under the terms of the GNU General Public License as published by the |
@@ -24,29 +24,38 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | 28 | #include <linux/types.h> |
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
32 | #include <linux/usb.h> | ||
33 | #include <linux/usb/ehci_def.h> | ||
34 | #include <linux/usb/hcd.h> | ||
35 | #include <linux/usb/otg.h> | ||
31 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
32 | #include <linux/fsl_devices.h> | 37 | #include <linux/fsl_devices.h> |
33 | 38 | ||
39 | #include "ehci.h" | ||
34 | #include "ehci-fsl.h" | 40 | #include "ehci-fsl.h" |
35 | 41 | ||
42 | #define DRIVER_DESC "Freescale EHCI Host controller driver" | ||
43 | #define DRV_NAME "ehci-fsl" | ||
44 | |||
45 | static struct hc_driver __read_mostly fsl_ehci_hc_driver; | ||
46 | |||
36 | /* configure so an HC device and id are always provided */ | 47 | /* configure so an HC device and id are always provided */ |
37 | /* always called with process context; sleeping is OK */ | 48 | /* always called with process context; sleeping is OK */ |
38 | 49 | ||
39 | /** | 50 | /* |
40 | * usb_hcd_fsl_probe - initialize FSL-based HCDs | 51 | * fsl_ehci_drv_probe - initialize FSL-based HCDs |
41 | * @drvier: Driver to be used for this HCD | ||
42 | * @pdev: USB Host Controller being probed | 52 | * @pdev: USB Host Controller being probed |
43 | * Context: !in_interrupt() | 53 | * Context: !in_interrupt() |
44 | * | 54 | * |
45 | * Allocates basic resources for this USB host controller. | 55 | * Allocates basic resources for this USB host controller. |
46 | * | 56 | * |
47 | */ | 57 | */ |
48 | static int usb_hcd_fsl_probe(const struct hc_driver *driver, | 58 | static int fsl_ehci_drv_probe(struct platform_device *pdev) |
49 | struct platform_device *pdev) | ||
50 | { | 59 | { |
51 | struct fsl_usb2_platform_data *pdata; | 60 | struct fsl_usb2_platform_data *pdata; |
52 | struct usb_hcd *hcd; | 61 | struct usb_hcd *hcd; |
@@ -86,7 +95,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
86 | } | 95 | } |
87 | irq = res->start; | 96 | irq = res->start; |
88 | 97 | ||
89 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | 98 | hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev, |
99 | dev_name(&pdev->dev)); | ||
90 | if (!hcd) { | 100 | if (!hcd) { |
91 | retval = -ENOMEM; | 101 | retval = -ENOMEM; |
92 | goto err1; | 102 | goto err1; |
@@ -159,38 +169,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
159 | return retval; | 169 | return retval; |
160 | } | 170 | } |
161 | 171 | ||
162 | /* may be called without controller electrically present */ | ||
163 | /* may be called with controller, bus, and devices active */ | ||
164 | |||
165 | /** | ||
166 | * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs | ||
167 | * @dev: USB Host Controller being removed | ||
168 | * Context: !in_interrupt() | ||
169 | * | ||
170 | * Reverses the effect of usb_hcd_fsl_probe(). | ||
171 | * | ||
172 | */ | ||
173 | static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | ||
174 | struct platform_device *pdev) | ||
175 | { | ||
176 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
177 | |||
178 | if (!IS_ERR_OR_NULL(hcd->usb_phy)) { | ||
179 | otg_set_host(hcd->usb_phy->otg, NULL); | ||
180 | usb_put_phy(hcd->usb_phy); | ||
181 | } | ||
182 | |||
183 | usb_remove_hcd(hcd); | ||
184 | |||
185 | /* | ||
186 | * do platform specific un-initialization: | ||
187 | * release iomux pins, disable clock, etc. | ||
188 | */ | ||
189 | if (pdata->exit) | ||
190 | pdata->exit(pdev); | ||
191 | usb_put_hcd(hcd); | ||
192 | } | ||
193 | |||
194 | static int ehci_fsl_setup_phy(struct usb_hcd *hcd, | 172 | static int ehci_fsl_setup_phy(struct usb_hcd *hcd, |
195 | enum fsl_usb2_phy_modes phy_mode, | 173 | enum fsl_usb2_phy_modes phy_mode, |
196 | unsigned int port_offset) | 174 | unsigned int port_offset) |
@@ -636,79 +614,77 @@ static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) | |||
636 | #define ehci_start_port_reset NULL | 614 | #define ehci_start_port_reset NULL |
637 | #endif /* CONFIG_USB_OTG */ | 615 | #endif /* CONFIG_USB_OTG */ |
638 | 616 | ||
617 | static struct ehci_driver_overrides ehci_fsl_overrides __initdata = { | ||
618 | .extra_priv_size = sizeof(struct ehci_fsl), | ||
619 | .reset = ehci_fsl_setup, | ||
620 | }; | ||
639 | 621 | ||
640 | static const struct hc_driver ehci_fsl_hc_driver = { | 622 | /** |
641 | .description = hcd_name, | 623 | * fsl_ehci_drv_remove - shutdown processing for FSL-based HCDs |
642 | .product_desc = "Freescale On-Chip EHCI Host Controller", | 624 | * @dev: USB Host Controller being removed |
643 | .hcd_priv_size = sizeof(struct ehci_fsl), | 625 | * Context: !in_interrupt() |
626 | * | ||
627 | * Reverses the effect of usb_hcd_fsl_probe(). | ||
628 | * | ||
629 | */ | ||
644 | 630 | ||
645 | /* | 631 | static int fsl_ehci_drv_remove(struct platform_device *pdev) |
646 | * generic hardware linkage | 632 | { |
647 | */ | 633 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); |
648 | .irq = ehci_irq, | 634 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
649 | .flags = HCD_USB2 | HCD_MEMORY | HCD_BH, | ||
650 | 635 | ||
651 | /* | 636 | if (!IS_ERR_OR_NULL(hcd->usb_phy)) { |
652 | * basic lifecycle operations | 637 | otg_set_host(hcd->usb_phy->otg, NULL); |
653 | */ | 638 | usb_put_phy(hcd->usb_phy); |
654 | .reset = ehci_fsl_setup, | 639 | } |
655 | .start = ehci_run, | ||
656 | .stop = ehci_stop, | ||
657 | .shutdown = ehci_shutdown, | ||
658 | 640 | ||
659 | /* | 641 | usb_remove_hcd(hcd); |
660 | * managing i/o requests and associated device resources | ||
661 | */ | ||
662 | .urb_enqueue = ehci_urb_enqueue, | ||
663 | .urb_dequeue = ehci_urb_dequeue, | ||
664 | .endpoint_disable = ehci_endpoint_disable, | ||
665 | .endpoint_reset = ehci_endpoint_reset, | ||
666 | 642 | ||
667 | /* | 643 | /* |
668 | * scheduling support | 644 | * do platform specific un-initialization: |
645 | * release iomux pins, disable clock, etc. | ||
669 | */ | 646 | */ |
670 | .get_frame_number = ehci_get_frame, | 647 | if (pdata->exit) |
648 | pdata->exit(pdev); | ||
649 | usb_put_hcd(hcd); | ||
671 | 650 | ||
672 | /* | 651 | return 0; |
673 | * root hub support | 652 | } |
674 | */ | 653 | |
675 | .hub_status_data = ehci_hub_status_data, | 654 | static struct platform_driver ehci_fsl_driver = { |
676 | .hub_control = ehci_hub_control, | 655 | .probe = fsl_ehci_drv_probe, |
677 | .bus_suspend = ehci_bus_suspend, | 656 | .remove = fsl_ehci_drv_remove, |
678 | .bus_resume = ehci_bus_resume, | 657 | .shutdown = usb_hcd_platform_shutdown, |
679 | .start_port_reset = ehci_start_port_reset, | 658 | .driver = { |
680 | .relinquish_port = ehci_relinquish_port, | 659 | .name = "fsl-ehci", |
681 | .port_handed_over = ehci_port_handed_over, | 660 | .pm = EHCI_FSL_PM_OPS, |
682 | 661 | }, | |
683 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
684 | }; | 662 | }; |
685 | 663 | ||
686 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 664 | static int __init ehci_fsl_init(void) |
687 | { | 665 | { |
688 | if (usb_disabled()) | 666 | if (usb_disabled()) |
689 | return -ENODEV; | 667 | return -ENODEV; |
690 | 668 | ||
691 | /* FIXME we only want one one probe() not two */ | 669 | pr_info(DRV_NAME ": " DRIVER_DESC "\n"); |
692 | return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev); | ||
693 | } | ||
694 | 670 | ||
695 | static int ehci_fsl_drv_remove(struct platform_device *pdev) | 671 | ehci_init_driver(&fsl_ehci_hc_driver, &ehci_fsl_overrides); |
696 | { | ||
697 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
698 | 672 | ||
699 | /* FIXME we only want one one remove() not two */ | 673 | fsl_ehci_hc_driver.product_desc = |
700 | usb_hcd_fsl_remove(hcd, pdev); | 674 | "Freescale On-Chip EHCI Host Controller"; |
701 | return 0; | 675 | fsl_ehci_hc_driver.start_port_reset = ehci_start_port_reset; |
676 | |||
677 | |||
678 | return platform_driver_register(&ehci_fsl_driver); | ||
702 | } | 679 | } |
680 | module_init(ehci_fsl_init); | ||
703 | 681 | ||
704 | MODULE_ALIAS("platform:fsl-ehci"); | 682 | static void __exit ehci_fsl_cleanup(void) |
683 | { | ||
684 | platform_driver_unregister(&ehci_fsl_driver); | ||
685 | } | ||
686 | module_exit(ehci_fsl_cleanup); | ||
705 | 687 | ||
706 | static struct platform_driver ehci_fsl_driver = { | 688 | MODULE_DESCRIPTION(DRIVER_DESC); |
707 | .probe = ehci_fsl_drv_probe, | 689 | MODULE_LICENSE("GPL"); |
708 | .remove = ehci_fsl_drv_remove, | 690 | MODULE_ALIAS("platform:" DRV_NAME); |
709 | .shutdown = usb_hcd_platform_shutdown, | ||
710 | .driver = { | ||
711 | .name = "fsl-ehci", | ||
712 | .pm = EHCI_FSL_PM_OPS, | ||
713 | }, | ||
714 | }; | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f4d88dfb26a7..c63d82c91f10 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -239,7 +239,7 @@ static void tdi_reset (struct ehci_hcd *ehci) | |||
239 | * Reset a non-running (STS_HALT == 1) controller. | 239 | * Reset a non-running (STS_HALT == 1) controller. |
240 | * Must be called with interrupts enabled and the lock not held. | 240 | * Must be called with interrupts enabled and the lock not held. |
241 | */ | 241 | */ |
242 | static int ehci_reset (struct ehci_hcd *ehci) | 242 | int ehci_reset(struct ehci_hcd *ehci) |
243 | { | 243 | { |
244 | int retval; | 244 | int retval; |
245 | u32 command = ehci_readl(ehci, &ehci->regs->command); | 245 | u32 command = ehci_readl(ehci, &ehci->regs->command); |
@@ -275,6 +275,7 @@ static int ehci_reset (struct ehci_hcd *ehci) | |||
275 | ehci->resuming_ports = 0; | 275 | ehci->resuming_ports = 0; |
276 | return retval; | 276 | return retval; |
277 | } | 277 | } |
278 | EXPORT_SYMBOL_GPL(ehci_reset); | ||
278 | 279 | ||
279 | /* | 280 | /* |
280 | * Idle the controller (turn off the schedules). | 281 | * Idle the controller (turn off the schedules). |
@@ -1250,11 +1251,6 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
1250 | MODULE_AUTHOR (DRIVER_AUTHOR); | 1251 | MODULE_AUTHOR (DRIVER_AUTHOR); |
1251 | MODULE_LICENSE ("GPL"); | 1252 | MODULE_LICENSE ("GPL"); |
1252 | 1253 | ||
1253 | #ifdef CONFIG_USB_EHCI_FSL | ||
1254 | #include "ehci-fsl.c" | ||
1255 | #define PLATFORM_DRIVER ehci_fsl_driver | ||
1256 | #endif | ||
1257 | |||
1258 | #ifdef CONFIG_USB_EHCI_SH | 1254 | #ifdef CONFIG_USB_EHCI_SH |
1259 | #include "ehci-sh.c" | 1255 | #include "ehci-sh.c" |
1260 | #define PLATFORM_DRIVER ehci_hcd_sh_driver | 1256 | #define PLATFORM_DRIVER ehci_hcd_sh_driver |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 69208447d213..22abb6830dfa 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -155,7 +155,7 @@ static int ehci_port_change(struct ehci_hcd *ehci) | |||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
157 | 157 | ||
158 | static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | 158 | void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, |
159 | bool suspending, bool do_wakeup) | 159 | bool suspending, bool do_wakeup) |
160 | { | 160 | { |
161 | int port; | 161 | int port; |
@@ -220,6 +220,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | |||
220 | 220 | ||
221 | spin_unlock_irq(&ehci->lock); | 221 | spin_unlock_irq(&ehci->lock); |
222 | } | 222 | } |
223 | EXPORT_SYMBOL_GPL(ehci_adjust_port_wakeup_flags); | ||
223 | 224 | ||
224 | static int ehci_bus_suspend (struct usb_hcd *hcd) | 225 | static int ehci_bus_suspend (struct usb_hcd *hcd) |
225 | { | 226 | { |
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index d8a75a51d6d4..2593def13cea 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c | |||
@@ -88,15 +88,13 @@ static int ehci_platform_power_on(struct platform_device *dev) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 90 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
91 | if (priv->phys[phy_num]) { | 91 | ret = phy_init(priv->phys[phy_num]); |
92 | ret = phy_init(priv->phys[phy_num]); | 92 | if (ret) |
93 | if (ret) | 93 | goto err_exit_phy; |
94 | goto err_exit_phy; | 94 | ret = phy_power_on(priv->phys[phy_num]); |
95 | ret = phy_power_on(priv->phys[phy_num]); | 95 | if (ret) { |
96 | if (ret) { | 96 | phy_exit(priv->phys[phy_num]); |
97 | phy_exit(priv->phys[phy_num]); | 97 | goto err_exit_phy; |
98 | goto err_exit_phy; | ||
99 | } | ||
100 | } | 98 | } |
101 | } | 99 | } |
102 | 100 | ||
@@ -104,10 +102,8 @@ static int ehci_platform_power_on(struct platform_device *dev) | |||
104 | 102 | ||
105 | err_exit_phy: | 103 | err_exit_phy: |
106 | while (--phy_num >= 0) { | 104 | while (--phy_num >= 0) { |
107 | if (priv->phys[phy_num]) { | 105 | phy_power_off(priv->phys[phy_num]); |
108 | phy_power_off(priv->phys[phy_num]); | 106 | phy_exit(priv->phys[phy_num]); |
109 | phy_exit(priv->phys[phy_num]); | ||
110 | } | ||
111 | } | 107 | } |
112 | err_disable_clks: | 108 | err_disable_clks: |
113 | while (--clk >= 0) | 109 | while (--clk >= 0) |
@@ -123,10 +119,8 @@ static void ehci_platform_power_off(struct platform_device *dev) | |||
123 | int clk, phy_num; | 119 | int clk, phy_num; |
124 | 120 | ||
125 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 121 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
126 | if (priv->phys[phy_num]) { | 122 | phy_power_off(priv->phys[phy_num]); |
127 | phy_power_off(priv->phys[phy_num]); | 123 | phy_exit(priv->phys[phy_num]); |
128 | phy_exit(priv->phys[phy_num]); | ||
129 | } | ||
130 | } | 124 | } |
131 | 125 | ||
132 | for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) | 126 | for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) |
@@ -154,7 +148,6 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
154 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); | 148 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); |
155 | struct ehci_platform_priv *priv; | 149 | struct ehci_platform_priv *priv; |
156 | struct ehci_hcd *ehci; | 150 | struct ehci_hcd *ehci; |
157 | const char *phy_name; | ||
158 | int err, irq, phy_num, clk = 0; | 151 | int err, irq, phy_num, clk = 0; |
159 | 152 | ||
160 | if (usb_disabled()) | 153 | if (usb_disabled()) |
@@ -202,38 +195,28 @@ static int ehci_platform_probe(struct platform_device *dev) | |||
202 | "needs-reset-on-resume")) | 195 | "needs-reset-on-resume")) |
203 | pdata->reset_on_resume = 1; | 196 | pdata->reset_on_resume = 1; |
204 | 197 | ||
198 | if (of_property_read_bool(dev->dev.of_node, | ||
199 | "has-transaction-translator")) | ||
200 | pdata->has_tt = 1; | ||
201 | |||
205 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, | 202 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, |
206 | "phys", "#phy-cells"); | 203 | "phys", "#phy-cells"); |
207 | priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; | ||
208 | 204 | ||
209 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, | 205 | if (priv->num_phys > 0) { |
210 | sizeof(struct phy *), GFP_KERNEL); | 206 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, |
211 | if (!priv->phys) | 207 | sizeof(struct phy *), GFP_KERNEL); |
212 | return -ENOMEM; | 208 | if (!priv->phys) |
209 | return -ENOMEM; | ||
210 | } else | ||
211 | priv->num_phys = 0; | ||
213 | 212 | ||
214 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 213 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
215 | err = of_property_read_string_index( | 214 | priv->phys[phy_num] = devm_of_phy_get_by_index( |
216 | dev->dev.of_node, | 215 | &dev->dev, dev->dev.of_node, phy_num); |
217 | "phy-names", phy_num, | 216 | if (IS_ERR(priv->phys[phy_num])) { |
218 | &phy_name); | 217 | err = PTR_ERR(priv->phys[phy_num]); |
219 | 218 | goto err_put_hcd; | |
220 | if (err < 0) { | 219 | } |
221 | if (priv->num_phys > 1) { | ||
222 | dev_err(&dev->dev, "phy-names not provided"); | ||
223 | goto err_put_hcd; | ||
224 | } else | ||
225 | phy_name = "usb"; | ||
226 | } | ||
227 | |||
228 | priv->phys[phy_num] = devm_phy_get(&dev->dev, | ||
229 | phy_name); | ||
230 | if (IS_ERR(priv->phys[phy_num])) { | ||
231 | err = PTR_ERR(priv->phys[phy_num]); | ||
232 | if ((priv->num_phys > 1) || | ||
233 | (err == -EPROBE_DEFER)) | ||
234 | goto err_put_hcd; | ||
235 | priv->phys[phy_num] = NULL; | ||
236 | } | ||
237 | } | 220 | } |
238 | 221 | ||
239 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { | 222 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index ff9af29b4e9f..4031b372008e 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -304,6 +304,7 @@ struct dma_aligned_buffer { | |||
304 | static void free_dma_aligned_buffer(struct urb *urb) | 304 | static void free_dma_aligned_buffer(struct urb *urb) |
305 | { | 305 | { |
306 | struct dma_aligned_buffer *temp; | 306 | struct dma_aligned_buffer *temp; |
307 | size_t length; | ||
307 | 308 | ||
308 | if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) | 309 | if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) |
309 | return; | 310 | return; |
@@ -311,9 +312,14 @@ static void free_dma_aligned_buffer(struct urb *urb) | |||
311 | temp = container_of(urb->transfer_buffer, | 312 | temp = container_of(urb->transfer_buffer, |
312 | struct dma_aligned_buffer, data); | 313 | struct dma_aligned_buffer, data); |
313 | 314 | ||
314 | if (usb_urb_dir_in(urb)) | 315 | if (usb_urb_dir_in(urb)) { |
315 | memcpy(temp->old_xfer_buffer, temp->data, | 316 | if (usb_pipeisoc(urb->pipe)) |
316 | urb->transfer_buffer_length); | 317 | length = urb->transfer_buffer_length; |
318 | else | ||
319 | length = urb->actual_length; | ||
320 | |||
321 | memcpy(temp->old_xfer_buffer, temp->data, length); | ||
322 | } | ||
317 | urb->transfer_buffer = temp->old_xfer_buffer; | 323 | urb->transfer_buffer = temp->old_xfer_buffer; |
318 | kfree(temp->kmalloc_ptr); | 324 | kfree(temp->kmalloc_ptr); |
319 | 325 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 52ef0844a180..f700157cd084 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -868,10 +868,13 @@ extern void ehci_init_driver(struct hc_driver *drv, | |||
868 | extern int ehci_setup(struct usb_hcd *hcd); | 868 | extern int ehci_setup(struct usb_hcd *hcd); |
869 | extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, | 869 | extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, |
870 | u32 mask, u32 done, int usec); | 870 | u32 mask, u32 done, int usec); |
871 | extern int ehci_reset(struct ehci_hcd *ehci); | ||
871 | 872 | ||
872 | #ifdef CONFIG_PM | 873 | #ifdef CONFIG_PM |
873 | extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); | 874 | extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); |
874 | extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); | 875 | extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); |
876 | extern void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, | ||
877 | bool suspending, bool do_wakeup); | ||
875 | #endif /* CONFIG_PM */ | 878 | #endif /* CONFIG_PM */ |
876 | 879 | ||
877 | extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 880 | extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 7e325e90d7d9..5e0d60035216 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c | |||
@@ -126,6 +126,8 @@ static int usb_get_ver_info(struct device_node *np) | |||
126 | /* | 126 | /* |
127 | * returns 1 for usb controller version 1.6 | 127 | * returns 1 for usb controller version 1.6 |
128 | * returns 2 for usb controller version 2.2 | 128 | * returns 2 for usb controller version 2.2 |
129 | * returns 3 for usb controller version 2.4 | ||
130 | * returns 4 for usb controller version 2.5 | ||
129 | * returns 0 otherwise | 131 | * returns 0 otherwise |
130 | */ | 132 | */ |
131 | if (of_device_is_compatible(np, "fsl-usb2-dr")) { | 133 | if (of_device_is_compatible(np, "fsl-usb2-dr")) { |
@@ -135,6 +137,8 @@ static int usb_get_ver_info(struct device_node *np) | |||
135 | ver = FSL_USB_VER_2_2; | 137 | ver = FSL_USB_VER_2_2; |
136 | else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.4")) | 138 | else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.4")) |
137 | ver = FSL_USB_VER_2_4; | 139 | ver = FSL_USB_VER_2_4; |
140 | else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.5")) | ||
141 | ver = FSL_USB_VER_2_5; | ||
138 | else /* for previous controller versions */ | 142 | else /* for previous controller versions */ |
139 | ver = FSL_USB_VER_OLD; | 143 | ver = FSL_USB_VER_OLD; |
140 | 144 | ||
@@ -150,6 +154,10 @@ static int usb_get_ver_info(struct device_node *np) | |||
150 | ver = FSL_USB_VER_1_6; | 154 | ver = FSL_USB_VER_1_6; |
151 | else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2")) | 155 | else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2")) |
152 | ver = FSL_USB_VER_2_2; | 156 | ver = FSL_USB_VER_2_2; |
157 | else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.4")) | ||
158 | ver = FSL_USB_VER_2_4; | ||
159 | else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.5")) | ||
160 | ver = FSL_USB_VER_2_5; | ||
153 | else /* for previous controller versions */ | 161 | else /* for previous controller versions */ |
154 | ver = FSL_USB_VER_OLD; | 162 | ver = FSL_USB_VER_OLD; |
155 | } | 163 | } |
diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c index 00e492eaba6a..1fd8718a9f11 100644 --- a/drivers/usb/host/fusbh200-hcd.c +++ b/drivers/usb/host/fusbh200-hcd.c | |||
@@ -499,7 +499,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
499 | unsigned i; | 499 | unsigned i; |
500 | __hc32 tag; | 500 | __hc32 tag; |
501 | 501 | ||
502 | if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC))) | 502 | seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC); |
503 | if (!seen) | ||
503 | return 0; | 504 | return 0; |
504 | seen_count = 0; | 505 | seen_count = 0; |
505 | 506 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 13181dcd9820..d089b3fb7a13 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -500,7 +500,8 @@ static void start_atl_transfers(struct isp116x *isp116x) | |||
500 | if (isp116x->periodic_count) { | 500 | if (isp116x->periodic_count) { |
501 | isp116x->fmindex = index = | 501 | isp116x->fmindex = index = |
502 | (isp116x->fmindex + 1) & (PERIODIC_SIZE - 1); | 502 | (isp116x->fmindex + 1) & (PERIODIC_SIZE - 1); |
503 | if ((load = isp116x->load[index])) { | 503 | load = isp116x->load[index]; |
504 | if (load) { | ||
504 | /* Bring all int transfers for this frame | 505 | /* Bring all int transfers for this frame |
505 | into the active queue */ | 506 | into the active queue */ |
506 | isp116x->atl_active = last_ep = | 507 | isp116x->atl_active = last_ep = |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 04f2186939d2..c3eded317495 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -491,7 +491,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
491 | char *next; | 491 | char *next; |
492 | unsigned i; | 492 | unsigned i; |
493 | 493 | ||
494 | if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC))) | 494 | seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC); |
495 | if (!seen) | ||
495 | return 0; | 496 | return 0; |
496 | seen_count = 0; | 497 | seen_count = 0; |
497 | 498 | ||
@@ -506,7 +507,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
506 | /* dump a snapshot of the periodic schedule (and load) */ | 507 | /* dump a snapshot of the periodic schedule (and load) */ |
507 | spin_lock_irqsave (&ohci->lock, flags); | 508 | spin_lock_irqsave (&ohci->lock, flags); |
508 | for (i = 0; i < NUM_INTS; i++) { | 509 | for (i = 0; i < NUM_INTS; i++) { |
509 | if (!(ed = ohci->periodic [i])) | 510 | ed = ohci->periodic[i]; |
511 | if (!ed) | ||
510 | continue; | 512 | continue; |
511 | 513 | ||
512 | temp = scnprintf (next, size, "%2d [%3d]:", i, ohci->load [i]); | 514 | temp = scnprintf (next, size, "%2d [%3d]:", i, ohci->load [i]); |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1dab9dfbca6a..760cb57e954e 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -155,7 +155,8 @@ static int ohci_urb_enqueue ( | |||
155 | int retval = 0; | 155 | int retval = 0; |
156 | 156 | ||
157 | /* every endpoint has a ed, locate and maybe (re)initialize it */ | 157 | /* every endpoint has a ed, locate and maybe (re)initialize it */ |
158 | if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval))) | 158 | ed = ed_get(ohci, urb->ep, urb->dev, pipe, urb->interval); |
159 | if (! ed) | ||
159 | return -ENOMEM; | 160 | return -ENOMEM; |
160 | 161 | ||
161 | /* for the private part of the URB we need the number of TDs (size) */ | 162 | /* for the private part of the URB we need the number of TDs (size) */ |
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 185ceee52d47..c2669f185f65 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c | |||
@@ -57,15 +57,13 @@ static int ohci_platform_power_on(struct platform_device *dev) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 59 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
60 | if (priv->phys[phy_num]) { | 60 | ret = phy_init(priv->phys[phy_num]); |
61 | ret = phy_init(priv->phys[phy_num]); | 61 | if (ret) |
62 | if (ret) | 62 | goto err_exit_phy; |
63 | goto err_exit_phy; | 63 | ret = phy_power_on(priv->phys[phy_num]); |
64 | ret = phy_power_on(priv->phys[phy_num]); | 64 | if (ret) { |
65 | if (ret) { | 65 | phy_exit(priv->phys[phy_num]); |
66 | phy_exit(priv->phys[phy_num]); | 66 | goto err_exit_phy; |
67 | goto err_exit_phy; | ||
68 | } | ||
69 | } | 67 | } |
70 | } | 68 | } |
71 | 69 | ||
@@ -73,10 +71,8 @@ static int ohci_platform_power_on(struct platform_device *dev) | |||
73 | 71 | ||
74 | err_exit_phy: | 72 | err_exit_phy: |
75 | while (--phy_num >= 0) { | 73 | while (--phy_num >= 0) { |
76 | if (priv->phys[phy_num]) { | 74 | phy_power_off(priv->phys[phy_num]); |
77 | phy_power_off(priv->phys[phy_num]); | 75 | phy_exit(priv->phys[phy_num]); |
78 | phy_exit(priv->phys[phy_num]); | ||
79 | } | ||
80 | } | 76 | } |
81 | err_disable_clks: | 77 | err_disable_clks: |
82 | while (--clk >= 0) | 78 | while (--clk >= 0) |
@@ -92,10 +88,8 @@ static void ohci_platform_power_off(struct platform_device *dev) | |||
92 | int clk, phy_num; | 88 | int clk, phy_num; |
93 | 89 | ||
94 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 90 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
95 | if (priv->phys[phy_num]) { | 91 | phy_power_off(priv->phys[phy_num]); |
96 | phy_power_off(priv->phys[phy_num]); | 92 | phy_exit(priv->phys[phy_num]); |
97 | phy_exit(priv->phys[phy_num]); | ||
98 | } | ||
99 | } | 93 | } |
100 | 94 | ||
101 | for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) | 95 | for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) |
@@ -123,7 +117,6 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
123 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); | 117 | struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); |
124 | struct ohci_platform_priv *priv; | 118 | struct ohci_platform_priv *priv; |
125 | struct ohci_hcd *ohci; | 119 | struct ohci_hcd *ohci; |
126 | const char *phy_name; | ||
127 | int err, irq, phy_num, clk = 0; | 120 | int err, irq, phy_num, clk = 0; |
128 | 121 | ||
129 | if (usb_disabled()) | 122 | if (usb_disabled()) |
@@ -174,36 +167,22 @@ static int ohci_platform_probe(struct platform_device *dev) | |||
174 | 167 | ||
175 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, | 168 | priv->num_phys = of_count_phandle_with_args(dev->dev.of_node, |
176 | "phys", "#phy-cells"); | 169 | "phys", "#phy-cells"); |
177 | priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1; | ||
178 | 170 | ||
179 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, | 171 | if (priv->num_phys > 0) { |
180 | sizeof(struct phy *), GFP_KERNEL); | 172 | priv->phys = devm_kcalloc(&dev->dev, priv->num_phys, |
181 | if (!priv->phys) | 173 | sizeof(struct phy *), GFP_KERNEL); |
182 | return -ENOMEM; | 174 | if (!priv->phys) |
175 | return -ENOMEM; | ||
176 | } else | ||
177 | priv->num_phys = 0; | ||
183 | 178 | ||
184 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { | 179 | for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { |
185 | err = of_property_read_string_index( | 180 | priv->phys[phy_num] = devm_of_phy_get_by_index( |
186 | dev->dev.of_node, | 181 | &dev->dev, dev->dev.of_node, phy_num); |
187 | "phy-names", phy_num, | 182 | if (IS_ERR(priv->phys[phy_num])) { |
188 | &phy_name); | 183 | err = PTR_ERR(priv->phys[phy_num]); |
189 | 184 | goto err_put_hcd; | |
190 | if (err < 0) { | 185 | } |
191 | if (priv->num_phys > 1) { | ||
192 | dev_err(&dev->dev, "phy-names not provided"); | ||
193 | goto err_put_hcd; | ||
194 | } else | ||
195 | phy_name = "usb"; | ||
196 | } | ||
197 | |||
198 | priv->phys[phy_num] = devm_phy_get(&dev->dev, | ||
199 | phy_name); | ||
200 | if (IS_ERR(priv->phys[phy_num])) { | ||
201 | err = PTR_ERR(priv->phys[phy_num]); | ||
202 | if ((priv->num_phys > 1) || | ||
203 | (err == -EPROBE_DEFER)) | ||
204 | goto err_put_hcd; | ||
205 | priv->phys[phy_num] = NULL; | ||
206 | } | ||
207 | } | 186 | } |
208 | 187 | ||
209 | for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { | 188 | for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 1463c398d322..f7d561ed3c23 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -407,7 +407,8 @@ static struct ed *ed_get ( | |||
407 | 407 | ||
408 | spin_lock_irqsave (&ohci->lock, flags); | 408 | spin_lock_irqsave (&ohci->lock, flags); |
409 | 409 | ||
410 | if (!(ed = ep->hcpriv)) { | 410 | ed = ep->hcpriv; |
411 | if (!ed) { | ||
411 | struct td *td; | 412 | struct td *td; |
412 | int is_out; | 413 | int is_out; |
413 | u32 info; | 414 | u32 info; |
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index ffc32f4b1b1b..62b6b7804c66 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c | |||
@@ -105,7 +105,7 @@ static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool | |||
105 | { | 105 | { |
106 | struct platform_device *hci_dev; | 106 | struct platform_device *hci_dev; |
107 | struct resource hci_res[2]; | 107 | struct resource hci_res[2]; |
108 | int ret = -ENOMEM; | 108 | int ret; |
109 | 109 | ||
110 | memset(hci_res, 0, sizeof(hci_res)); | 110 | memset(hci_res, 0, sizeof(hci_res)); |
111 | 111 | ||
@@ -119,7 +119,7 @@ static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool | |||
119 | hci_dev = platform_device_alloc(ohci ? "ohci-platform" : | 119 | hci_dev = platform_device_alloc(ohci ? "ohci-platform" : |
120 | "ehci-platform" , 0); | 120 | "ehci-platform" , 0); |
121 | if (!hci_dev) | 121 | if (!hci_dev) |
122 | return NULL; | 122 | return ERR_PTR(-ENOMEM); |
123 | 123 | ||
124 | hci_dev->dev.parent = dev->dev; | 124 | hci_dev->dev.parent = dev->dev; |
125 | hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask; | 125 | hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask; |
@@ -166,7 +166,8 @@ static int ssb_hcd_probe(struct ssb_device *dev, | |||
166 | if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) | 166 | if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) |
167 | return -EOPNOTSUPP; | 167 | return -EOPNOTSUPP; |
168 | 168 | ||
169 | usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL); | 169 | usb_dev = devm_kzalloc(dev->dev, sizeof(struct ssb_hcd_device), |
170 | GFP_KERNEL); | ||
170 | if (!usb_dev) | 171 | if (!usb_dev) |
171 | return -ENOMEM; | 172 | return -ENOMEM; |
172 | 173 | ||
@@ -181,10 +182,8 @@ static int ssb_hcd_probe(struct ssb_device *dev, | |||
181 | start = ssb_admatch_base(tmp); | 182 | start = ssb_admatch_base(tmp); |
182 | len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp); | 183 | len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp); |
183 | usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len); | 184 | usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len); |
184 | if (IS_ERR(usb_dev->ohci_dev)) { | 185 | if (IS_ERR(usb_dev->ohci_dev)) |
185 | err = PTR_ERR(usb_dev->ohci_dev); | 186 | return PTR_ERR(usb_dev->ohci_dev); |
186 | goto err_free_usb_dev; | ||
187 | } | ||
188 | 187 | ||
189 | if (coreid == SSB_DEV_USB20_HOST) { | 188 | if (coreid == SSB_DEV_USB20_HOST) { |
190 | start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */ | 189 | start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */ |
@@ -200,8 +199,6 @@ static int ssb_hcd_probe(struct ssb_device *dev, | |||
200 | 199 | ||
201 | err_unregister_ohci_dev: | 200 | err_unregister_ohci_dev: |
202 | platform_device_unregister(usb_dev->ohci_dev); | 201 | platform_device_unregister(usb_dev->ohci_dev); |
203 | err_free_usb_dev: | ||
204 | kfree(usb_dev); | ||
205 | return err; | 202 | return err; |
206 | } | 203 | } |
207 | 204 | ||
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 0827d7c96527..e75c565feb53 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -1184,6 +1184,10 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
1184 | struct xhci_bus_state *bus_state; | 1184 | struct xhci_bus_state *bus_state; |
1185 | u32 temp; | 1185 | u32 temp; |
1186 | unsigned long flags; | 1186 | unsigned long flags; |
1187 | unsigned long port_was_suspended = 0; | ||
1188 | bool need_usb2_u3_exit = false; | ||
1189 | int slot_id; | ||
1190 | int sret; | ||
1187 | 1191 | ||
1188 | max_ports = xhci_get_ports(hcd, &port_array); | 1192 | max_ports = xhci_get_ports(hcd, &port_array); |
1189 | bus_state = &xhci->bus_state[hcd_index(hcd)]; | 1193 | bus_state = &xhci->bus_state[hcd_index(hcd)]; |
@@ -1207,7 +1211,6 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
1207 | /* Check whether need resume ports. If needed | 1211 | /* Check whether need resume ports. If needed |
1208 | resume port and disable remote wakeup */ | 1212 | resume port and disable remote wakeup */ |
1209 | u32 temp; | 1213 | u32 temp; |
1210 | int slot_id; | ||
1211 | 1214 | ||
1212 | temp = readl(port_array[port_index]); | 1215 | temp = readl(port_array[port_index]); |
1213 | if (DEV_SUPERSPEED(temp)) | 1216 | if (DEV_SUPERSPEED(temp)) |
@@ -1216,39 +1219,47 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
1216 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | 1219 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
1217 | if (test_bit(port_index, &bus_state->bus_suspended) && | 1220 | if (test_bit(port_index, &bus_state->bus_suspended) && |
1218 | (temp & PORT_PLS_MASK)) { | 1221 | (temp & PORT_PLS_MASK)) { |
1219 | if (DEV_SUPERSPEED(temp)) { | 1222 | set_bit(port_index, &port_was_suspended); |
1220 | xhci_set_link_state(xhci, port_array, | 1223 | if (!DEV_SUPERSPEED(temp)) { |
1221 | port_index, XDEV_U0); | ||
1222 | } else { | ||
1223 | xhci_set_link_state(xhci, port_array, | 1224 | xhci_set_link_state(xhci, port_array, |
1224 | port_index, XDEV_RESUME); | 1225 | port_index, XDEV_RESUME); |
1225 | 1226 | need_usb2_u3_exit = true; | |
1226 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1227 | msleep(20); | ||
1228 | spin_lock_irqsave(&xhci->lock, flags); | ||
1229 | |||
1230 | xhci_set_link_state(xhci, port_array, | ||
1231 | port_index, XDEV_U0); | ||
1232 | } | 1227 | } |
1233 | /* wait for the port to enter U0 and report port link | ||
1234 | * state change. | ||
1235 | */ | ||
1236 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1237 | msleep(20); | ||
1238 | spin_lock_irqsave(&xhci->lock, flags); | ||
1239 | |||
1240 | /* Clear PLC */ | ||
1241 | xhci_test_and_clear_bit(xhci, port_array, port_index, | ||
1242 | PORT_PLC); | ||
1243 | |||
1244 | slot_id = xhci_find_slot_id_by_port(hcd, | ||
1245 | xhci, port_index + 1); | ||
1246 | if (slot_id) | ||
1247 | xhci_ring_device(xhci, slot_id); | ||
1248 | } else | 1228 | } else |
1249 | writel(temp, port_array[port_index]); | 1229 | writel(temp, port_array[port_index]); |
1250 | } | 1230 | } |
1251 | 1231 | ||
1232 | if (need_usb2_u3_exit) { | ||
1233 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1234 | msleep(20); | ||
1235 | spin_lock_irqsave(&xhci->lock, flags); | ||
1236 | } | ||
1237 | |||
1238 | port_index = max_ports; | ||
1239 | while (port_index--) { | ||
1240 | if (!(port_was_suspended & BIT(port_index))) | ||
1241 | continue; | ||
1242 | /* Clear PLC to poll it later after XDEV_U0 */ | ||
1243 | xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); | ||
1244 | xhci_set_link_state(xhci, port_array, port_index, XDEV_U0); | ||
1245 | } | ||
1246 | |||
1247 | port_index = max_ports; | ||
1248 | while (port_index--) { | ||
1249 | if (!(port_was_suspended & BIT(port_index))) | ||
1250 | continue; | ||
1251 | /* Poll and Clear PLC */ | ||
1252 | sret = xhci_handshake(port_array[port_index], PORT_PLC, | ||
1253 | PORT_PLC, 10 * 1000); | ||
1254 | if (sret) | ||
1255 | xhci_warn(xhci, "port %d resume PLC timeout\n", | ||
1256 | port_index); | ||
1257 | xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); | ||
1258 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); | ||
1259 | if (slot_id) | ||
1260 | xhci_ring_device(xhci, slot_id); | ||
1261 | } | ||
1262 | |||
1252 | (void) readl(&xhci->op_regs->command); | 1263 | (void) readl(&xhci->op_regs->command); |
1253 | 1264 | ||
1254 | bus_state->next_statechange = jiffies + msecs_to_jiffies(5); | 1265 | bus_state->next_statechange = jiffies + msecs_to_jiffies(5); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 2af32e26fafc..4a4cb1d91ac8 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -45,6 +45,13 @@ static const char hcd_name[] = "xhci_hcd"; | |||
45 | 45 | ||
46 | static struct hc_driver __read_mostly xhci_pci_hc_driver; | 46 | static struct hc_driver __read_mostly xhci_pci_hc_driver; |
47 | 47 | ||
48 | static int xhci_pci_setup(struct usb_hcd *hcd); | ||
49 | |||
50 | static const struct xhci_driver_overrides xhci_pci_overrides __initconst = { | ||
51 | .extra_priv_size = sizeof(struct xhci_hcd), | ||
52 | .reset = xhci_pci_setup, | ||
53 | }; | ||
54 | |||
48 | /* called after powerup, by probe or system-pm "wakeup" */ | 55 | /* called after powerup, by probe or system-pm "wakeup" */ |
49 | static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) | 56 | static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) |
50 | { | 57 | { |
@@ -206,7 +213,6 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
206 | if (!retval) | 213 | if (!retval) |
207 | return retval; | 214 | return retval; |
208 | 215 | ||
209 | kfree(xhci); | ||
210 | return retval; | 216 | return retval; |
211 | } | 217 | } |
212 | 218 | ||
@@ -247,11 +253,6 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
247 | goto dealloc_usb2_hcd; | 253 | goto dealloc_usb2_hcd; |
248 | } | 254 | } |
249 | 255 | ||
250 | /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset) | ||
251 | * is called by usb_add_hcd(). | ||
252 | */ | ||
253 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | ||
254 | |||
255 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, | 256 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, |
256 | IRQF_SHARED); | 257 | IRQF_SHARED); |
257 | if (retval) | 258 | if (retval) |
@@ -290,8 +291,6 @@ static void xhci_pci_remove(struct pci_dev *dev) | |||
290 | /* Workaround for spurious wakeups at shutdown with HSW */ | 291 | /* Workaround for spurious wakeups at shutdown with HSW */ |
291 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | 292 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) |
292 | pci_set_power_state(dev, PCI_D3hot); | 293 | pci_set_power_state(dev, PCI_D3hot); |
293 | |||
294 | kfree(xhci); | ||
295 | } | 294 | } |
296 | 295 | ||
297 | #ifdef CONFIG_PM | 296 | #ifdef CONFIG_PM |
@@ -379,7 +378,7 @@ static struct pci_driver xhci_pci_driver = { | |||
379 | 378 | ||
380 | static int __init xhci_pci_init(void) | 379 | static int __init xhci_pci_init(void) |
381 | { | 380 | { |
382 | xhci_init_driver(&xhci_pci_hc_driver, xhci_pci_setup); | 381 | xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides); |
383 | #ifdef CONFIG_PM | 382 | #ifdef CONFIG_PM |
384 | xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; | 383 | xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; |
385 | xhci_pci_hc_driver.pci_resume = xhci_pci_resume; | 384 | xhci_pci_hc_driver.pci_resume = xhci_pci_resume; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 783e819139a7..890ad9d9d329 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -26,6 +26,15 @@ | |||
26 | 26 | ||
27 | static struct hc_driver __read_mostly xhci_plat_hc_driver; | 27 | static struct hc_driver __read_mostly xhci_plat_hc_driver; |
28 | 28 | ||
29 | static int xhci_plat_setup(struct usb_hcd *hcd); | ||
30 | static int xhci_plat_start(struct usb_hcd *hcd); | ||
31 | |||
32 | static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { | ||
33 | .extra_priv_size = sizeof(struct xhci_hcd), | ||
34 | .reset = xhci_plat_setup, | ||
35 | .start = xhci_plat_start, | ||
36 | }; | ||
37 | |||
29 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) | 38 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) |
30 | { | 39 | { |
31 | /* | 40 | /* |
@@ -127,31 +136,21 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
127 | goto disable_clk; | 136 | goto disable_clk; |
128 | } | 137 | } |
129 | 138 | ||
130 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
131 | if (ret) | ||
132 | goto disable_clk; | ||
133 | |||
134 | device_wakeup_enable(hcd->self.controller); | 139 | device_wakeup_enable(hcd->self.controller); |
135 | 140 | ||
136 | /* USB 2.0 roothub is stored in the platform_device now. */ | ||
137 | hcd = platform_get_drvdata(pdev); | ||
138 | xhci = hcd_to_xhci(hcd); | 141 | xhci = hcd_to_xhci(hcd); |
139 | xhci->clk = clk; | 142 | xhci->clk = clk; |
143 | xhci->main_hcd = hcd; | ||
140 | xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, | 144 | xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, |
141 | dev_name(&pdev->dev), hcd); | 145 | dev_name(&pdev->dev), hcd); |
142 | if (!xhci->shared_hcd) { | 146 | if (!xhci->shared_hcd) { |
143 | ret = -ENOMEM; | 147 | ret = -ENOMEM; |
144 | goto dealloc_usb2_hcd; | 148 | goto disable_clk; |
145 | } | 149 | } |
146 | 150 | ||
147 | if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || | 151 | if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || |
148 | (pdata && pdata->usb3_lpm_capable)) | 152 | (pdata && pdata->usb3_lpm_capable)) |
149 | xhci->quirks |= XHCI_LPM_SUPPORT; | 153 | xhci->quirks |= XHCI_LPM_SUPPORT; |
150 | /* | ||
151 | * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) | ||
152 | * is called by usb_add_hcd(). | ||
153 | */ | ||
154 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | ||
155 | 154 | ||
156 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) | 155 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) |
157 | xhci->shared_hcd->can_do_streams = 1; | 156 | xhci->shared_hcd->can_do_streams = 1; |
@@ -168,21 +167,26 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
168 | goto put_usb3_hcd; | 167 | goto put_usb3_hcd; |
169 | } | 168 | } |
170 | 169 | ||
171 | ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); | 170 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
172 | if (ret) | 171 | if (ret) |
173 | goto disable_usb_phy; | 172 | goto disable_usb_phy; |
174 | 173 | ||
174 | ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); | ||
175 | if (ret) | ||
176 | goto dealloc_usb2_hcd; | ||
177 | |||
175 | return 0; | 178 | return 0; |
176 | 179 | ||
180 | |||
181 | dealloc_usb2_hcd: | ||
182 | usb_remove_hcd(hcd); | ||
183 | |||
177 | disable_usb_phy: | 184 | disable_usb_phy: |
178 | usb_phy_shutdown(hcd->usb_phy); | 185 | usb_phy_shutdown(hcd->usb_phy); |
179 | 186 | ||
180 | put_usb3_hcd: | 187 | put_usb3_hcd: |
181 | usb_put_hcd(xhci->shared_hcd); | 188 | usb_put_hcd(xhci->shared_hcd); |
182 | 189 | ||
183 | dealloc_usb2_hcd: | ||
184 | usb_remove_hcd(hcd); | ||
185 | |||
186 | disable_clk: | 190 | disable_clk: |
187 | if (!IS_ERR(clk)) | 191 | if (!IS_ERR(clk)) |
188 | clk_disable_unprepare(clk); | 192 | clk_disable_unprepare(clk); |
@@ -201,13 +205,13 @@ static int xhci_plat_remove(struct platform_device *dev) | |||
201 | 205 | ||
202 | usb_remove_hcd(xhci->shared_hcd); | 206 | usb_remove_hcd(xhci->shared_hcd); |
203 | usb_phy_shutdown(hcd->usb_phy); | 207 | usb_phy_shutdown(hcd->usb_phy); |
204 | usb_put_hcd(xhci->shared_hcd); | ||
205 | 208 | ||
206 | usb_remove_hcd(hcd); | 209 | usb_remove_hcd(hcd); |
210 | usb_put_hcd(xhci->shared_hcd); | ||
211 | |||
207 | if (!IS_ERR(clk)) | 212 | if (!IS_ERR(clk)) |
208 | clk_disable_unprepare(clk); | 213 | clk_disable_unprepare(clk); |
209 | usb_put_hcd(hcd); | 214 | usb_put_hcd(hcd); |
210 | kfree(xhci); | ||
211 | 215 | ||
212 | return 0; | 216 | return 0; |
213 | } | 217 | } |
@@ -271,8 +275,7 @@ MODULE_ALIAS("platform:xhci-hcd"); | |||
271 | 275 | ||
272 | static int __init xhci_plat_init(void) | 276 | static int __init xhci_plat_init(void) |
273 | { | 277 | { |
274 | xhci_init_driver(&xhci_plat_hc_driver, xhci_plat_setup); | 278 | xhci_init_driver(&xhci_plat_hc_driver, &xhci_plat_overrides); |
275 | xhci_plat_hc_driver.start = xhci_plat_start; | ||
276 | return platform_driver_register(&usb_xhci_driver); | 279 | return platform_driver_register(&usb_xhci_driver); |
277 | } | 280 | } |
278 | module_init(xhci_plat_init); | 281 | module_init(xhci_plat_init); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7d34cbfaf373..94416ff70810 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1934,7 +1934,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1934 | td->urb->actual_length = | 1934 | td->urb->actual_length = |
1935 | td->urb->transfer_buffer_length - | 1935 | td->urb->transfer_buffer_length - |
1936 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); | 1936 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
1937 | else | 1937 | else if (!td->urb_length_set) |
1938 | td->urb->actual_length = 0; | 1938 | td->urb->actual_length = 0; |
1939 | 1939 | ||
1940 | return finish_td(xhci, td, event_trb, event, ep, status, false); | 1940 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
@@ -3781,8 +3781,11 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, | |||
3781 | { | 3781 | { |
3782 | int reserved_trbs = xhci->cmd_ring_reserved_trbs; | 3782 | int reserved_trbs = xhci->cmd_ring_reserved_trbs; |
3783 | int ret; | 3783 | int ret; |
3784 | if (xhci->xhc_state & XHCI_STATE_DYING) | 3784 | |
3785 | if (xhci->xhc_state) { | ||
3786 | xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n"); | ||
3785 | return -ESHUTDOWN; | 3787 | return -ESHUTDOWN; |
3788 | } | ||
3786 | 3789 | ||
3787 | if (!command_must_succeed) | 3790 | if (!command_must_succeed) |
3788 | reserved_trbs++; | 3791 | reserved_trbs++; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 36bf089b708f..7da0d6043d33 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -660,12 +660,6 @@ static void xhci_only_stop_hcd(struct usb_hcd *hcd) | |||
660 | 660 | ||
661 | spin_lock_irq(&xhci->lock); | 661 | spin_lock_irq(&xhci->lock); |
662 | xhci_halt(xhci); | 662 | xhci_halt(xhci); |
663 | |||
664 | /* The shared_hcd is going to be deallocated shortly (the USB core only | ||
665 | * calls this function when allocation fails in usb_add_hcd(), or | ||
666 | * usb_remove_hcd() is called). So we need to unset xHCI's pointer. | ||
667 | */ | ||
668 | xhci->shared_hcd = NULL; | ||
669 | spin_unlock_irq(&xhci->lock); | 663 | spin_unlock_irq(&xhci->lock); |
670 | } | 664 | } |
671 | 665 | ||
@@ -897,6 +891,9 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) | |||
897 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 891 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
898 | u32 command; | 892 | u32 command; |
899 | 893 | ||
894 | if (!hcd->state) | ||
895 | return 0; | ||
896 | |||
900 | if (hcd->state != HC_STATE_SUSPENDED || | 897 | if (hcd->state != HC_STATE_SUSPENDED || |
901 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) | 898 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) |
902 | return -EINVAL; | 899 | return -EINVAL; |
@@ -983,6 +980,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
983 | int retval = 0; | 980 | int retval = 0; |
984 | bool comp_timer_running = false; | 981 | bool comp_timer_running = false; |
985 | 982 | ||
983 | if (!hcd->state) | ||
984 | return 0; | ||
985 | |||
986 | /* Wait a bit if either of the roothubs need to settle from the | 986 | /* Wait a bit if either of the roothubs need to settle from the |
987 | * transition into bus suspend. | 987 | * transition into bus suspend. |
988 | */ | 988 | */ |
@@ -3769,8 +3769,6 @@ disable_slot: | |||
3769 | /* | 3769 | /* |
3770 | * Issue an Address Device command and optionally send a corresponding | 3770 | * Issue an Address Device command and optionally send a corresponding |
3771 | * SetAddress request to the device. | 3771 | * SetAddress request to the device. |
3772 | * We should be protected by the usb_address0_mutex in hub_wq's hub_port_init, | ||
3773 | * so we should only issue and wait on one address command at the same time. | ||
3774 | */ | 3772 | */ |
3775 | static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | 3773 | static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, |
3776 | enum xhci_setup_dev setup) | 3774 | enum xhci_setup_dev setup) |
@@ -4842,10 +4840,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4842 | hcd->self.no_stop_on_short = 1; | 4840 | hcd->self.no_stop_on_short = 1; |
4843 | 4841 | ||
4844 | if (usb_hcd_is_primary_hcd(hcd)) { | 4842 | if (usb_hcd_is_primary_hcd(hcd)) { |
4845 | xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); | 4843 | xhci = hcd_to_xhci(hcd); |
4846 | if (!xhci) | ||
4847 | return -ENOMEM; | ||
4848 | *((struct xhci_hcd **) hcd->hcd_priv) = xhci; | ||
4849 | xhci->main_hcd = hcd; | 4844 | xhci->main_hcd = hcd; |
4850 | /* Mark the first roothub as being USB 2.0. | 4845 | /* Mark the first roothub as being USB 2.0. |
4851 | * The xHCI driver will register the USB 3.0 roothub. | 4846 | * The xHCI driver will register the USB 3.0 roothub. |
@@ -4894,13 +4889,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4894 | /* Make sure the HC is halted. */ | 4889 | /* Make sure the HC is halted. */ |
4895 | retval = xhci_halt(xhci); | 4890 | retval = xhci_halt(xhci); |
4896 | if (retval) | 4891 | if (retval) |
4897 | goto error; | 4892 | return retval; |
4898 | 4893 | ||
4899 | xhci_dbg(xhci, "Resetting HCD\n"); | 4894 | xhci_dbg(xhci, "Resetting HCD\n"); |
4900 | /* Reset the internal HC memory state and registers. */ | 4895 | /* Reset the internal HC memory state and registers. */ |
4901 | retval = xhci_reset(xhci); | 4896 | retval = xhci_reset(xhci); |
4902 | if (retval) | 4897 | if (retval) |
4903 | goto error; | 4898 | return retval; |
4904 | xhci_dbg(xhci, "Reset complete\n"); | 4899 | xhci_dbg(xhci, "Reset complete\n"); |
4905 | 4900 | ||
4906 | /* Set dma_mask and coherent_dma_mask to 64-bits, | 4901 | /* Set dma_mask and coherent_dma_mask to 64-bits, |
@@ -4915,16 +4910,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4915 | /* Initialize HCD and host controller data structures. */ | 4910 | /* Initialize HCD and host controller data structures. */ |
4916 | retval = xhci_init(hcd); | 4911 | retval = xhci_init(hcd); |
4917 | if (retval) | 4912 | if (retval) |
4918 | goto error; | 4913 | return retval; |
4919 | xhci_dbg(xhci, "Called HCD init\n"); | 4914 | xhci_dbg(xhci, "Called HCD init\n"); |
4920 | 4915 | ||
4921 | xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", | 4916 | xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", |
4922 | xhci->hcc_params, xhci->hci_version, xhci->quirks); | 4917 | xhci->hcc_params, xhci->hci_version, xhci->quirks); |
4923 | 4918 | ||
4924 | return 0; | 4919 | return 0; |
4925 | error: | ||
4926 | kfree(xhci); | ||
4927 | return retval; | ||
4928 | } | 4920 | } |
4929 | EXPORT_SYMBOL_GPL(xhci_gen_setup); | 4921 | EXPORT_SYMBOL_GPL(xhci_gen_setup); |
4930 | 4922 | ||
@@ -4989,11 +4981,21 @@ static const struct hc_driver xhci_hc_driver = { | |||
4989 | .find_raw_port_number = xhci_find_raw_port_number, | 4981 | .find_raw_port_number = xhci_find_raw_port_number, |
4990 | }; | 4982 | }; |
4991 | 4983 | ||
4992 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)) | 4984 | void xhci_init_driver(struct hc_driver *drv, |
4985 | const struct xhci_driver_overrides *over) | ||
4993 | { | 4986 | { |
4994 | BUG_ON(!setup_fn); | 4987 | BUG_ON(!over); |
4988 | |||
4989 | /* Copy the generic table to drv then apply the overrides */ | ||
4995 | *drv = xhci_hc_driver; | 4990 | *drv = xhci_hc_driver; |
4996 | drv->reset = setup_fn; | 4991 | |
4992 | if (over) { | ||
4993 | drv->hcd_priv_size += over->extra_priv_size; | ||
4994 | if (over->reset) | ||
4995 | drv->reset = over->reset; | ||
4996 | if (over->start) | ||
4997 | drv->start = over->start; | ||
4998 | } | ||
4997 | } | 4999 | } |
4998 | EXPORT_SYMBOL_GPL(xhci_init_driver); | 5000 | EXPORT_SYMBOL_GPL(xhci_init_driver); |
4999 | 5001 | ||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 6977f8491fa7..31e46cc55807 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1593,10 +1593,24 @@ struct xhci_hcd { | |||
1593 | #define COMP_MODE_RCVRY_MSECS 2000 | 1593 | #define COMP_MODE_RCVRY_MSECS 2000 |
1594 | }; | 1594 | }; |
1595 | 1595 | ||
1596 | /* Platform specific overrides to generic XHCI hc_driver ops */ | ||
1597 | struct xhci_driver_overrides { | ||
1598 | size_t extra_priv_size; | ||
1599 | int (*reset)(struct usb_hcd *hcd); | ||
1600 | int (*start)(struct usb_hcd *hcd); | ||
1601 | }; | ||
1602 | |||
1596 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 1603 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
1597 | static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) | 1604 | static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) |
1598 | { | 1605 | { |
1599 | return *((struct xhci_hcd **) (hcd->hcd_priv)); | 1606 | struct usb_hcd *primary_hcd; |
1607 | |||
1608 | if (usb_hcd_is_primary_hcd(hcd)) | ||
1609 | primary_hcd = hcd; | ||
1610 | else | ||
1611 | primary_hcd = hcd->primary_hcd; | ||
1612 | |||
1613 | return (struct xhci_hcd *) (primary_hcd->hcd_priv); | ||
1600 | } | 1614 | } |
1601 | 1615 | ||
1602 | static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | 1616 | static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) |
@@ -1750,7 +1764,8 @@ int xhci_run(struct usb_hcd *hcd); | |||
1750 | void xhci_stop(struct usb_hcd *hcd); | 1764 | void xhci_stop(struct usb_hcd *hcd); |
1751 | void xhci_shutdown(struct usb_hcd *hcd); | 1765 | void xhci_shutdown(struct usb_hcd *hcd); |
1752 | int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); | 1766 | int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); |
1753 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)); | 1767 | void xhci_init_driver(struct hc_driver *drv, |
1768 | const struct xhci_driver_overrides *over); | ||
1754 | 1769 | ||
1755 | #ifdef CONFIG_PM | 1770 | #ifdef CONFIG_PM |
1756 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); | 1771 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); |
diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 3fc4fe770253..18ebf5b1f256 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c | |||
@@ -812,6 +812,8 @@ static struct usb_request *isp1760_ep_alloc_request(struct usb_ep *ep, | |||
812 | struct isp1760_request *req; | 812 | struct isp1760_request *req; |
813 | 813 | ||
814 | req = kzalloc(sizeof(*req), gfp_flags); | 814 | req = kzalloc(sizeof(*req), gfp_flags); |
815 | if (!req) | ||
816 | return NULL; | ||
815 | 817 | ||
816 | return &req->req; | 818 | return &req->req; |
817 | } | 819 | } |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 022dc0008f2a..306d6852ebc7 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -2316,10 +2316,12 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2316 | /* Set mode 0x03 */ | 2316 | /* Set mode 0x03 */ |
2317 | SiSUSBSetMode(sisusb->SiS_Pr, 0x03); | 2317 | SiSUSBSetMode(sisusb->SiS_Pr, 0x03); |
2318 | 2318 | ||
2319 | if (!(myfont = find_font("VGA8x16"))) | 2319 | myfont = find_font("VGA8x16"); |
2320 | if (!myfont) | ||
2320 | return 1; | 2321 | return 1; |
2321 | 2322 | ||
2322 | if (!(tempbuf = vmalloc(8192))) | 2323 | tempbuf = vmalloc(8192); |
2324 | if (!tempbuf) | ||
2323 | return 1; | 2325 | return 1; |
2324 | 2326 | ||
2325 | for (i = 0; i < 256; i++) | 2327 | for (i = 0; i < 256; i++) |
@@ -2342,7 +2344,8 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2342 | 2344 | ||
2343 | if (init && !sisusb->scrbuf) { | 2345 | if (init && !sisusb->scrbuf) { |
2344 | 2346 | ||
2345 | if ((tempbuf = vmalloc(8192))) { | 2347 | tempbuf = vmalloc(8192); |
2348 | if (tempbuf) { | ||
2346 | 2349 | ||
2347 | i = 4096; | 2350 | i = 4096; |
2348 | tempbufb = (u16 *)tempbuf; | 2351 | tempbufb = (u16 *)tempbuf; |
@@ -2417,11 +2420,13 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2417 | struct usb_interface *interface; | 2420 | struct usb_interface *interface; |
2418 | int subminor = iminor(inode); | 2421 | int subminor = iminor(inode); |
2419 | 2422 | ||
2420 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { | 2423 | interface = usb_find_interface(&sisusb_driver, subminor); |
2424 | if (!interface) { | ||
2421 | return -ENODEV; | 2425 | return -ENODEV; |
2422 | } | 2426 | } |
2423 | 2427 | ||
2424 | if (!(sisusb = usb_get_intfdata(interface))) { | 2428 | sisusb = usb_get_intfdata(interface); |
2429 | if (!sisusb) { | ||
2425 | return -ENODEV; | 2430 | return -ENODEV; |
2426 | } | 2431 | } |
2427 | 2432 | ||
@@ -2488,7 +2493,8 @@ sisusb_release(struct inode *inode, struct file *file) | |||
2488 | { | 2493 | { |
2489 | struct sisusb_usb_data *sisusb; | 2494 | struct sisusb_usb_data *sisusb; |
2490 | 2495 | ||
2491 | if (!(sisusb = file->private_data)) | 2496 | sisusb = file->private_data; |
2497 | if (!sisusb) | ||
2492 | return -ENODEV; | 2498 | return -ENODEV; |
2493 | 2499 | ||
2494 | mutex_lock(&sisusb->lock); | 2500 | mutex_lock(&sisusb->lock); |
@@ -2520,7 +2526,8 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | |||
2520 | u16 buf16; | 2526 | u16 buf16; |
2521 | u32 buf32, address; | 2527 | u32 buf32, address; |
2522 | 2528 | ||
2523 | if (!(sisusb = file->private_data)) | 2529 | sisusb = file->private_data; |
2530 | if (!sisusb) | ||
2524 | return -ENODEV; | 2531 | return -ENODEV; |
2525 | 2532 | ||
2526 | mutex_lock(&sisusb->lock); | 2533 | mutex_lock(&sisusb->lock); |
@@ -2662,7 +2669,8 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count, | |||
2662 | u16 buf16; | 2669 | u16 buf16; |
2663 | u32 buf32, address; | 2670 | u32 buf32, address; |
2664 | 2671 | ||
2665 | if (!(sisusb = file->private_data)) | 2672 | sisusb = file->private_data; |
2673 | if (!sisusb) | ||
2666 | return -ENODEV; | 2674 | return -ENODEV; |
2667 | 2675 | ||
2668 | mutex_lock(&sisusb->lock); | 2676 | mutex_lock(&sisusb->lock); |
@@ -2805,7 +2813,8 @@ sisusb_lseek(struct file *file, loff_t offset, int orig) | |||
2805 | struct sisusb_usb_data *sisusb; | 2813 | struct sisusb_usb_data *sisusb; |
2806 | loff_t ret; | 2814 | loff_t ret; |
2807 | 2815 | ||
2808 | if (!(sisusb = file->private_data)) | 2816 | sisusb = file->private_data; |
2817 | if (!sisusb) | ||
2809 | return -ENODEV; | 2818 | return -ENODEV; |
2810 | 2819 | ||
2811 | mutex_lock(&sisusb->lock); | 2820 | mutex_lock(&sisusb->lock); |
@@ -2970,7 +2979,8 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2970 | long retval = 0; | 2979 | long retval = 0; |
2971 | u32 __user *argp = (u32 __user *)arg; | 2980 | u32 __user *argp = (u32 __user *)arg; |
2972 | 2981 | ||
2973 | if (!(sisusb = file->private_data)) | 2982 | sisusb = file->private_data; |
2983 | if (!sisusb) | ||
2974 | return -ENODEV; | 2984 | return -ENODEV; |
2975 | 2985 | ||
2976 | mutex_lock(&sisusb->lock); | 2986 | mutex_lock(&sisusb->lock); |
@@ -3084,7 +3094,8 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3084 | dev->devnum); | 3094 | dev->devnum); |
3085 | 3095 | ||
3086 | /* Allocate memory for our private */ | 3096 | /* Allocate memory for our private */ |
3087 | if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { | 3097 | sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL); |
3098 | if (!sisusb) { | ||
3088 | dev_err(&dev->dev, "Failed to allocate memory for private data\n"); | 3099 | dev_err(&dev->dev, "Failed to allocate memory for private data\n"); |
3089 | return -ENOMEM; | 3100 | return -ENOMEM; |
3090 | } | 3101 | } |
@@ -3093,7 +3104,8 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3093 | mutex_init(&(sisusb->lock)); | 3104 | mutex_init(&(sisusb->lock)); |
3094 | 3105 | ||
3095 | /* Register device */ | 3106 | /* Register device */ |
3096 | if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { | 3107 | retval = usb_register_dev(intf, &usb_sisusb_class); |
3108 | if (retval) { | ||
3097 | dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n", | 3109 | dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n", |
3098 | dev->devnum); | 3110 | dev->devnum); |
3099 | retval = -ENODEV; | 3111 | retval = -ENODEV; |
@@ -3214,7 +3226,8 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3214 | struct sisusb_usb_data *sisusb; | 3226 | struct sisusb_usb_data *sisusb; |
3215 | 3227 | ||
3216 | /* This should *not* happen */ | 3228 | /* This should *not* happen */ |
3217 | if (!(sisusb = usb_get_intfdata(intf))) | 3229 | sisusb = usb_get_intfdata(intf); |
3230 | if (!sisusb) | ||
3218 | return; | 3231 | return; |
3219 | 3232 | ||
3220 | #ifdef INCL_SISUSB_CON | 3233 | #ifdef INCL_SISUSB_CON |
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index a638c4e9a947..ace343088915 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -169,7 +169,8 @@ sisusb_get_sisusb_lock_and_check(unsigned short console) | |||
169 | if (in_atomic()) | 169 | if (in_atomic()) |
170 | return NULL; | 170 | return NULL; |
171 | 171 | ||
172 | if (!(sisusb = sisusb_get_sisusb(console))) | 172 | sisusb = sisusb_get_sisusb(console); |
173 | if (!sisusb) | ||
173 | return NULL; | 174 | return NULL; |
174 | 175 | ||
175 | mutex_lock(&sisusb->lock); | 176 | mutex_lock(&sisusb->lock); |
@@ -214,7 +215,8 @@ sisusbcon_init(struct vc_data *c, int init) | |||
214 | * are set up/restored. | 215 | * are set up/restored. |
215 | */ | 216 | */ |
216 | 217 | ||
217 | if (!(sisusb = sisusb_get_sisusb(c->vc_num))) | 218 | sisusb = sisusb_get_sisusb(c->vc_num); |
219 | if (!sisusb) | ||
218 | return; | 220 | return; |
219 | 221 | ||
220 | mutex_lock(&sisusb->lock); | 222 | mutex_lock(&sisusb->lock); |
@@ -277,7 +279,8 @@ sisusbcon_deinit(struct vc_data *c) | |||
277 | * and others, ie not under our control. | 279 | * and others, ie not under our control. |
278 | */ | 280 | */ |
279 | 281 | ||
280 | if (!(sisusb = sisusb_get_sisusb(c->vc_num))) | 282 | sisusb = sisusb_get_sisusb(c->vc_num); |
283 | if (!sisusb) | ||
281 | return; | 284 | return; |
282 | 285 | ||
283 | mutex_lock(&sisusb->lock); | 286 | mutex_lock(&sisusb->lock); |
@@ -369,7 +372,8 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | |||
369 | struct sisusb_usb_data *sisusb; | 372 | struct sisusb_usb_data *sisusb; |
370 | ssize_t written; | 373 | ssize_t written; |
371 | 374 | ||
372 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 375 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
376 | if (!sisusb) | ||
373 | return; | 377 | return; |
374 | 378 | ||
375 | /* sisusb->lock is down */ | 379 | /* sisusb->lock is down */ |
@@ -395,7 +399,8 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, | |||
395 | u16 *dest; | 399 | u16 *dest; |
396 | int i; | 400 | int i; |
397 | 401 | ||
398 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 402 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
403 | if (!sisusb) | ||
399 | return; | 404 | return; |
400 | 405 | ||
401 | /* sisusb->lock is down */ | 406 | /* sisusb->lock is down */ |
@@ -433,7 +438,8 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) | |||
433 | if (width <= 0 || height <= 0) | 438 | if (width <= 0 || height <= 0) |
434 | return; | 439 | return; |
435 | 440 | ||
436 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 441 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
442 | if (!sisusb) | ||
437 | return; | 443 | return; |
438 | 444 | ||
439 | /* sisusb->lock is down */ | 445 | /* sisusb->lock is down */ |
@@ -486,7 +492,8 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
486 | if (width <= 0 || height <= 0) | 492 | if (width <= 0 || height <= 0) |
487 | return; | 493 | return; |
488 | 494 | ||
489 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 495 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
496 | if (!sisusb) | ||
490 | return; | 497 | return; |
491 | 498 | ||
492 | /* sisusb->lock is down */ | 499 | /* sisusb->lock is down */ |
@@ -520,7 +527,8 @@ sisusbcon_switch(struct vc_data *c) | |||
520 | * Returnvalue != 0 naturally means the opposite. | 527 | * Returnvalue != 0 naturally means the opposite. |
521 | */ | 528 | */ |
522 | 529 | ||
523 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 530 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
531 | if (!sisusb) | ||
524 | return 0; | 532 | return 0; |
525 | 533 | ||
526 | /* sisusb->lock is down */ | 534 | /* sisusb->lock is down */ |
@@ -569,7 +577,8 @@ sisusbcon_save_screen(struct vc_data *c) | |||
569 | * buffer. | 577 | * buffer. |
570 | */ | 578 | */ |
571 | 579 | ||
572 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 580 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
581 | if (!sisusb) | ||
573 | return; | 582 | return; |
574 | 583 | ||
575 | /* sisusb->lock is down */ | 584 | /* sisusb->lock is down */ |
@@ -602,7 +611,8 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table) | |||
602 | if (!CON_IS_VISIBLE(c)) | 611 | if (!CON_IS_VISIBLE(c)) |
603 | return -EINVAL; | 612 | return -EINVAL; |
604 | 613 | ||
605 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 614 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
615 | if (!sisusb) | ||
606 | return -EINVAL; | 616 | return -EINVAL; |
607 | 617 | ||
608 | /* sisusb->lock is down */ | 618 | /* sisusb->lock is down */ |
@@ -637,7 +647,8 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) | |||
637 | ssize_t written; | 647 | ssize_t written; |
638 | int ret = 0; | 648 | int ret = 0; |
639 | 649 | ||
640 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 650 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
651 | if (!sisusb) | ||
641 | return 0; | 652 | return 0; |
642 | 653 | ||
643 | /* sisusb->lock is down */ | 654 | /* sisusb->lock is down */ |
@@ -721,7 +732,8 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines) | |||
721 | 732 | ||
722 | /* The return value does not seem to be used */ | 733 | /* The return value does not seem to be used */ |
723 | 734 | ||
724 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 735 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
736 | if (!sisusb) | ||
725 | return 0; | 737 | return 0; |
726 | 738 | ||
727 | /* sisusb->lock is down */ | 739 | /* sisusb->lock is down */ |
@@ -779,7 +791,8 @@ sisusbcon_cursor(struct vc_data *c, int mode) | |||
779 | struct sisusb_usb_data *sisusb; | 791 | struct sisusb_usb_data *sisusb; |
780 | int from, to, baseline; | 792 | int from, to, baseline; |
781 | 793 | ||
782 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 794 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
795 | if (!sisusb) | ||
783 | return; | 796 | return; |
784 | 797 | ||
785 | /* sisusb->lock is down */ | 798 | /* sisusb->lock is down */ |
@@ -906,7 +919,8 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines) | |||
906 | if (!lines) | 919 | if (!lines) |
907 | return 1; | 920 | return 1; |
908 | 921 | ||
909 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 922 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
923 | if (!sisusb) | ||
910 | return 0; | 924 | return 0; |
911 | 925 | ||
912 | /* sisusb->lock is down */ | 926 | /* sisusb->lock is down */ |
@@ -1018,7 +1032,8 @@ sisusbcon_set_origin(struct vc_data *c) | |||
1018 | * screenbuffer as the origin. | 1032 | * screenbuffer as the origin. |
1019 | */ | 1033 | */ |
1020 | 1034 | ||
1021 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 1035 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
1036 | if (!sisusb) | ||
1022 | return 0; | 1037 | return 0; |
1023 | 1038 | ||
1024 | /* sisusb->lock is down */ | 1039 | /* sisusb->lock is down */ |
@@ -1047,7 +1062,8 @@ sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows, | |||
1047 | struct sisusb_usb_data *sisusb; | 1062 | struct sisusb_usb_data *sisusb; |
1048 | int fh; | 1063 | int fh; |
1049 | 1064 | ||
1050 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 1065 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
1066 | if (!sisusb) | ||
1051 | return -ENODEV; | 1067 | return -ENODEV; |
1052 | 1068 | ||
1053 | fh = sisusb->current_font_height; | 1069 | fh = sisusb->current_font_height; |
@@ -1286,7 +1302,8 @@ sisusbcon_font_set(struct vc_data *c, struct console_font *font, | |||
1286 | if (font->width != 8 || (charcount != 256 && charcount != 512)) | 1302 | if (font->width != 8 || (charcount != 256 && charcount != 512)) |
1287 | return -EINVAL; | 1303 | return -EINVAL; |
1288 | 1304 | ||
1289 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 1305 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
1306 | if (!sisusb) | ||
1290 | return -ENODEV; | 1307 | return -ENODEV; |
1291 | 1308 | ||
1292 | /* sisusb->lock is down */ | 1309 | /* sisusb->lock is down */ |
@@ -1326,7 +1343,8 @@ sisusbcon_font_get(struct vc_data *c, struct console_font *font) | |||
1326 | { | 1343 | { |
1327 | struct sisusb_usb_data *sisusb; | 1344 | struct sisusb_usb_data *sisusb; |
1328 | 1345 | ||
1329 | if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num))) | 1346 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
1347 | if (!sisusb) | ||
1330 | return -ENODEV; | 1348 | return -ENODEV; |
1331 | 1349 | ||
1332 | /* sisusb->lock is down */ | 1350 | /* sisusb->lock is down */ |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 588d62a73e1a..bbd029c9c725 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -714,7 +714,8 @@ static int uss720_probe(struct usb_interface *intf, | |||
714 | /* | 714 | /* |
715 | * Allocate parport interface | 715 | * Allocate parport interface |
716 | */ | 716 | */ |
717 | if (!(priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) { | 717 | priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL); |
718 | if (!priv) { | ||
718 | usb_put_dev(usbdev); | 719 | usb_put_dev(usbdev); |
719 | return -ENOMEM; | 720 | return -ENOMEM; |
720 | } | 721 | } |
@@ -723,7 +724,8 @@ static int uss720_probe(struct usb_interface *intf, | |||
723 | kref_init(&priv->ref_count); | 724 | kref_init(&priv->ref_count); |
724 | spin_lock_init(&priv->asynclock); | 725 | spin_lock_init(&priv->asynclock); |
725 | INIT_LIST_HEAD(&priv->asynclist); | 726 | INIT_LIST_HEAD(&priv->asynclist); |
726 | if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) { | 727 | pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops); |
728 | if (!pp) { | ||
727 | printk(KERN_WARNING "uss720: could not register parport\n"); | 729 | printk(KERN_WARNING "uss720: could not register parport\n"); |
728 | goto probe_abort; | 730 | goto probe_abort; |
729 | } | 731 | } |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 9a62e89d6dc0..3598f1a62673 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -675,7 +675,8 @@ static int mon_bin_open(struct inode *inode, struct file *file) | |||
675 | int rc; | 675 | int rc; |
676 | 676 | ||
677 | mutex_lock(&mon_lock); | 677 | mutex_lock(&mon_lock); |
678 | if ((mbus = mon_bus_lookup(iminor(inode))) == NULL) { | 678 | mbus = mon_bus_lookup(iminor(inode)); |
679 | if (mbus == NULL) { | ||
679 | mutex_unlock(&mon_lock); | 680 | mutex_unlock(&mon_lock); |
680 | return -ENODEV; | 681 | return -ENODEV; |
681 | } | 682 | } |
@@ -1018,8 +1019,8 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
1018 | return -EINVAL; | 1019 | return -EINVAL; |
1019 | 1020 | ||
1020 | size = CHUNK_ALIGN(arg); | 1021 | size = CHUNK_ALIGN(arg); |
1021 | if ((vec = kzalloc(sizeof(struct mon_pgmap) * (size/CHUNK_SIZE), | 1022 | vec = kzalloc(sizeof(struct mon_pgmap) * (size / CHUNK_SIZE), GFP_KERNEL); |
1022 | GFP_KERNEL)) == NULL) { | 1023 | if (vec == NULL) { |
1023 | ret = -ENOMEM; | 1024 | ret = -ENOMEM; |
1024 | break; | 1025 | break; |
1025 | } | 1026 | } |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 10405119985c..f7c292f4891e 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -96,7 +96,8 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb) | |||
96 | { | 96 | { |
97 | struct mon_bus *mbus; | 97 | struct mon_bus *mbus; |
98 | 98 | ||
99 | if ((mbus = ubus->mon_bus) != NULL) | 99 | mbus = ubus->mon_bus; |
100 | if (mbus != NULL) | ||
100 | mon_bus_submit(mbus, urb); | 101 | mon_bus_submit(mbus, urb); |
101 | mon_bus_submit(&mon_bus0, urb); | 102 | mon_bus_submit(&mon_bus0, urb); |
102 | } | 103 | } |
@@ -122,7 +123,8 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) | |||
122 | { | 123 | { |
123 | struct mon_bus *mbus; | 124 | struct mon_bus *mbus; |
124 | 125 | ||
125 | if ((mbus = ubus->mon_bus) != NULL) | 126 | mbus = ubus->mon_bus; |
127 | if (mbus != NULL) | ||
126 | mon_bus_submit_error(mbus, urb, error); | 128 | mon_bus_submit_error(mbus, urb, error); |
127 | mon_bus_submit_error(&mon_bus0, urb, error); | 129 | mon_bus_submit_error(&mon_bus0, urb, error); |
128 | } | 130 | } |
@@ -148,7 +150,8 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status) | |||
148 | { | 150 | { |
149 | struct mon_bus *mbus; | 151 | struct mon_bus *mbus; |
150 | 152 | ||
151 | if ((mbus = ubus->mon_bus) != NULL) | 153 | mbus = ubus->mon_bus; |
154 | if (mbus != NULL) | ||
152 | mon_bus_complete(mbus, urb, status); | 155 | mon_bus_complete(mbus, urb, status); |
153 | mon_bus_complete(&mon_bus0, urb, status); | 156 | mon_bus_complete(&mon_bus0, urb, status); |
154 | } | 157 | } |
@@ -280,7 +283,8 @@ static void mon_bus_init(struct usb_bus *ubus) | |||
280 | { | 283 | { |
281 | struct mon_bus *mbus; | 284 | struct mon_bus *mbus; |
282 | 285 | ||
283 | if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) | 286 | mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL); |
287 | if (mbus == NULL) | ||
284 | goto err_alloc; | 288 | goto err_alloc; |
285 | kref_init(&mbus->ref); | 289 | kref_init(&mbus->ref); |
286 | spin_lock_init(&mbus->lock); | 290 | spin_lock_init(&mbus->lock); |
diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index ebd6189a5014..5388a339cfb8 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c | |||
@@ -28,7 +28,8 @@ static int mon_stat_open(struct inode *inode, struct file *file) | |||
28 | struct mon_bus *mbus; | 28 | struct mon_bus *mbus; |
29 | struct snap *sp; | 29 | struct snap *sp; |
30 | 30 | ||
31 | if ((sp = kmalloc(sizeof(struct snap), GFP_KERNEL)) == NULL) | 31 | sp = kmalloc(sizeof(struct snap), GFP_KERNEL); |
32 | if (sp == NULL) | ||
32 | return -ENOMEM; | 33 | return -ENOMEM; |
33 | 34 | ||
34 | mbus = inode->i_private; | 35 | mbus = inode->i_private; |
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 220fd4d3b41c..c41fe588d14d 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
@@ -438,11 +438,15 @@ static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
438 | } | 438 | } |
439 | 439 | ||
440 | static const struct musb_platform_ops am35x_ops = { | 440 | static const struct musb_platform_ops am35x_ops = { |
441 | .quirks = MUSB_INDEXED_EP, | 441 | .quirks = MUSB_DMA_INVENTRA | MUSB_INDEXED_EP, |
442 | .init = am35x_musb_init, | 442 | .init = am35x_musb_init, |
443 | .exit = am35x_musb_exit, | 443 | .exit = am35x_musb_exit, |
444 | 444 | ||
445 | .read_fifo = am35x_read_fifo, | 445 | .read_fifo = am35x_read_fifo, |
446 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
447 | .dma_init = musbhs_dma_controller_create, | ||
448 | .dma_exit = musbhs_dma_controller_destroy, | ||
449 | #endif | ||
446 | .enable = am35x_musb_enable, | 450 | .enable = am35x_musb_enable, |
447 | .disable = am35x_musb_disable, | 451 | .disable = am35x_musb_disable, |
448 | 452 | ||
@@ -565,7 +569,7 @@ static int am35x_remove(struct platform_device *pdev) | |||
565 | return 0; | 569 | return 0; |
566 | } | 570 | } |
567 | 571 | ||
568 | #ifdef CONFIG_PM | 572 | #ifdef CONFIG_PM_SLEEP |
569 | static int am35x_suspend(struct device *dev) | 573 | static int am35x_suspend(struct device *dev) |
570 | { | 574 | { |
571 | struct am35x_glue *glue = dev_get_drvdata(dev); | 575 | struct am35x_glue *glue = dev_get_drvdata(dev); |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 6123b748d262..310238c6b5cd 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -465,6 +465,7 @@ static int bfin_musb_exit(struct musb *musb) | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static const struct musb_platform_ops bfin_ops = { | 467 | static const struct musb_platform_ops bfin_ops = { |
468 | .quirks = MUSB_DMA_INVENTRA, | ||
468 | .init = bfin_musb_init, | 469 | .init = bfin_musb_init, |
469 | .exit = bfin_musb_exit, | 470 | .exit = bfin_musb_exit, |
470 | 471 | ||
@@ -477,6 +478,10 @@ static const struct musb_platform_ops bfin_ops = { | |||
477 | .fifo_mode = 2, | 478 | .fifo_mode = 2, |
478 | .read_fifo = bfin_read_fifo, | 479 | .read_fifo = bfin_read_fifo, |
479 | .write_fifo = bfin_write_fifo, | 480 | .write_fifo = bfin_write_fifo, |
481 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
482 | .dma_init = musbhs_dma_controller_create, | ||
483 | .dma_exit = musbhs_dma_controller_destroy, | ||
484 | #endif | ||
480 | .enable = bfin_musb_enable, | 485 | .enable = bfin_musb_enable, |
481 | .disable = bfin_musb_disable, | 486 | .disable = bfin_musb_disable, |
482 | 487 | ||
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 904fb85d85a6..cc134109b056 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -1297,7 +1297,8 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1297 | EXPORT_SYMBOL_GPL(cppi_interrupt); | 1297 | EXPORT_SYMBOL_GPL(cppi_interrupt); |
1298 | 1298 | ||
1299 | /* Instantiate a software object representing a DMA controller. */ | 1299 | /* Instantiate a software object representing a DMA controller. */ |
1300 | struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mregs) | 1300 | struct dma_controller * |
1301 | cppi_dma_controller_create(struct musb *musb, void __iomem *mregs) | ||
1301 | { | 1302 | { |
1302 | struct cppi *controller; | 1303 | struct cppi *controller; |
1303 | struct device *dev = musb->controller; | 1304 | struct device *dev = musb->controller; |
@@ -1334,7 +1335,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr | |||
1334 | if (irq > 0) { | 1335 | if (irq > 0) { |
1335 | if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) { | 1336 | if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) { |
1336 | dev_err(dev, "request_irq %d failed!\n", irq); | 1337 | dev_err(dev, "request_irq %d failed!\n", irq); |
1337 | dma_controller_destroy(&controller->controller); | 1338 | musb_dma_controller_destroy(&controller->controller); |
1338 | return NULL; | 1339 | return NULL; |
1339 | } | 1340 | } |
1340 | controller->irq = irq; | 1341 | controller->irq = irq; |
@@ -1343,11 +1344,12 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr | |||
1343 | cppi_controller_start(controller); | 1344 | cppi_controller_start(controller); |
1344 | return &controller->controller; | 1345 | return &controller->controller; |
1345 | } | 1346 | } |
1347 | EXPORT_SYMBOL_GPL(cppi_dma_controller_create); | ||
1346 | 1348 | ||
1347 | /* | 1349 | /* |
1348 | * Destroy a previously-instantiated DMA controller. | 1350 | * Destroy a previously-instantiated DMA controller. |
1349 | */ | 1351 | */ |
1350 | void dma_controller_destroy(struct dma_controller *c) | 1352 | void cppi_dma_controller_destroy(struct dma_controller *c) |
1351 | { | 1353 | { |
1352 | struct cppi *cppi; | 1354 | struct cppi *cppi; |
1353 | 1355 | ||
@@ -1363,6 +1365,7 @@ void dma_controller_destroy(struct dma_controller *c) | |||
1363 | 1365 | ||
1364 | kfree(cppi); | 1366 | kfree(cppi); |
1365 | } | 1367 | } |
1368 | EXPORT_SYMBOL_GPL(cppi_dma_controller_destroy); | ||
1366 | 1369 | ||
1367 | /* | 1370 | /* |
1368 | * Context: controller irqlocked, endpoint selected | 1371 | * Context: controller irqlocked, endpoint selected |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 9a9c82a4d35d..b03d3b867fca 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -458,11 +458,15 @@ static int da8xx_musb_exit(struct musb *musb) | |||
458 | } | 458 | } |
459 | 459 | ||
460 | static const struct musb_platform_ops da8xx_ops = { | 460 | static const struct musb_platform_ops da8xx_ops = { |
461 | .quirks = MUSB_INDEXED_EP, | 461 | .quirks = MUSB_DMA_CPPI | MUSB_INDEXED_EP, |
462 | .init = da8xx_musb_init, | 462 | .init = da8xx_musb_init, |
463 | .exit = da8xx_musb_exit, | 463 | .exit = da8xx_musb_exit, |
464 | 464 | ||
465 | .fifo_mode = 2, | 465 | .fifo_mode = 2, |
466 | #ifdef CONFIG_USB_TI_CPPI_DMA | ||
467 | .dma_init = cppi_dma_controller_create, | ||
468 | .dma_exit = cppi_dma_controller_destroy, | ||
469 | #endif | ||
466 | .enable = da8xx_musb_enable, | 470 | .enable = da8xx_musb_enable, |
467 | .disable = da8xx_musb_disable, | 471 | .disable = da8xx_musb_disable, |
468 | 472 | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 3c1d9b211b51..cee61a51645e 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -284,7 +284,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) | |||
284 | * mask, state, "vector", and EOI registers. | 284 | * mask, state, "vector", and EOI registers. |
285 | */ | 285 | */ |
286 | cppi = container_of(musb->dma_controller, struct cppi, controller); | 286 | cppi = container_of(musb->dma_controller, struct cppi, controller); |
287 | if (is_cppi_enabled() && musb->dma_controller && !cppi->irq) | 287 | if (is_cppi_enabled(musb) && musb->dma_controller && !cppi->irq) |
288 | retval = cppi_interrupt(irq, __hci); | 288 | retval = cppi_interrupt(irq, __hci); |
289 | 289 | ||
290 | /* ack and handle non-CPPI interrupts */ | 290 | /* ack and handle non-CPPI interrupts */ |
@@ -491,9 +491,14 @@ static int davinci_musb_exit(struct musb *musb) | |||
491 | } | 491 | } |
492 | 492 | ||
493 | static const struct musb_platform_ops davinci_ops = { | 493 | static const struct musb_platform_ops davinci_ops = { |
494 | .quirks = MUSB_DMA_CPPI, | ||
494 | .init = davinci_musb_init, | 495 | .init = davinci_musb_init, |
495 | .exit = davinci_musb_exit, | 496 | .exit = davinci_musb_exit, |
496 | 497 | ||
498 | #ifdef CONFIG_USB_TI_CPPI_DMA | ||
499 | .dma_init = cppi_dma_controller_create, | ||
500 | .dma_exit = cppi_dma_controller_destroy, | ||
501 | #endif | ||
497 | .enable = davinci_musb_enable, | 502 | .enable = davinci_musb_enable, |
498 | .disable = davinci_musb_disable, | 503 | .disable = davinci_musb_disable, |
499 | 504 | ||
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index bb7b26325a74..5e5a8fa005f8 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c | |||
@@ -105,8 +105,12 @@ static int jz4740_musb_exit(struct musb *musb) | |||
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ||
108 | /* | ||
109 | * DMA has not been confirmed to work with CONFIG_USB_INVENTRA_DMA, | ||
110 | * so let's not set up the dma function pointers yet. | ||
111 | */ | ||
108 | static const struct musb_platform_ops jz4740_musb_ops = { | 112 | static const struct musb_platform_ops jz4740_musb_ops = { |
109 | .quirks = MUSB_INDEXED_EP, | 113 | .quirks = MUSB_DMA_INVENTRA | MUSB_INDEXED_EP, |
110 | .fifo_mode = 2, | 114 | .fifo_mode = 2, |
111 | .init = jz4740_musb_init, | 115 | .init = jz4740_musb_init, |
112 | .exit = jz4740_musb_exit, | 116 | .exit = jz4740_musb_exit, |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 6dca3d794ced..514a6cdaeff6 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -251,6 +251,11 @@ static u32 musb_indexed_ep_offset(u8 epnum, u16 offset) | |||
251 | return 0x10 + offset; | 251 | return 0x10 + offset; |
252 | } | 252 | } |
253 | 253 | ||
254 | static u32 musb_default_busctl_offset(u8 epnum, u16 offset) | ||
255 | { | ||
256 | return 0x80 + (0x08 * epnum) + offset; | ||
257 | } | ||
258 | |||
254 | static u8 musb_default_readb(const void __iomem *addr, unsigned offset) | 259 | static u8 musb_default_readb(const void __iomem *addr, unsigned offset) |
255 | { | 260 | { |
256 | return __raw_readb(addr + offset); | 261 | return __raw_readb(addr + offset); |
@@ -309,7 +314,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len, | |||
309 | index += len & ~0x03; | 314 | index += len & ~0x03; |
310 | } | 315 | } |
311 | if (len & 0x02) { | 316 | if (len & 0x02) { |
312 | musb_writew(fifo, 0, *(u16 *)&src[index]); | 317 | __raw_writew(*(u16 *)&src[index], fifo); |
313 | index += 2; | 318 | index += 2; |
314 | } | 319 | } |
315 | } else { | 320 | } else { |
@@ -319,7 +324,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len, | |||
319 | } | 324 | } |
320 | } | 325 | } |
321 | if (len & 0x01) | 326 | if (len & 0x01) |
322 | musb_writeb(fifo, 0, src[index]); | 327 | __raw_writeb(src[index], fifo); |
323 | } else { | 328 | } else { |
324 | /* byte aligned */ | 329 | /* byte aligned */ |
325 | iowrite8_rep(fifo, src, len); | 330 | iowrite8_rep(fifo, src, len); |
@@ -351,7 +356,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
351 | index = len & ~0x03; | 356 | index = len & ~0x03; |
352 | } | 357 | } |
353 | if (len & 0x02) { | 358 | if (len & 0x02) { |
354 | *(u16 *)&dst[index] = musb_readw(fifo, 0); | 359 | *(u16 *)&dst[index] = __raw_readw(fifo); |
355 | index += 2; | 360 | index += 2; |
356 | } | 361 | } |
357 | } else { | 362 | } else { |
@@ -361,7 +366,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
361 | } | 366 | } |
362 | } | 367 | } |
363 | if (len & 0x01) | 368 | if (len & 0x01) |
364 | dst[index] = musb_readb(fifo, 0); | 369 | dst[index] = __raw_readb(fifo); |
365 | } else { | 370 | } else { |
366 | /* byte aligned */ | 371 | /* byte aligned */ |
367 | ioread8_rep(fifo, dst, len); | 372 | ioread8_rep(fifo, dst, len); |
@@ -389,6 +394,15 @@ EXPORT_SYMBOL_GPL(musb_readl); | |||
389 | void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data); | 394 | void (*musb_writel)(void __iomem *addr, unsigned offset, u32 data); |
390 | EXPORT_SYMBOL_GPL(musb_writel); | 395 | EXPORT_SYMBOL_GPL(musb_writel); |
391 | 396 | ||
397 | #ifndef CONFIG_MUSB_PIO_ONLY | ||
398 | struct dma_controller * | ||
399 | (*musb_dma_controller_create)(struct musb *musb, void __iomem *base); | ||
400 | EXPORT_SYMBOL(musb_dma_controller_create); | ||
401 | |||
402 | void (*musb_dma_controller_destroy)(struct dma_controller *c); | ||
403 | EXPORT_SYMBOL(musb_dma_controller_destroy); | ||
404 | #endif | ||
405 | |||
392 | /* | 406 | /* |
393 | * New style IO functions | 407 | * New style IO functions |
394 | */ | 408 | */ |
@@ -1535,7 +1549,6 @@ static int musb_core_init(u16 musb_type, struct musb *musb) | |||
1535 | #endif | 1549 | #endif |
1536 | 1550 | ||
1537 | hw_ep->regs = musb->io.ep_offset(i, 0) + mbase; | 1551 | hw_ep->regs = musb->io.ep_offset(i, 0) + mbase; |
1538 | hw_ep->target_regs = musb_read_target_reg_base(i, mbase); | ||
1539 | hw_ep->rx_reinit = 1; | 1552 | hw_ep->rx_reinit = 1; |
1540 | hw_ep->tx_reinit = 1; | 1553 | hw_ep->tx_reinit = 1; |
1541 | 1554 | ||
@@ -1658,15 +1671,13 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) | |||
1658 | /* called with controller lock already held */ | 1671 | /* called with controller lock already held */ |
1659 | 1672 | ||
1660 | if (!epnum) { | 1673 | if (!epnum) { |
1661 | #ifndef CONFIG_USB_TUSB_OMAP_DMA | 1674 | if (!is_cppi_enabled(musb)) { |
1662 | if (!is_cppi_enabled()) { | ||
1663 | /* endpoint 0 */ | 1675 | /* endpoint 0 */ |
1664 | if (is_host_active(musb)) | 1676 | if (is_host_active(musb)) |
1665 | musb_h_ep0_irq(musb); | 1677 | musb_h_ep0_irq(musb); |
1666 | else | 1678 | else |
1667 | musb_g_ep0_irq(musb); | 1679 | musb_g_ep0_irq(musb); |
1668 | } | 1680 | } |
1669 | #endif | ||
1670 | } else { | 1681 | } else { |
1671 | /* endpoints 1..15 */ | 1682 | /* endpoints 1..15 */ |
1672 | if (transmit) { | 1683 | if (transmit) { |
@@ -2029,6 +2040,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2029 | musb->io.ep_offset = musb_flat_ep_offset; | 2040 | musb->io.ep_offset = musb_flat_ep_offset; |
2030 | musb->io.ep_select = musb_flat_ep_select; | 2041 | musb->io.ep_select = musb_flat_ep_select; |
2031 | } | 2042 | } |
2043 | /* And override them with platform specific ops if specified. */ | ||
2044 | if (musb->ops->ep_offset) | ||
2045 | musb->io.ep_offset = musb->ops->ep_offset; | ||
2046 | if (musb->ops->ep_select) | ||
2047 | musb->io.ep_select = musb->ops->ep_select; | ||
2032 | 2048 | ||
2033 | /* At least tusb6010 has its own offsets */ | 2049 | /* At least tusb6010 has its own offsets */ |
2034 | if (musb->ops->ep_offset) | 2050 | if (musb->ops->ep_offset) |
@@ -2046,6 +2062,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2046 | else | 2062 | else |
2047 | musb->io.fifo_offset = musb_default_fifo_offset; | 2063 | musb->io.fifo_offset = musb_default_fifo_offset; |
2048 | 2064 | ||
2065 | if (musb->ops->busctl_offset) | ||
2066 | musb->io.busctl_offset = musb->ops->busctl_offset; | ||
2067 | else | ||
2068 | musb->io.busctl_offset = musb_default_busctl_offset; | ||
2069 | |||
2049 | if (musb->ops->readb) | 2070 | if (musb->ops->readb) |
2050 | musb_readb = musb->ops->readb; | 2071 | musb_readb = musb->ops->readb; |
2051 | if (musb->ops->writeb) | 2072 | if (musb->ops->writeb) |
@@ -2059,6 +2080,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2059 | if (musb->ops->writel) | 2080 | if (musb->ops->writel) |
2060 | musb_writel = musb->ops->writel; | 2081 | musb_writel = musb->ops->writel; |
2061 | 2082 | ||
2083 | #ifndef CONFIG_MUSB_PIO_ONLY | ||
2084 | if (!musb->ops->dma_init || !musb->ops->dma_exit) { | ||
2085 | dev_err(dev, "DMA controller not set\n"); | ||
2086 | goto fail2; | ||
2087 | } | ||
2088 | musb_dma_controller_create = musb->ops->dma_init; | ||
2089 | musb_dma_controller_destroy = musb->ops->dma_exit; | ||
2090 | #endif | ||
2091 | |||
2062 | if (musb->ops->read_fifo) | 2092 | if (musb->ops->read_fifo) |
2063 | musb->io.read_fifo = musb->ops->read_fifo; | 2093 | musb->io.read_fifo = musb->ops->read_fifo; |
2064 | else | 2094 | else |
@@ -2078,7 +2108,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2078 | pm_runtime_get_sync(musb->controller); | 2108 | pm_runtime_get_sync(musb->controller); |
2079 | 2109 | ||
2080 | if (use_dma && dev->dma_mask) { | 2110 | if (use_dma && dev->dma_mask) { |
2081 | musb->dma_controller = dma_controller_create(musb, musb->mregs); | 2111 | musb->dma_controller = |
2112 | musb_dma_controller_create(musb, musb->mregs); | ||
2082 | if (IS_ERR(musb->dma_controller)) { | 2113 | if (IS_ERR(musb->dma_controller)) { |
2083 | status = PTR_ERR(musb->dma_controller); | 2114 | status = PTR_ERR(musb->dma_controller); |
2084 | goto fail2_5; | 2115 | goto fail2_5; |
@@ -2189,7 +2220,7 @@ fail3: | |||
2189 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2220 | cancel_delayed_work_sync(&musb->finish_resume_work); |
2190 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2221 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
2191 | if (musb->dma_controller) | 2222 | if (musb->dma_controller) |
2192 | dma_controller_destroy(musb->dma_controller); | 2223 | musb_dma_controller_destroy(musb->dma_controller); |
2193 | fail2_5: | 2224 | fail2_5: |
2194 | pm_runtime_put_sync(musb->controller); | 2225 | pm_runtime_put_sync(musb->controller); |
2195 | 2226 | ||
@@ -2248,7 +2279,7 @@ static int musb_remove(struct platform_device *pdev) | |||
2248 | musb_shutdown(pdev); | 2279 | musb_shutdown(pdev); |
2249 | 2280 | ||
2250 | if (musb->dma_controller) | 2281 | if (musb->dma_controller) |
2251 | dma_controller_destroy(musb->dma_controller); | 2282 | musb_dma_controller_destroy(musb->dma_controller); |
2252 | 2283 | ||
2253 | cancel_work_sync(&musb->irq_work); | 2284 | cancel_work_sync(&musb->irq_work); |
2254 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2285 | cancel_delayed_work_sync(&musb->finish_resume_work); |
@@ -2316,18 +2347,18 @@ static void musb_save_context(struct musb *musb) | |||
2316 | musb_readb(epio, MUSB_RXINTERVAL); | 2347 | musb_readb(epio, MUSB_RXINTERVAL); |
2317 | 2348 | ||
2318 | musb->context.index_regs[i].txfunaddr = | 2349 | musb->context.index_regs[i].txfunaddr = |
2319 | musb_read_txfunaddr(musb_base, i); | 2350 | musb_read_txfunaddr(musb, i); |
2320 | musb->context.index_regs[i].txhubaddr = | 2351 | musb->context.index_regs[i].txhubaddr = |
2321 | musb_read_txhubaddr(musb_base, i); | 2352 | musb_read_txhubaddr(musb, i); |
2322 | musb->context.index_regs[i].txhubport = | 2353 | musb->context.index_regs[i].txhubport = |
2323 | musb_read_txhubport(musb_base, i); | 2354 | musb_read_txhubport(musb, i); |
2324 | 2355 | ||
2325 | musb->context.index_regs[i].rxfunaddr = | 2356 | musb->context.index_regs[i].rxfunaddr = |
2326 | musb_read_rxfunaddr(musb_base, i); | 2357 | musb_read_rxfunaddr(musb, i); |
2327 | musb->context.index_regs[i].rxhubaddr = | 2358 | musb->context.index_regs[i].rxhubaddr = |
2328 | musb_read_rxhubaddr(musb_base, i); | 2359 | musb_read_rxhubaddr(musb, i); |
2329 | musb->context.index_regs[i].rxhubport = | 2360 | musb->context.index_regs[i].rxhubport = |
2330 | musb_read_rxhubport(musb_base, i); | 2361 | musb_read_rxhubport(musb, i); |
2331 | } | 2362 | } |
2332 | } | 2363 | } |
2333 | 2364 | ||
@@ -2335,7 +2366,6 @@ static void musb_restore_context(struct musb *musb) | |||
2335 | { | 2366 | { |
2336 | int i; | 2367 | int i; |
2337 | void __iomem *musb_base = musb->mregs; | 2368 | void __iomem *musb_base = musb->mregs; |
2338 | void __iomem *ep_target_regs; | ||
2339 | void __iomem *epio; | 2369 | void __iomem *epio; |
2340 | u8 power; | 2370 | u8 power; |
2341 | 2371 | ||
@@ -2396,21 +2426,18 @@ static void musb_restore_context(struct musb *musb) | |||
2396 | musb_writeb(epio, MUSB_RXINTERVAL, | 2426 | musb_writeb(epio, MUSB_RXINTERVAL, |
2397 | 2427 | ||
2398 | musb->context.index_regs[i].rxinterval); | 2428 | musb->context.index_regs[i].rxinterval); |
2399 | musb_write_txfunaddr(musb_base, i, | 2429 | musb_write_txfunaddr(musb, i, |
2400 | musb->context.index_regs[i].txfunaddr); | 2430 | musb->context.index_regs[i].txfunaddr); |
2401 | musb_write_txhubaddr(musb_base, i, | 2431 | musb_write_txhubaddr(musb, i, |
2402 | musb->context.index_regs[i].txhubaddr); | 2432 | musb->context.index_regs[i].txhubaddr); |
2403 | musb_write_txhubport(musb_base, i, | 2433 | musb_write_txhubport(musb, i, |
2404 | musb->context.index_regs[i].txhubport); | 2434 | musb->context.index_regs[i].txhubport); |
2405 | 2435 | ||
2406 | ep_target_regs = | 2436 | musb_write_rxfunaddr(musb, i, |
2407 | musb_read_target_reg_base(i, musb_base); | ||
2408 | |||
2409 | musb_write_rxfunaddr(ep_target_regs, | ||
2410 | musb->context.index_regs[i].rxfunaddr); | 2437 | musb->context.index_regs[i].rxfunaddr); |
2411 | musb_write_rxhubaddr(ep_target_regs, | 2438 | musb_write_rxhubaddr(musb, i, |
2412 | musb->context.index_regs[i].rxhubaddr); | 2439 | musb->context.index_regs[i].rxhubaddr); |
2413 | musb_write_rxhubport(ep_target_regs, | 2440 | musb_write_rxhubport(musb, i, |
2414 | musb->context.index_regs[i].rxhubport); | 2441 | musb->context.index_regs[i].rxhubport); |
2415 | } | 2442 | } |
2416 | musb_writeb(musb_base, MUSB_INDEX, musb->context.index); | 2443 | musb_writeb(musb_base, MUSB_INDEX, musb->context.index); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 3877249a8b2d..4b886d0f6bdf 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -67,7 +67,6 @@ struct musb_ep; | |||
67 | #include "musb_dma.h" | 67 | #include "musb_dma.h" |
68 | 68 | ||
69 | #include "musb_io.h" | 69 | #include "musb_io.h" |
70 | #include "musb_regs.h" | ||
71 | 70 | ||
72 | #include "musb_gadget.h" | 71 | #include "musb_gadget.h" |
73 | #include <linux/usb/hcd.h> | 72 | #include <linux/usb/hcd.h> |
@@ -157,6 +156,8 @@ struct musb_io; | |||
157 | * @writel: write 32 bits | 156 | * @writel: write 32 bits |
158 | * @read_fifo: reads the fifo | 157 | * @read_fifo: reads the fifo |
159 | * @write_fifo: writes to fifo | 158 | * @write_fifo: writes to fifo |
159 | * @dma_init: platform specific dma init function | ||
160 | * @dma_exit: platform specific dma exit function | ||
160 | * @init: turns on clocks, sets up platform-specific registers, etc | 161 | * @init: turns on clocks, sets up platform-specific registers, etc |
161 | * @exit: undoes @init | 162 | * @exit: undoes @init |
162 | * @set_mode: forcefully changes operating mode | 163 | * @set_mode: forcefully changes operating mode |
@@ -165,6 +166,8 @@ struct musb_io; | |||
165 | * @vbus_status: returns vbus status if possible | 166 | * @vbus_status: returns vbus status if possible |
166 | * @set_vbus: forces vbus status | 167 | * @set_vbus: forces vbus status |
167 | * @adjust_channel_params: pre check for standard dma channel_program func | 168 | * @adjust_channel_params: pre check for standard dma channel_program func |
169 | * @pre_root_reset_end: called before the root usb port reset flag gets cleared | ||
170 | * @post_root_reset_end: called after the root usb port reset flag gets cleared | ||
168 | */ | 171 | */ |
169 | struct musb_platform_ops { | 172 | struct musb_platform_ops { |
170 | 173 | ||
@@ -187,6 +190,7 @@ struct musb_platform_ops { | |||
187 | void (*ep_select)(void __iomem *mbase, u8 epnum); | 190 | void (*ep_select)(void __iomem *mbase, u8 epnum); |
188 | u16 fifo_mode; | 191 | u16 fifo_mode; |
189 | u32 (*fifo_offset)(u8 epnum); | 192 | u32 (*fifo_offset)(u8 epnum); |
193 | u32 (*busctl_offset)(u8 epnum, u16 offset); | ||
190 | u8 (*readb)(const void __iomem *addr, unsigned offset); | 194 | u8 (*readb)(const void __iomem *addr, unsigned offset); |
191 | void (*writeb)(void __iomem *addr, unsigned offset, u8 data); | 195 | void (*writeb)(void __iomem *addr, unsigned offset, u8 data); |
192 | u16 (*readw)(const void __iomem *addr, unsigned offset); | 196 | u16 (*readw)(const void __iomem *addr, unsigned offset); |
@@ -195,6 +199,9 @@ struct musb_platform_ops { | |||
195 | void (*writel)(void __iomem *addr, unsigned offset, u32 data); | 199 | void (*writel)(void __iomem *addr, unsigned offset, u32 data); |
196 | void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); | 200 | void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); |
197 | void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); | 201 | void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); |
202 | struct dma_controller * | ||
203 | (*dma_init) (struct musb *musb, void __iomem *base); | ||
204 | void (*dma_exit)(struct dma_controller *c); | ||
198 | int (*set_mode)(struct musb *musb, u8 mode); | 205 | int (*set_mode)(struct musb *musb, u8 mode); |
199 | void (*try_idle)(struct musb *musb, unsigned long timeout); | 206 | void (*try_idle)(struct musb *musb, unsigned long timeout); |
200 | int (*recover)(struct musb *musb); | 207 | int (*recover)(struct musb *musb); |
@@ -205,6 +212,8 @@ struct musb_platform_ops { | |||
205 | int (*adjust_channel_params)(struct dma_channel *channel, | 212 | int (*adjust_channel_params)(struct dma_channel *channel, |
206 | u16 packet_sz, u8 *mode, | 213 | u16 packet_sz, u8 *mode, |
207 | dma_addr_t *dma_addr, u32 *len); | 214 | dma_addr_t *dma_addr, u32 *len); |
215 | void (*pre_root_reset_end)(struct musb *musb); | ||
216 | void (*post_root_reset_end)(struct musb *musb); | ||
208 | }; | 217 | }; |
209 | 218 | ||
210 | /* | 219 | /* |
@@ -241,8 +250,6 @@ struct musb_hw_ep { | |||
241 | void __iomem *fifo_sync_va; | 250 | void __iomem *fifo_sync_va; |
242 | #endif | 251 | #endif |
243 | 252 | ||
244 | void __iomem *target_regs; | ||
245 | |||
246 | /* currently scheduled peripheral endpoint */ | 253 | /* currently scheduled peripheral endpoint */ |
247 | struct musb_qh *in_qh; | 254 | struct musb_qh *in_qh; |
248 | struct musb_qh *out_qh; | 255 | struct musb_qh *out_qh; |
@@ -437,6 +444,9 @@ struct musb { | |||
437 | #endif | 444 | #endif |
438 | }; | 445 | }; |
439 | 446 | ||
447 | /* This must be included after struct musb is defined */ | ||
448 | #include "musb_regs.h" | ||
449 | |||
440 | static inline struct musb *gadget_to_musb(struct usb_gadget *g) | 450 | static inline struct musb *gadget_to_musb(struct usb_gadget *g) |
441 | { | 451 | { |
442 | return container_of(g, struct musb, g); | 452 | return container_of(g, struct musb, g); |
@@ -590,4 +600,16 @@ static inline int musb_platform_exit(struct musb *musb) | |||
590 | return musb->ops->exit(musb); | 600 | return musb->ops->exit(musb); |
591 | } | 601 | } |
592 | 602 | ||
603 | static inline void musb_platform_pre_root_reset_end(struct musb *musb) | ||
604 | { | ||
605 | if (musb->ops->pre_root_reset_end) | ||
606 | musb->ops->pre_root_reset_end(musb); | ||
607 | } | ||
608 | |||
609 | static inline void musb_platform_post_root_reset_end(struct musb *musb) | ||
610 | { | ||
611 | if (musb->ops->post_root_reset_end) | ||
612 | musb->ops->post_root_reset_end(musb); | ||
613 | } | ||
614 | |||
593 | #endif /* __MUSB_CORE_H__ */ | 615 | #endif /* __MUSB_CORE_H__ */ |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 8bd8c5e26921..4d1b44c232ee 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -678,7 +678,7 @@ err: | |||
678 | return ret; | 678 | return ret; |
679 | } | 679 | } |
680 | 680 | ||
681 | void dma_controller_destroy(struct dma_controller *c) | 681 | void cppi41_dma_controller_destroy(struct dma_controller *c) |
682 | { | 682 | { |
683 | struct cppi41_dma_controller *controller = container_of(c, | 683 | struct cppi41_dma_controller *controller = container_of(c, |
684 | struct cppi41_dma_controller, controller); | 684 | struct cppi41_dma_controller, controller); |
@@ -687,9 +687,10 @@ void dma_controller_destroy(struct dma_controller *c) | |||
687 | cppi41_dma_controller_stop(controller); | 687 | cppi41_dma_controller_stop(controller); |
688 | kfree(controller); | 688 | kfree(controller); |
689 | } | 689 | } |
690 | EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy); | ||
690 | 691 | ||
691 | struct dma_controller *dma_controller_create(struct musb *musb, | 692 | struct dma_controller * |
692 | void __iomem *base) | 693 | cppi41_dma_controller_create(struct musb *musb, void __iomem *base) |
693 | { | 694 | { |
694 | struct cppi41_dma_controller *controller; | 695 | struct cppi41_dma_controller *controller; |
695 | int ret = 0; | 696 | int ret = 0; |
@@ -726,3 +727,4 @@ kzalloc_fail: | |||
726 | return ERR_PTR(ret); | 727 | return ERR_PTR(ret); |
727 | return NULL; | 728 | return NULL; |
728 | } | 729 | } |
730 | EXPORT_SYMBOL_GPL(cppi41_dma_controller_create); | ||
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 78a283e9ce40..9b22d946c089 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -191,9 +191,16 @@ static ssize_t musb_test_mode_write(struct file *file, | |||
191 | { | 191 | { |
192 | struct seq_file *s = file->private_data; | 192 | struct seq_file *s = file->private_data; |
193 | struct musb *musb = s->private; | 193 | struct musb *musb = s->private; |
194 | u8 test = 0; | 194 | u8 test; |
195 | char buf[18]; | 195 | char buf[18]; |
196 | 196 | ||
197 | test = musb_readb(musb->mregs, MUSB_TESTMODE); | ||
198 | if (test) { | ||
199 | dev_err(musb->controller, "Error: test mode is already set. " | ||
200 | "Please do USB Bus Reset to start a new test.\n"); | ||
201 | return count; | ||
202 | } | ||
203 | |||
197 | memset(buf, 0x00, sizeof(buf)); | 204 | memset(buf, 0x00, sizeof(buf)); |
198 | 205 | ||
199 | if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 206 | if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
@@ -238,6 +245,90 @@ static const struct file_operations musb_test_mode_fops = { | |||
238 | .release = single_release, | 245 | .release = single_release, |
239 | }; | 246 | }; |
240 | 247 | ||
248 | static int musb_softconnect_show(struct seq_file *s, void *unused) | ||
249 | { | ||
250 | struct musb *musb = s->private; | ||
251 | u8 reg; | ||
252 | int connect; | ||
253 | |||
254 | switch (musb->xceiv->otg->state) { | ||
255 | case OTG_STATE_A_HOST: | ||
256 | case OTG_STATE_A_WAIT_BCON: | ||
257 | reg = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
258 | connect = reg & MUSB_DEVCTL_SESSION ? 1 : 0; | ||
259 | break; | ||
260 | default: | ||
261 | connect = -1; | ||
262 | } | ||
263 | |||
264 | seq_printf(s, "%d\n", connect); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static int musb_softconnect_open(struct inode *inode, struct file *file) | ||
270 | { | ||
271 | return single_open(file, musb_softconnect_show, inode->i_private); | ||
272 | } | ||
273 | |||
274 | static ssize_t musb_softconnect_write(struct file *file, | ||
275 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
276 | { | ||
277 | struct seq_file *s = file->private_data; | ||
278 | struct musb *musb = s->private; | ||
279 | char buf[2]; | ||
280 | u8 reg; | ||
281 | |||
282 | memset(buf, 0x00, sizeof(buf)); | ||
283 | |||
284 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
285 | return -EFAULT; | ||
286 | |||
287 | if (!strncmp(buf, "0", 1)) { | ||
288 | switch (musb->xceiv->otg->state) { | ||
289 | case OTG_STATE_A_HOST: | ||
290 | musb_root_disconnect(musb); | ||
291 | reg = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
292 | reg &= ~MUSB_DEVCTL_SESSION; | ||
293 | musb_writeb(musb->mregs, MUSB_DEVCTL, reg); | ||
294 | break; | ||
295 | default: | ||
296 | break; | ||
297 | } | ||
298 | } else if (!strncmp(buf, "1", 1)) { | ||
299 | switch (musb->xceiv->otg->state) { | ||
300 | case OTG_STATE_A_WAIT_BCON: | ||
301 | /* | ||
302 | * musb_save_context() called in musb_runtime_suspend() | ||
303 | * might cache devctl with SESSION bit cleared during | ||
304 | * soft-disconnect, so specifically set SESSION bit | ||
305 | * here to preserve it for musb_runtime_resume(). | ||
306 | */ | ||
307 | musb->context.devctl |= MUSB_DEVCTL_SESSION; | ||
308 | reg = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
309 | reg |= MUSB_DEVCTL_SESSION; | ||
310 | musb_writeb(musb->mregs, MUSB_DEVCTL, reg); | ||
311 | break; | ||
312 | default: | ||
313 | break; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | return count; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * In host mode, connect/disconnect the bus without physically | ||
322 | * remove the devices. | ||
323 | */ | ||
324 | static const struct file_operations musb_softconnect_fops = { | ||
325 | .open = musb_softconnect_open, | ||
326 | .write = musb_softconnect_write, | ||
327 | .read = seq_read, | ||
328 | .llseek = seq_lseek, | ||
329 | .release = single_release, | ||
330 | }; | ||
331 | |||
241 | int musb_init_debugfs(struct musb *musb) | 332 | int musb_init_debugfs(struct musb *musb) |
242 | { | 333 | { |
243 | struct dentry *root; | 334 | struct dentry *root; |
@@ -264,6 +355,13 @@ int musb_init_debugfs(struct musb *musb) | |||
264 | goto err1; | 355 | goto err1; |
265 | } | 356 | } |
266 | 357 | ||
358 | file = debugfs_create_file("softconnect", S_IRUGO | S_IWUSR, | ||
359 | root, musb, &musb_softconnect_fops); | ||
360 | if (!file) { | ||
361 | ret = -ENOMEM; | ||
362 | goto err1; | ||
363 | } | ||
364 | |||
267 | musb->debugfs_root = root; | 365 | musb->debugfs_root = root; |
268 | 366 | ||
269 | return 0; | 367 | return 0; |
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 1d44faa86252..46357e183b4c 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h | |||
@@ -68,16 +68,41 @@ struct musb_hw_ep; | |||
68 | #define is_dma_capable() (1) | 68 | #define is_dma_capable() (1) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #if defined(CONFIG_USB_TI_CPPI_DMA) || defined(CONFIG_USB_TI_CPPI41_DMA) | 71 | #ifdef CONFIG_USB_UX500_DMA |
72 | #define is_cppi_enabled() 1 | 72 | #define musb_dma_ux500(musb) (musb->io.quirks & MUSB_DMA_UX500) |
73 | #else | ||
74 | #define musb_dma_ux500(musb) 0 | ||
75 | #endif | ||
76 | |||
77 | #ifdef CONFIG_USB_TI_CPPI41_DMA | ||
78 | #define musb_dma_cppi41(musb) (musb->io.quirks & MUSB_DMA_CPPI41) | ||
79 | #else | ||
80 | #define musb_dma_cppi41(musb) 0 | ||
81 | #endif | ||
82 | |||
83 | #ifdef CONFIG_USB_TI_CPPI_DMA | ||
84 | #define musb_dma_cppi(musb) (musb->io.quirks & MUSB_DMA_CPPI) | ||
73 | #else | 85 | #else |
74 | #define is_cppi_enabled() 0 | 86 | #define musb_dma_cppi(musb) 0 |
75 | #endif | 87 | #endif |
76 | 88 | ||
77 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 89 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
78 | #define tusb_dma_omap() 1 | 90 | #define tusb_dma_omap(musb) (musb->io.quirks & MUSB_DMA_TUSB_OMAP) |
91 | #else | ||
92 | #define tusb_dma_omap(musb) 0 | ||
93 | #endif | ||
94 | |||
95 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
96 | #define musb_dma_inventra(musb) (musb->io.quirks & MUSB_DMA_INVENTRA) | ||
79 | #else | 97 | #else |
80 | #define tusb_dma_omap() 0 | 98 | #define musb_dma_inventra(musb) 0 |
99 | #endif | ||
100 | |||
101 | #if defined(CONFIG_USB_TI_CPPI_DMA) || defined(CONFIG_USB_TI_CPPI41_DMA) | ||
102 | #define is_cppi_enabled(musb) \ | ||
103 | (musb_dma_cppi(musb) || musb_dma_cppi41(musb)) | ||
104 | #else | ||
105 | #define is_cppi_enabled(musb) 0 | ||
81 | #endif | 106 | #endif |
82 | 107 | ||
83 | /* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1 | 108 | /* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1 |
@@ -177,19 +202,41 @@ struct dma_controller { | |||
177 | extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit); | 202 | extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit); |
178 | 203 | ||
179 | #ifdef CONFIG_MUSB_PIO_ONLY | 204 | #ifdef CONFIG_MUSB_PIO_ONLY |
180 | static inline struct dma_controller *dma_controller_create(struct musb *m, | 205 | static inline struct dma_controller * |
181 | void __iomem *io) | 206 | musb_dma_controller_create(struct musb *m, void __iomem *io) |
182 | { | 207 | { |
183 | return NULL; | 208 | return NULL; |
184 | } | 209 | } |
185 | 210 | ||
186 | static inline void dma_controller_destroy(struct dma_controller *d) { } | 211 | static inline void musb_dma_controller_destroy(struct dma_controller *d) { } |
187 | 212 | ||
188 | #else | 213 | #else |
189 | 214 | ||
190 | extern struct dma_controller *dma_controller_create(struct musb *, void __iomem *); | 215 | extern struct dma_controller * |
216 | (*musb_dma_controller_create)(struct musb *, void __iomem *); | ||
191 | 217 | ||
192 | extern void dma_controller_destroy(struct dma_controller *); | 218 | extern void (*musb_dma_controller_destroy)(struct dma_controller *); |
193 | #endif | 219 | #endif |
194 | 220 | ||
221 | /* Platform specific DMA functions */ | ||
222 | extern struct dma_controller * | ||
223 | musbhs_dma_controller_create(struct musb *musb, void __iomem *base); | ||
224 | extern void musbhs_dma_controller_destroy(struct dma_controller *c); | ||
225 | |||
226 | extern struct dma_controller * | ||
227 | tusb_dma_controller_create(struct musb *musb, void __iomem *base); | ||
228 | extern void tusb_dma_controller_destroy(struct dma_controller *c); | ||
229 | |||
230 | extern struct dma_controller * | ||
231 | cppi_dma_controller_create(struct musb *musb, void __iomem *base); | ||
232 | extern void cppi_dma_controller_destroy(struct dma_controller *c); | ||
233 | |||
234 | extern struct dma_controller * | ||
235 | cppi41_dma_controller_create(struct musb *musb, void __iomem *base); | ||
236 | extern void cppi41_dma_controller_destroy(struct dma_controller *c); | ||
237 | |||
238 | extern struct dma_controller * | ||
239 | ux500_dma_controller_create(struct musb *musb, void __iomem *base); | ||
240 | extern void ux500_dma_controller_destroy(struct dma_controller *c); | ||
241 | |||
195 | #endif /* __MUSB_DMA_H__ */ | 242 | #endif /* __MUSB_DMA_H__ */ |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 65d931a28a14..1334a3de31b8 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -634,10 +634,14 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
634 | } | 634 | } |
635 | 635 | ||
636 | static struct musb_platform_ops dsps_ops = { | 636 | static struct musb_platform_ops dsps_ops = { |
637 | .quirks = MUSB_INDEXED_EP, | 637 | .quirks = MUSB_DMA_CPPI41 | MUSB_INDEXED_EP, |
638 | .init = dsps_musb_init, | 638 | .init = dsps_musb_init, |
639 | .exit = dsps_musb_exit, | 639 | .exit = dsps_musb_exit, |
640 | 640 | ||
641 | #ifdef CONFIG_USB_TI_CPPI41_DMA | ||
642 | .dma_init = cppi41_dma_controller_create, | ||
643 | .dma_exit = cppi41_dma_controller_destroy, | ||
644 | #endif | ||
641 | .enable = dsps_musb_enable, | 645 | .enable = dsps_musb_enable, |
642 | .disable = dsps_musb_disable, | 646 | .disable = dsps_musb_disable, |
643 | 647 | ||
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 4c481cd66c77..625d482f1a97 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -366,7 +366,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
366 | } | 366 | } |
367 | 367 | ||
368 | #endif | 368 | #endif |
369 | if (is_cppi_enabled()) { | 369 | if (is_cppi_enabled(musb)) { |
370 | /* program endpoint CSR first, then setup DMA */ | 370 | /* program endpoint CSR first, then setup DMA */ |
371 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); | 371 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); |
372 | csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE | | 372 | csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE | |
@@ -402,7 +402,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
402 | musb_writew(epio, MUSB_TXCSR, csr); | 402 | musb_writew(epio, MUSB_TXCSR, csr); |
403 | /* invariant: prequest->buf is non-null */ | 403 | /* invariant: prequest->buf is non-null */ |
404 | } | 404 | } |
405 | } else if (tusb_dma_omap()) | 405 | } else if (tusb_dma_omap(musb)) |
406 | use_dma = use_dma && c->channel_program( | 406 | use_dma = use_dma && c->channel_program( |
407 | musb_ep->dma, musb_ep->packet_sz, | 407 | musb_ep->dma, musb_ep->packet_sz, |
408 | request->zero, | 408 | request->zero, |
@@ -489,6 +489,7 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
489 | 489 | ||
490 | if (request) { | 490 | if (request) { |
491 | u8 is_dma = 0; | 491 | u8 is_dma = 0; |
492 | bool short_packet = false; | ||
492 | 493 | ||
493 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { | 494 | if (dma && (csr & MUSB_TXCSR_DMAENAB)) { |
494 | is_dma = 1; | 495 | is_dma = 1; |
@@ -507,15 +508,18 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
507 | * First, maybe a terminating short packet. Some DMA | 508 | * First, maybe a terminating short packet. Some DMA |
508 | * engines might handle this by themselves. | 509 | * engines might handle this by themselves. |
509 | */ | 510 | */ |
510 | if ((request->zero && request->length | 511 | if ((request->zero && request->length) |
511 | && (request->length % musb_ep->packet_sz == 0) | 512 | && (request->length % musb_ep->packet_sz == 0) |
512 | && (request->actual == request->length)) | 513 | && (request->actual == request->length)) |
513 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) | 514 | short_packet = true; |
514 | || (is_dma && (!dma->desired_mode || | 515 | |
516 | if ((musb_dma_inventra(musb) || musb_dma_ux500(musb)) && | ||
517 | (is_dma && (!dma->desired_mode || | ||
515 | (request->actual & | 518 | (request->actual & |
516 | (musb_ep->packet_sz - 1)))) | 519 | (musb_ep->packet_sz - 1))))) |
517 | #endif | 520 | short_packet = true; |
518 | ) { | 521 | |
522 | if (short_packet) { | ||
519 | /* | 523 | /* |
520 | * On DMA completion, FIFO may not be | 524 | * On DMA completion, FIFO may not be |
521 | * available yet... | 525 | * available yet... |
@@ -595,7 +599,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
595 | return; | 599 | return; |
596 | } | 600 | } |
597 | 601 | ||
598 | if (is_cppi_enabled() && is_buffer_mapped(req)) { | 602 | if (is_cppi_enabled(musb) && is_buffer_mapped(req)) { |
599 | struct dma_controller *c = musb->dma_controller; | 603 | struct dma_controller *c = musb->dma_controller; |
600 | struct dma_channel *channel = musb_ep->dma; | 604 | struct dma_channel *channel = musb_ep->dma; |
601 | 605 | ||
@@ -772,7 +776,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
772 | fifo_count = min_t(unsigned, len, fifo_count); | 776 | fifo_count = min_t(unsigned, len, fifo_count); |
773 | 777 | ||
774 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 778 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
775 | if (tusb_dma_omap() && is_buffer_mapped(req)) { | 779 | if (tusb_dma_omap(musb) && is_buffer_mapped(req)) { |
776 | struct dma_controller *c = musb->dma_controller; | 780 | struct dma_controller *c = musb->dma_controller; |
777 | struct dma_channel *channel = musb_ep->dma; | 781 | struct dma_channel *channel = musb_ep->dma; |
778 | u32 dma_addr = request->dma + request->actual; | 782 | u32 dma_addr = request->dma + request->actual; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index c3d5fc9dfb5b..26c65e66cc0f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -181,7 +181,7 @@ static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep) | |||
181 | /* NOTE: no locks here; caller should lock and select EP */ | 181 | /* NOTE: no locks here; caller should lock and select EP */ |
182 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); | 182 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); |
183 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; | 183 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; |
184 | if (is_cppi_enabled()) | 184 | if (is_cppi_enabled(ep->musb)) |
185 | txcsr |= MUSB_TXCSR_DMAMODE; | 185 | txcsr |= MUSB_TXCSR_DMAMODE; |
186 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); | 186 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); |
187 | } | 187 | } |
@@ -294,7 +294,7 @@ start: | |||
294 | 294 | ||
295 | if (!hw_ep->tx_channel) | 295 | if (!hw_ep->tx_channel) |
296 | musb_h_tx_start(hw_ep); | 296 | musb_h_tx_start(hw_ep); |
297 | else if (is_cppi_enabled() || tusb_dma_omap()) | 297 | else if (is_cppi_enabled(musb) || tusb_dma_omap(musb)) |
298 | musb_h_tx_dma_start(hw_ep); | 298 | musb_h_tx_dma_start(hw_ep); |
299 | } | 299 | } |
300 | } | 300 | } |
@@ -555,8 +555,9 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err) | |||
555 | * the busy/not-empty tests are basically paranoia. | 555 | * the busy/not-empty tests are basically paranoia. |
556 | */ | 556 | */ |
557 | static void | 557 | static void |
558 | musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | 558 | musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum) |
559 | { | 559 | { |
560 | struct musb_hw_ep *ep = musb->endpoints + epnum; | ||
560 | u16 csr; | 561 | u16 csr; |
561 | 562 | ||
562 | /* NOTE: we know the "rx" fifo reinit never triggers for ep0. | 563 | /* NOTE: we know the "rx" fifo reinit never triggers for ep0. |
@@ -594,10 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
594 | 595 | ||
595 | /* target addr and (for multipoint) hub addr/port */ | 596 | /* target addr and (for multipoint) hub addr/port */ |
596 | if (musb->is_multipoint) { | 597 | if (musb->is_multipoint) { |
597 | musb_write_rxfunaddr(ep->target_regs, qh->addr_reg); | 598 | musb_write_rxfunaddr(musb, epnum, qh->addr_reg); |
598 | musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg); | 599 | musb_write_rxhubaddr(musb, epnum, qh->h_addr_reg); |
599 | musb_write_rxhubport(ep->target_regs, qh->h_port_reg); | 600 | musb_write_rxhubport(musb, epnum, qh->h_port_reg); |
600 | |||
601 | } else | 601 | } else |
602 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); | 602 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); |
603 | 603 | ||
@@ -617,23 +617,22 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
617 | ep->rx_reinit = 0; | 617 | ep->rx_reinit = 0; |
618 | } | 618 | } |
619 | 619 | ||
620 | static bool musb_tx_dma_program(struct dma_controller *dma, | 620 | static int musb_tx_dma_set_mode_mentor(struct dma_controller *dma, |
621 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, | 621 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, |
622 | struct urb *urb, u32 offset, u32 length) | 622 | struct urb *urb, u32 offset, |
623 | u32 *length, u8 *mode) | ||
623 | { | 624 | { |
624 | struct dma_channel *channel = hw_ep->tx_channel; | 625 | struct dma_channel *channel = hw_ep->tx_channel; |
625 | void __iomem *epio = hw_ep->regs; | 626 | void __iomem *epio = hw_ep->regs; |
626 | u16 pkt_size = qh->maxpacket; | 627 | u16 pkt_size = qh->maxpacket; |
627 | u16 csr; | 628 | u16 csr; |
628 | u8 mode; | ||
629 | 629 | ||
630 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) | 630 | if (*length > channel->max_len) |
631 | if (length > channel->max_len) | 631 | *length = channel->max_len; |
632 | length = channel->max_len; | ||
633 | 632 | ||
634 | csr = musb_readw(epio, MUSB_TXCSR); | 633 | csr = musb_readw(epio, MUSB_TXCSR); |
635 | if (length > pkt_size) { | 634 | if (*length > pkt_size) { |
636 | mode = 1; | 635 | *mode = 1; |
637 | csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB; | 636 | csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB; |
638 | /* autoset shouldn't be set in high bandwidth */ | 637 | /* autoset shouldn't be set in high bandwidth */ |
639 | /* | 638 | /* |
@@ -649,15 +648,28 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
649 | can_bulk_split(hw_ep->musb, qh->type))) | 648 | can_bulk_split(hw_ep->musb, qh->type))) |
650 | csr |= MUSB_TXCSR_AUTOSET; | 649 | csr |= MUSB_TXCSR_AUTOSET; |
651 | } else { | 650 | } else { |
652 | mode = 0; | 651 | *mode = 0; |
653 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); | 652 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); |
654 | csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */ | 653 | csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */ |
655 | } | 654 | } |
656 | channel->desired_mode = mode; | 655 | channel->desired_mode = mode; |
657 | musb_writew(epio, MUSB_TXCSR, csr); | 656 | musb_writew(epio, MUSB_TXCSR, csr); |
658 | #else | 657 | |
659 | if (!is_cppi_enabled() && !tusb_dma_omap()) | 658 | return 0; |
660 | return false; | 659 | } |
660 | |||
661 | static int musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, | ||
662 | struct musb_hw_ep *hw_ep, | ||
663 | struct musb_qh *qh, | ||
664 | struct urb *urb, | ||
665 | u32 offset, | ||
666 | u32 *length, | ||
667 | u8 *mode) | ||
668 | { | ||
669 | struct dma_channel *channel = hw_ep->tx_channel; | ||
670 | |||
671 | if (!is_cppi_enabled(hw_ep->musb) && !tusb_dma_omap(hw_ep->musb)) | ||
672 | return -ENODEV; | ||
661 | 673 | ||
662 | channel->actual_len = 0; | 674 | channel->actual_len = 0; |
663 | 675 | ||
@@ -665,8 +677,28 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
665 | * TX uses "RNDIS" mode automatically but needs help | 677 | * TX uses "RNDIS" mode automatically but needs help |
666 | * to identify the zero-length-final-packet case. | 678 | * to identify the zero-length-final-packet case. |
667 | */ | 679 | */ |
668 | mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; | 680 | *mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; |
669 | #endif | 681 | |
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static bool musb_tx_dma_program(struct dma_controller *dma, | ||
686 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, | ||
687 | struct urb *urb, u32 offset, u32 length) | ||
688 | { | ||
689 | struct dma_channel *channel = hw_ep->tx_channel; | ||
690 | u16 pkt_size = qh->maxpacket; | ||
691 | u8 mode; | ||
692 | int res; | ||
693 | |||
694 | if (musb_dma_inventra(hw_ep->musb) || musb_dma_ux500(hw_ep->musb)) | ||
695 | res = musb_tx_dma_set_mode_mentor(dma, hw_ep, qh, urb, | ||
696 | offset, &length, &mode); | ||
697 | else | ||
698 | res = musb_tx_dma_set_mode_cppi_tusb(dma, hw_ep, qh, urb, | ||
699 | offset, &length, &mode); | ||
700 | if (res) | ||
701 | return false; | ||
670 | 702 | ||
671 | qh->segsize = length; | 703 | qh->segsize = length; |
672 | 704 | ||
@@ -678,6 +710,9 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
678 | 710 | ||
679 | if (!dma->channel_program(channel, pkt_size, mode, | 711 | if (!dma->channel_program(channel, pkt_size, mode, |
680 | urb->transfer_dma + offset, length)) { | 712 | urb->transfer_dma + offset, length)) { |
713 | void __iomem *epio = hw_ep->regs; | ||
714 | u16 csr; | ||
715 | |||
681 | dma->channel_release(channel); | 716 | dma->channel_release(channel); |
682 | hw_ep->tx_channel = NULL; | 717 | hw_ep->tx_channel = NULL; |
683 | 718 | ||
@@ -801,9 +836,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
801 | 836 | ||
802 | /* target addr and (for multipoint) hub addr/port */ | 837 | /* target addr and (for multipoint) hub addr/port */ |
803 | if (musb->is_multipoint) { | 838 | if (musb->is_multipoint) { |
804 | musb_write_txfunaddr(mbase, epnum, qh->addr_reg); | 839 | musb_write_txfunaddr(musb, epnum, qh->addr_reg); |
805 | musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg); | 840 | musb_write_txhubaddr(musb, epnum, qh->h_addr_reg); |
806 | musb_write_txhubport(mbase, epnum, qh->h_port_reg); | 841 | musb_write_txhubport(musb, epnum, qh->h_port_reg); |
807 | /* FIXME if !epnum, do the same for RX ... */ | 842 | /* FIXME if !epnum, do the same for RX ... */ |
808 | } else | 843 | } else |
809 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); | 844 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); |
@@ -875,7 +910,7 @@ finish: | |||
875 | u16 csr; | 910 | u16 csr; |
876 | 911 | ||
877 | if (hw_ep->rx_reinit) { | 912 | if (hw_ep->rx_reinit) { |
878 | musb_rx_reinit(musb, qh, hw_ep); | 913 | musb_rx_reinit(musb, qh, epnum); |
879 | 914 | ||
880 | /* init new state: toggle and NYET, maybe DMA later */ | 915 | /* init new state: toggle and NYET, maybe DMA later */ |
881 | if (usb_gettoggle(urb->dev, qh->epnum, 0)) | 916 | if (usb_gettoggle(urb->dev, qh->epnum, 0)) |
@@ -901,7 +936,7 @@ finish: | |||
901 | 936 | ||
902 | /* kick things off */ | 937 | /* kick things off */ |
903 | 938 | ||
904 | if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { | 939 | if ((is_cppi_enabled(musb) || tusb_dma_omap(musb)) && dma_channel) { |
905 | /* Candidate for DMA */ | 940 | /* Candidate for DMA */ |
906 | dma_channel->actual_len = 0L; | 941 | dma_channel->actual_len = 0L; |
907 | qh->segsize = len; | 942 | qh->segsize = len; |
@@ -1441,7 +1476,7 @@ done: | |||
1441 | } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) { | 1476 | } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) { |
1442 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, | 1477 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, |
1443 | offset, length)) { | 1478 | offset, length)) { |
1444 | if (is_cppi_enabled() || tusb_dma_omap()) | 1479 | if (is_cppi_enabled(musb) || tusb_dma_omap(musb)) |
1445 | musb_h_tx_dma_start(hw_ep); | 1480 | musb_h_tx_dma_start(hw_ep); |
1446 | return; | 1481 | return; |
1447 | } | 1482 | } |
@@ -1498,9 +1533,47 @@ done: | |||
1498 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); | 1533 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); |
1499 | } | 1534 | } |
1500 | 1535 | ||
1536 | #ifdef CONFIG_USB_TI_CPPI41_DMA | ||
1537 | /* Seems to set up ISO for cppi41 and not advance len. See commit c57c41d */ | ||
1538 | static int musb_rx_dma_iso_cppi41(struct dma_controller *dma, | ||
1539 | struct musb_hw_ep *hw_ep, | ||
1540 | struct musb_qh *qh, | ||
1541 | struct urb *urb, | ||
1542 | size_t len) | ||
1543 | { | ||
1544 | struct dma_channel *channel = hw_ep->tx_channel; | ||
1545 | void __iomem *epio = hw_ep->regs; | ||
1546 | dma_addr_t *buf; | ||
1547 | u32 length, res; | ||
1548 | u16 val; | ||
1501 | 1549 | ||
1502 | #ifdef CONFIG_USB_INVENTRA_DMA | 1550 | buf = (void *)urb->iso_frame_desc[qh->iso_idx].offset + |
1551 | (u32)urb->transfer_dma; | ||
1552 | |||
1553 | length = urb->iso_frame_desc[qh->iso_idx].length; | ||
1503 | 1554 | ||
1555 | val = musb_readw(epio, MUSB_RXCSR); | ||
1556 | val |= MUSB_RXCSR_DMAENAB; | ||
1557 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | ||
1558 | |||
1559 | res = dma->channel_program(channel, qh->maxpacket, 0, | ||
1560 | (u32)buf, length); | ||
1561 | |||
1562 | return res; | ||
1563 | } | ||
1564 | #else | ||
1565 | static inline int musb_rx_dma_iso_cppi41(struct dma_controller *dma, | ||
1566 | struct musb_hw_ep *hw_ep, | ||
1567 | struct musb_qh *qh, | ||
1568 | struct urb *urb, | ||
1569 | size_t len) | ||
1570 | { | ||
1571 | return false; | ||
1572 | } | ||
1573 | #endif | ||
1574 | |||
1575 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) || \ | ||
1576 | defined(CONFIG_USB_TI_CPPI41_DMA) | ||
1504 | /* Host side RX (IN) using Mentor DMA works as follows: | 1577 | /* Host side RX (IN) using Mentor DMA works as follows: |
1505 | submit_urb -> | 1578 | submit_urb -> |
1506 | - if queue was empty, ProgramEndpoint | 1579 | - if queue was empty, ProgramEndpoint |
@@ -1535,7 +1608,194 @@ done: | |||
1535 | * thus be a great candidate for using mode 1 ... for all but the | 1608 | * thus be a great candidate for using mode 1 ... for all but the |
1536 | * last packet of one URB's transfer. | 1609 | * last packet of one URB's transfer. |
1537 | */ | 1610 | */ |
1611 | static int musb_rx_dma_inventra_cppi41(struct dma_controller *dma, | ||
1612 | struct musb_hw_ep *hw_ep, | ||
1613 | struct musb_qh *qh, | ||
1614 | struct urb *urb, | ||
1615 | size_t len) | ||
1616 | { | ||
1617 | struct dma_channel *channel = hw_ep->rx_channel; | ||
1618 | void __iomem *epio = hw_ep->regs; | ||
1619 | u16 val; | ||
1620 | int pipe; | ||
1621 | bool done; | ||
1622 | |||
1623 | pipe = urb->pipe; | ||
1624 | |||
1625 | if (usb_pipeisoc(pipe)) { | ||
1626 | struct usb_iso_packet_descriptor *d; | ||
1627 | |||
1628 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1629 | d->actual_length = len; | ||
1630 | |||
1631 | /* even if there was an error, we did the dma | ||
1632 | * for iso_frame_desc->length | ||
1633 | */ | ||
1634 | if (d->status != -EILSEQ && d->status != -EOVERFLOW) | ||
1635 | d->status = 0; | ||
1636 | |||
1637 | if (++qh->iso_idx >= urb->number_of_packets) { | ||
1638 | done = true; | ||
1639 | } else { | ||
1640 | /* REVISIT: Why ignore return value here? */ | ||
1641 | if (musb_dma_cppi41(hw_ep->musb)) | ||
1642 | done = musb_rx_dma_iso_cppi41(dma, hw_ep, qh, | ||
1643 | urb, len); | ||
1644 | done = false; | ||
1645 | } | ||
1646 | |||
1647 | } else { | ||
1648 | /* done if urb buffer is full or short packet is recd */ | ||
1649 | done = (urb->actual_length + len >= | ||
1650 | urb->transfer_buffer_length | ||
1651 | || channel->actual_len < qh->maxpacket | ||
1652 | || channel->rx_packet_done); | ||
1653 | } | ||
1654 | |||
1655 | /* send IN token for next packet, without AUTOREQ */ | ||
1656 | if (!done) { | ||
1657 | val = musb_readw(epio, MUSB_RXCSR); | ||
1658 | val |= MUSB_RXCSR_H_REQPKT; | ||
1659 | musb_writew(epio, MUSB_RXCSR, MUSB_RXCSR_H_WZC_BITS | val); | ||
1660 | } | ||
1661 | |||
1662 | return done; | ||
1663 | } | ||
1664 | |||
1665 | /* Disadvantage of using mode 1: | ||
1666 | * It's basically usable only for mass storage class; essentially all | ||
1667 | * other protocols also terminate transfers on short packets. | ||
1668 | * | ||
1669 | * Details: | ||
1670 | * An extra IN token is sent at the end of the transfer (due to AUTOREQ) | ||
1671 | * If you try to use mode 1 for (transfer_buffer_length - 512), and try | ||
1672 | * to use the extra IN token to grab the last packet using mode 0, then | ||
1673 | * the problem is that you cannot be sure when the device will send the | ||
1674 | * last packet and RxPktRdy set. Sometimes the packet is recd too soon | ||
1675 | * such that it gets lost when RxCSR is re-set at the end of the mode 1 | ||
1676 | * transfer, while sometimes it is recd just a little late so that if you | ||
1677 | * try to configure for mode 0 soon after the mode 1 transfer is | ||
1678 | * completed, you will find rxcount 0. Okay, so you might think why not | ||
1679 | * wait for an interrupt when the pkt is recd. Well, you won't get any! | ||
1680 | */ | ||
1681 | static int musb_rx_dma_in_inventra_cppi41(struct dma_controller *dma, | ||
1682 | struct musb_hw_ep *hw_ep, | ||
1683 | struct musb_qh *qh, | ||
1684 | struct urb *urb, | ||
1685 | size_t len, | ||
1686 | u8 iso_err) | ||
1687 | { | ||
1688 | struct musb *musb = hw_ep->musb; | ||
1689 | void __iomem *epio = hw_ep->regs; | ||
1690 | struct dma_channel *channel = hw_ep->rx_channel; | ||
1691 | u16 rx_count, val; | ||
1692 | int length, pipe, done; | ||
1693 | dma_addr_t buf; | ||
1694 | |||
1695 | rx_count = musb_readw(epio, MUSB_RXCOUNT); | ||
1696 | pipe = urb->pipe; | ||
1697 | |||
1698 | if (usb_pipeisoc(pipe)) { | ||
1699 | int d_status = 0; | ||
1700 | struct usb_iso_packet_descriptor *d; | ||
1701 | |||
1702 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1538 | 1703 | ||
1704 | if (iso_err) { | ||
1705 | d_status = -EILSEQ; | ||
1706 | urb->error_count++; | ||
1707 | } | ||
1708 | if (rx_count > d->length) { | ||
1709 | if (d_status == 0) { | ||
1710 | d_status = -EOVERFLOW; | ||
1711 | urb->error_count++; | ||
1712 | } | ||
1713 | dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", | ||
1714 | rx_count, d->length); | ||
1715 | |||
1716 | length = d->length; | ||
1717 | } else | ||
1718 | length = rx_count; | ||
1719 | d->status = d_status; | ||
1720 | buf = urb->transfer_dma + d->offset; | ||
1721 | } else { | ||
1722 | length = rx_count; | ||
1723 | buf = urb->transfer_dma + urb->actual_length; | ||
1724 | } | ||
1725 | |||
1726 | channel->desired_mode = 0; | ||
1727 | #ifdef USE_MODE1 | ||
1728 | /* because of the issue below, mode 1 will | ||
1729 | * only rarely behave with correct semantics. | ||
1730 | */ | ||
1731 | if ((urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1732 | && (urb->transfer_buffer_length - urb->actual_length) | ||
1733 | > qh->maxpacket) | ||
1734 | channel->desired_mode = 1; | ||
1735 | if (rx_count < hw_ep->max_packet_sz_rx) { | ||
1736 | length = rx_count; | ||
1737 | channel->desired_mode = 0; | ||
1738 | } else { | ||
1739 | length = urb->transfer_buffer_length; | ||
1740 | } | ||
1741 | #endif | ||
1742 | |||
1743 | /* See comments above on disadvantages of using mode 1 */ | ||
1744 | val = musb_readw(epio, MUSB_RXCSR); | ||
1745 | val &= ~MUSB_RXCSR_H_REQPKT; | ||
1746 | |||
1747 | if (channel->desired_mode == 0) | ||
1748 | val &= ~MUSB_RXCSR_H_AUTOREQ; | ||
1749 | else | ||
1750 | val |= MUSB_RXCSR_H_AUTOREQ; | ||
1751 | val |= MUSB_RXCSR_DMAENAB; | ||
1752 | |||
1753 | /* autoclear shouldn't be set in high bandwidth */ | ||
1754 | if (qh->hb_mult == 1) | ||
1755 | val |= MUSB_RXCSR_AUTOCLEAR; | ||
1756 | |||
1757 | musb_writew(epio, MUSB_RXCSR, MUSB_RXCSR_H_WZC_BITS | val); | ||
1758 | |||
1759 | /* REVISIT if when actual_length != 0, | ||
1760 | * transfer_buffer_length needs to be | ||
1761 | * adjusted first... | ||
1762 | */ | ||
1763 | done = dma->channel_program(channel, qh->maxpacket, | ||
1764 | channel->desired_mode, | ||
1765 | buf, length); | ||
1766 | |||
1767 | if (!done) { | ||
1768 | dma->channel_release(channel); | ||
1769 | hw_ep->rx_channel = NULL; | ||
1770 | channel = NULL; | ||
1771 | val = musb_readw(epio, MUSB_RXCSR); | ||
1772 | val &= ~(MUSB_RXCSR_DMAENAB | ||
1773 | | MUSB_RXCSR_H_AUTOREQ | ||
1774 | | MUSB_RXCSR_AUTOCLEAR); | ||
1775 | musb_writew(epio, MUSB_RXCSR, val); | ||
1776 | } | ||
1777 | |||
1778 | return done; | ||
1779 | } | ||
1780 | #else | ||
1781 | static inline int musb_rx_dma_inventra_cppi41(struct dma_controller *dma, | ||
1782 | struct musb_hw_ep *hw_ep, | ||
1783 | struct musb_qh *qh, | ||
1784 | struct urb *urb, | ||
1785 | size_t len) | ||
1786 | { | ||
1787 | return false; | ||
1788 | } | ||
1789 | |||
1790 | static inline int musb_rx_dma_in_inventra_cppi41(struct dma_controller *dma, | ||
1791 | struct musb_hw_ep *hw_ep, | ||
1792 | struct musb_qh *qh, | ||
1793 | struct urb *urb, | ||
1794 | size_t len, | ||
1795 | u8 iso_err) | ||
1796 | { | ||
1797 | return false; | ||
1798 | } | ||
1539 | #endif | 1799 | #endif |
1540 | 1800 | ||
1541 | /* | 1801 | /* |
@@ -1546,6 +1806,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1546 | { | 1806 | { |
1547 | struct urb *urb; | 1807 | struct urb *urb; |
1548 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1808 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
1809 | struct dma_controller *c = musb->dma_controller; | ||
1549 | void __iomem *epio = hw_ep->regs; | 1810 | void __iomem *epio = hw_ep->regs; |
1550 | struct musb_qh *qh = hw_ep->in_qh; | 1811 | struct musb_qh *qh = hw_ep->in_qh; |
1551 | size_t xfer_len; | 1812 | size_t xfer_len; |
@@ -1661,9 +1922,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1661 | */ | 1922 | */ |
1662 | 1923 | ||
1663 | /* FIXME this is _way_ too much in-line logic for Mentor DMA */ | 1924 | /* FIXME this is _way_ too much in-line logic for Mentor DMA */ |
1664 | 1925 | if (!musb_dma_inventra(musb) && !musb_dma_ux500(musb) && | |
1665 | #if !defined(CONFIG_USB_INVENTRA_DMA) && !defined(CONFIG_USB_UX500_DMA) | 1926 | (rx_csr & MUSB_RXCSR_H_REQPKT)) { |
1666 | if (rx_csr & MUSB_RXCSR_H_REQPKT) { | ||
1667 | /* REVISIT this happened for a while on some short reads... | 1927 | /* REVISIT this happened for a while on some short reads... |
1668 | * the cleanup still needs investigation... looks bad... | 1928 | * the cleanup still needs investigation... looks bad... |
1669 | * and also duplicates dma cleanup code above ... plus, | 1929 | * and also duplicates dma cleanup code above ... plus, |
@@ -1684,7 +1944,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1684 | musb_writew(epio, MUSB_RXCSR, | 1944 | musb_writew(epio, MUSB_RXCSR, |
1685 | MUSB_RXCSR_H_WZC_BITS | rx_csr); | 1945 | MUSB_RXCSR_H_WZC_BITS | rx_csr); |
1686 | } | 1946 | } |
1687 | #endif | 1947 | |
1688 | if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) { | 1948 | if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) { |
1689 | xfer_len = dma->actual_len; | 1949 | xfer_len = dma->actual_len; |
1690 | 1950 | ||
@@ -1694,67 +1954,18 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1694 | | MUSB_RXCSR_RXPKTRDY); | 1954 | | MUSB_RXCSR_RXPKTRDY); |
1695 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | 1955 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); |
1696 | 1956 | ||
1697 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) || \ | 1957 | if (musb_dma_inventra(musb) || musb_dma_ux500(musb) || |
1698 | defined(CONFIG_USB_TI_CPPI41_DMA) | 1958 | musb_dma_cppi41(musb)) { |
1699 | if (usb_pipeisoc(pipe)) { | 1959 | done = musb_rx_dma_inventra_cppi41(c, hw_ep, qh, urb, xfer_len); |
1700 | struct usb_iso_packet_descriptor *d; | 1960 | dev_dbg(hw_ep->musb->controller, |
1701 | 1961 | "ep %d dma %s, rxcsr %04x, rxcount %d\n", | |
1702 | d = urb->iso_frame_desc + qh->iso_idx; | 1962 | epnum, done ? "off" : "reset", |
1703 | d->actual_length = xfer_len; | 1963 | musb_readw(epio, MUSB_RXCSR), |
1704 | 1964 | musb_readw(epio, MUSB_RXCOUNT)); | |
1705 | /* even if there was an error, we did the dma | 1965 | } else { |
1706 | * for iso_frame_desc->length | 1966 | done = true; |
1707 | */ | ||
1708 | if (d->status != -EILSEQ && d->status != -EOVERFLOW) | ||
1709 | d->status = 0; | ||
1710 | |||
1711 | if (++qh->iso_idx >= urb->number_of_packets) { | ||
1712 | done = true; | ||
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 | ||
1733 | done = false; | ||
1734 | } | ||
1735 | |||
1736 | } else { | ||
1737 | /* done if urb buffer is full or short packet is recd */ | ||
1738 | done = (urb->actual_length + xfer_len >= | ||
1739 | urb->transfer_buffer_length | ||
1740 | || dma->actual_len < qh->maxpacket | ||
1741 | || dma->rx_packet_done); | ||
1742 | } | ||
1743 | |||
1744 | /* send IN token for next packet, without AUTOREQ */ | ||
1745 | if (!done) { | ||
1746 | val |= MUSB_RXCSR_H_REQPKT; | ||
1747 | musb_writew(epio, MUSB_RXCSR, | ||
1748 | MUSB_RXCSR_H_WZC_BITS | val); | ||
1749 | } | 1967 | } |
1750 | 1968 | ||
1751 | dev_dbg(musb->controller, "ep %d dma %s, rxcsr %04x, rxcount %d\n", epnum, | ||
1752 | done ? "off" : "reset", | ||
1753 | musb_readw(epio, MUSB_RXCSR), | ||
1754 | musb_readw(epio, MUSB_RXCOUNT)); | ||
1755 | #else | ||
1756 | done = true; | ||
1757 | #endif | ||
1758 | } else if (urb->status == -EINPROGRESS) { | 1969 | } else if (urb->status == -EINPROGRESS) { |
1759 | /* if no errors, be sure a packet is ready for unloading */ | 1970 | /* if no errors, be sure a packet is ready for unloading */ |
1760 | if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) { | 1971 | if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) { |
@@ -1772,126 +1983,24 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1772 | } | 1983 | } |
1773 | 1984 | ||
1774 | /* we are expecting IN packets */ | 1985 | /* we are expecting IN packets */ |
1775 | #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA) || \ | 1986 | if ((musb_dma_inventra(musb) || musb_dma_ux500(musb) || |
1776 | defined(CONFIG_USB_TI_CPPI41_DMA) | 1987 | musb_dma_cppi41(musb)) && dma) { |
1777 | if (dma) { | 1988 | dev_dbg(hw_ep->musb->controller, |
1778 | struct dma_controller *c; | 1989 | "RX%d count %d, buffer 0x%llx len %d/%d\n", |
1779 | u16 rx_count; | 1990 | epnum, musb_readw(epio, MUSB_RXCOUNT), |
1780 | int ret, length; | 1991 | (unsigned long long) urb->transfer_dma |
1781 | dma_addr_t buf; | 1992 | + urb->actual_length, |
1782 | 1993 | qh->offset, | |
1783 | rx_count = musb_readw(epio, MUSB_RXCOUNT); | 1994 | urb->transfer_buffer_length); |
1784 | 1995 | ||
1785 | dev_dbg(musb->controller, "RX%d count %d, buffer 0x%llx len %d/%d\n", | 1996 | done = musb_rx_dma_in_inventra_cppi41(c, hw_ep, qh, |
1786 | epnum, rx_count, | 1997 | urb, xfer_len, |
1787 | (unsigned long long) urb->transfer_dma | 1998 | iso_err); |
1788 | + urb->actual_length, | 1999 | if (done) |
1789 | qh->offset, | 2000 | goto finish; |
1790 | urb->transfer_buffer_length); | ||
1791 | |||
1792 | c = musb->dma_controller; | ||
1793 | |||
1794 | if (usb_pipeisoc(pipe)) { | ||
1795 | int d_status = 0; | ||
1796 | struct usb_iso_packet_descriptor *d; | ||
1797 | |||
1798 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1799 | |||
1800 | if (iso_err) { | ||
1801 | d_status = -EILSEQ; | ||
1802 | urb->error_count++; | ||
1803 | } | ||
1804 | if (rx_count > d->length) { | ||
1805 | if (d_status == 0) { | ||
1806 | d_status = -EOVERFLOW; | ||
1807 | urb->error_count++; | ||
1808 | } | ||
1809 | dev_dbg(musb->controller, "** OVERFLOW %d into %d\n",\ | ||
1810 | rx_count, d->length); | ||
1811 | |||
1812 | length = d->length; | ||
1813 | } else | ||
1814 | length = rx_count; | ||
1815 | d->status = d_status; | ||
1816 | buf = urb->transfer_dma + d->offset; | ||
1817 | } else { | ||
1818 | length = rx_count; | ||
1819 | buf = urb->transfer_dma + | ||
1820 | urb->actual_length; | ||
1821 | } | ||
1822 | |||
1823 | dma->desired_mode = 0; | ||
1824 | #ifdef USE_MODE1 | ||
1825 | /* because of the issue below, mode 1 will | ||
1826 | * only rarely behave with correct semantics. | ||
1827 | */ | ||
1828 | if ((urb->transfer_flags & | ||
1829 | URB_SHORT_NOT_OK) | ||
1830 | && (urb->transfer_buffer_length - | ||
1831 | urb->actual_length) | ||
1832 | > qh->maxpacket) | ||
1833 | dma->desired_mode = 1; | ||
1834 | if (rx_count < hw_ep->max_packet_sz_rx) { | ||
1835 | length = rx_count; | ||
1836 | dma->desired_mode = 0; | ||
1837 | } else { | ||
1838 | length = urb->transfer_buffer_length; | ||
1839 | } | ||
1840 | #endif | ||
1841 | |||
1842 | /* Disadvantage of using mode 1: | ||
1843 | * It's basically usable only for mass storage class; essentially all | ||
1844 | * other protocols also terminate transfers on short packets. | ||
1845 | * | ||
1846 | * Details: | ||
1847 | * An extra IN token is sent at the end of the transfer (due to AUTOREQ) | ||
1848 | * If you try to use mode 1 for (transfer_buffer_length - 512), and try | ||
1849 | * to use the extra IN token to grab the last packet using mode 0, then | ||
1850 | * the problem is that you cannot be sure when the device will send the | ||
1851 | * last packet and RxPktRdy set. Sometimes the packet is recd too soon | ||
1852 | * such that it gets lost when RxCSR is re-set at the end of the mode 1 | ||
1853 | * transfer, while sometimes it is recd just a little late so that if you | ||
1854 | * try to configure for mode 0 soon after the mode 1 transfer is | ||
1855 | * completed, you will find rxcount 0. Okay, so you might think why not | ||
1856 | * wait for an interrupt when the pkt is recd. Well, you won't get any! | ||
1857 | */ | ||
1858 | |||
1859 | val = musb_readw(epio, MUSB_RXCSR); | ||
1860 | val &= ~MUSB_RXCSR_H_REQPKT; | ||
1861 | |||
1862 | if (dma->desired_mode == 0) | ||
1863 | val &= ~MUSB_RXCSR_H_AUTOREQ; | ||
1864 | else | 2001 | else |
1865 | val |= MUSB_RXCSR_H_AUTOREQ; | 2002 | dev_err(musb->controller, "error: rx_dma failed\n"); |
1866 | val |= MUSB_RXCSR_DMAENAB; | ||
1867 | |||
1868 | /* autoclear shouldn't be set in high bandwidth */ | ||
1869 | if (qh->hb_mult == 1) | ||
1870 | val |= MUSB_RXCSR_AUTOCLEAR; | ||
1871 | |||
1872 | musb_writew(epio, MUSB_RXCSR, | ||
1873 | MUSB_RXCSR_H_WZC_BITS | val); | ||
1874 | |||
1875 | /* REVISIT if when actual_length != 0, | ||
1876 | * transfer_buffer_length needs to be | ||
1877 | * adjusted first... | ||
1878 | */ | ||
1879 | ret = c->channel_program( | ||
1880 | dma, qh->maxpacket, | ||
1881 | dma->desired_mode, buf, length); | ||
1882 | |||
1883 | if (!ret) { | ||
1884 | c->channel_release(dma); | ||
1885 | hw_ep->rx_channel = NULL; | ||
1886 | dma = NULL; | ||
1887 | val = musb_readw(epio, MUSB_RXCSR); | ||
1888 | val &= ~(MUSB_RXCSR_DMAENAB | ||
1889 | | MUSB_RXCSR_H_AUTOREQ | ||
1890 | | MUSB_RXCSR_AUTOCLEAR); | ||
1891 | musb_writew(epio, MUSB_RXCSR, val); | ||
1892 | } | ||
1893 | } | 2003 | } |
1894 | #endif /* Mentor DMA */ | ||
1895 | 2004 | ||
1896 | if (!dma) { | 2005 | if (!dma) { |
1897 | unsigned int received_len; | 2006 | unsigned int received_len; |
@@ -2512,6 +2621,7 @@ static void musb_free_temp_buffer(struct urb *urb) | |||
2512 | { | 2621 | { |
2513 | enum dma_data_direction dir; | 2622 | enum dma_data_direction dir; |
2514 | struct musb_temp_buffer *temp; | 2623 | struct musb_temp_buffer *temp; |
2624 | size_t length; | ||
2515 | 2625 | ||
2516 | if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) | 2626 | if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) |
2517 | return; | 2627 | return; |
@@ -2522,8 +2632,12 @@ static void musb_free_temp_buffer(struct urb *urb) | |||
2522 | data); | 2632 | data); |
2523 | 2633 | ||
2524 | if (dir == DMA_FROM_DEVICE) { | 2634 | if (dir == DMA_FROM_DEVICE) { |
2525 | memcpy(temp->old_xfer_buffer, temp->data, | 2635 | if (usb_pipeisoc(urb->pipe)) |
2526 | urb->transfer_buffer_length); | 2636 | length = urb->transfer_buffer_length; |
2637 | else | ||
2638 | length = urb->actual_length; | ||
2639 | |||
2640 | memcpy(temp->old_xfer_buffer, temp->data, length); | ||
2527 | } | 2641 | } |
2528 | urb->transfer_buffer = temp->old_xfer_buffer; | 2642 | urb->transfer_buffer = temp->old_xfer_buffer; |
2529 | kfree(temp->kmalloc_ptr); | 2643 | kfree(temp->kmalloc_ptr); |
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 8a57a6f4b3a6..17a80ae20674 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h | |||
@@ -47,6 +47,7 @@ | |||
47 | * @fifo_offset: platform specific function to get fifo offset | 47 | * @fifo_offset: platform specific function to get fifo offset |
48 | * @read_fifo: platform specific function to read fifo | 48 | * @read_fifo: platform specific function to read fifo |
49 | * @write_fifo: platform specific function to write fifo | 49 | * @write_fifo: platform specific function to write fifo |
50 | * @busctl_offset: platform specific function to get busctl offset | ||
50 | */ | 51 | */ |
51 | struct musb_io { | 52 | struct musb_io { |
52 | u32 quirks; | 53 | u32 quirks; |
@@ -55,6 +56,7 @@ struct musb_io { | |||
55 | u32 (*fifo_offset)(u8 epnum); | 56 | u32 (*fifo_offset)(u8 epnum); |
56 | void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); | 57 | void (*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf); |
57 | void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); | 58 | void (*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf); |
59 | u32 (*busctl_offset)(u8 epnum, u16 offset); | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | /* Do not add new entries here, add them the struct musb_io instead */ | 62 | /* Do not add new entries here, add them the struct musb_io instead */ |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 11f0be07491e..cff5bcf0d00f 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -300,9 +300,6 @@ | |||
300 | #define MUSB_RXHUBADDR 0x06 | 300 | #define MUSB_RXHUBADDR 0x06 |
301 | #define MUSB_RXHUBPORT 0x07 | 301 | #define MUSB_RXHUBPORT 0x07 |
302 | 302 | ||
303 | #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ | ||
304 | (0x80 + (8*(_epnum)) + (_offset)) | ||
305 | |||
306 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | 303 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) |
307 | { | 304 | { |
308 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | 305 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); |
@@ -364,78 +361,84 @@ static inline u16 musb_read_hwvers(void __iomem *mbase) | |||
364 | return musb_readw(mbase, MUSB_HWVERS); | 361 | return musb_readw(mbase, MUSB_HWVERS); |
365 | } | 362 | } |
366 | 363 | ||
367 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) | 364 | static inline void musb_write_rxfunaddr(struct musb *musb, u8 epnum, |
368 | { | ||
369 | return (MUSB_BUSCTL_OFFSET(i, 0) + mbase); | ||
370 | } | ||
371 | |||
372 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
373 | u8 qh_addr_reg) | 365 | u8 qh_addr_reg) |
374 | { | 366 | { |
375 | musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg); | 367 | musb_writeb(musb->mregs, |
368 | musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR), | ||
369 | qh_addr_reg); | ||
376 | } | 370 | } |
377 | 371 | ||
378 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | 372 | static inline void musb_write_rxhubaddr(struct musb *musb, u8 epnum, |
379 | u8 qh_h_addr_reg) | 373 | u8 qh_h_addr_reg) |
380 | { | 374 | { |
381 | musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg); | 375 | musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBADDR), |
376 | qh_h_addr_reg); | ||
382 | } | 377 | } |
383 | 378 | ||
384 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | 379 | static inline void musb_write_rxhubport(struct musb *musb, u8 epnum, |
385 | u8 qh_h_port_reg) | 380 | u8 qh_h_port_reg) |
386 | { | 381 | { |
387 | musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg); | 382 | musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBPORT), |
383 | qh_h_port_reg); | ||
388 | } | 384 | } |
389 | 385 | ||
390 | static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, | 386 | static inline void musb_write_txfunaddr(struct musb *musb, u8 epnum, |
391 | u8 qh_addr_reg) | 387 | u8 qh_addr_reg) |
392 | { | 388 | { |
393 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), | 389 | musb_writeb(musb->mregs, |
394 | qh_addr_reg); | 390 | musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR), |
391 | qh_addr_reg); | ||
395 | } | 392 | } |
396 | 393 | ||
397 | static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, | 394 | static inline void musb_write_txhubaddr(struct musb *musb, u8 epnum, |
398 | u8 qh_addr_reg) | 395 | u8 qh_addr_reg) |
399 | { | 396 | { |
400 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), | 397 | musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBADDR), |
401 | qh_addr_reg); | 398 | qh_addr_reg); |
402 | } | 399 | } |
403 | 400 | ||
404 | static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | 401 | static inline void musb_write_txhubport(struct musb *musb, u8 epnum, |
405 | u8 qh_h_port_reg) | 402 | u8 qh_h_port_reg) |
406 | { | 403 | { |
407 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), | 404 | musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBPORT), |
408 | qh_h_port_reg); | 405 | qh_h_port_reg); |
409 | } | 406 | } |
410 | 407 | ||
411 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) | 408 | static inline u8 musb_read_rxfunaddr(struct musb *musb, u8 epnum) |
412 | { | 409 | { |
413 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR)); | 410 | return musb_readb(musb->mregs, |
411 | musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR)); | ||
414 | } | 412 | } |
415 | 413 | ||
416 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) | 414 | static inline u8 musb_read_rxhubaddr(struct musb *musb, u8 epnum) |
417 | { | 415 | { |
418 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR)); | 416 | return musb_readb(musb->mregs, |
417 | musb->io.busctl_offset(epnum, MUSB_RXHUBADDR)); | ||
419 | } | 418 | } |
420 | 419 | ||
421 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) | 420 | static inline u8 musb_read_rxhubport(struct musb *musb, u8 epnum) |
422 | { | 421 | { |
423 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT)); | 422 | return musb_readb(musb->mregs, |
423 | musb->io.busctl_offset(epnum, MUSB_RXHUBPORT)); | ||
424 | } | 424 | } |
425 | 425 | ||
426 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) | 426 | static inline u8 musb_read_txfunaddr(struct musb *musb, u8 epnum) |
427 | { | 427 | { |
428 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR)); | 428 | return musb_readb(musb->mregs, |
429 | musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR)); | ||
429 | } | 430 | } |
430 | 431 | ||
431 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) | 432 | static inline u8 musb_read_txhubaddr(struct musb *musb, u8 epnum) |
432 | { | 433 | { |
433 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR)); | 434 | return musb_readb(musb->mregs, |
435 | musb->io.busctl_offset(epnum, MUSB_TXHUBADDR)); | ||
434 | } | 436 | } |
435 | 437 | ||
436 | static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) | 438 | static inline u8 musb_read_txhubport(struct musb *musb, u8 epnum) |
437 | { | 439 | { |
438 | return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT)); | 440 | return musb_readb(musb->mregs, |
441 | musb->io.busctl_offset(epnum, MUSB_TXHUBPORT)); | ||
439 | } | 442 | } |
440 | 443 | ||
441 | #else /* CONFIG_BLACKFIN */ | 444 | #else /* CONFIG_BLACKFIN */ |
@@ -556,22 +559,17 @@ static inline u16 musb_read_hwvers(void __iomem *mbase) | |||
556 | return MUSB_HWVERS_1900; | 559 | return MUSB_HWVERS_1900; |
557 | } | 560 | } |
558 | 561 | ||
559 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) | 562 | static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum, |
560 | { | ||
561 | return NULL; | ||
562 | } | ||
563 | |||
564 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
565 | u8 qh_addr_req) | 563 | u8 qh_addr_req) |
566 | { | 564 | { |
567 | } | 565 | } |
568 | 566 | ||
569 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | 567 | static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum, |
570 | u8 qh_h_addr_reg) | 568 | u8 qh_h_addr_reg) |
571 | { | 569 | { |
572 | } | 570 | } |
573 | 571 | ||
574 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | 572 | static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum, |
575 | u8 qh_h_port_reg) | 573 | u8 qh_h_port_reg) |
576 | { | 574 | { |
577 | } | 575 | } |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 86c4b533e90b..30842bc195f5 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -195,8 +195,10 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
195 | msecs_to_jiffies(50)); | 195 | msecs_to_jiffies(50)); |
196 | } else { | 196 | } else { |
197 | dev_dbg(musb->controller, "root port reset stopped\n"); | 197 | dev_dbg(musb->controller, "root port reset stopped\n"); |
198 | musb_platform_pre_root_reset_end(musb); | ||
198 | musb_writeb(mbase, MUSB_POWER, | 199 | musb_writeb(mbase, MUSB_POWER, |
199 | power & ~MUSB_POWER_RESET); | 200 | power & ~MUSB_POWER_RESET); |
201 | musb_platform_post_root_reset_end(musb); | ||
200 | 202 | ||
201 | power = musb_readb(mbase, MUSB_POWER); | 203 | power = musb_readb(mbase, MUSB_POWER); |
202 | if (power & MUSB_POWER_HSMODE) { | 204 | if (power & MUSB_POWER_HSMODE) { |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index ab7ec09a8afe..7539c3188ffc 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -357,7 +357,7 @@ done: | |||
357 | return retval; | 357 | return retval; |
358 | } | 358 | } |
359 | 359 | ||
360 | void dma_controller_destroy(struct dma_controller *c) | 360 | void musbhs_dma_controller_destroy(struct dma_controller *c) |
361 | { | 361 | { |
362 | struct musb_dma_controller *controller = container_of(c, | 362 | struct musb_dma_controller *controller = container_of(c, |
363 | struct musb_dma_controller, controller); | 363 | struct musb_dma_controller, controller); |
@@ -369,8 +369,10 @@ void dma_controller_destroy(struct dma_controller *c) | |||
369 | 369 | ||
370 | kfree(controller); | 370 | kfree(controller); |
371 | } | 371 | } |
372 | EXPORT_SYMBOL_GPL(musbhs_dma_controller_destroy); | ||
372 | 373 | ||
373 | struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) | 374 | struct dma_controller *musbhs_dma_controller_create(struct musb *musb, |
375 | void __iomem *base) | ||
374 | { | 376 | { |
375 | struct musb_dma_controller *controller; | 377 | struct musb_dma_controller *controller; |
376 | struct device *dev = musb->controller; | 378 | struct device *dev = musb->controller; |
@@ -398,7 +400,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba | |||
398 | if (request_irq(irq, dma_controller_irq, 0, | 400 | if (request_irq(irq, dma_controller_irq, 0, |
399 | dev_name(musb->controller), &controller->controller)) { | 401 | dev_name(musb->controller), &controller->controller)) { |
400 | dev_err(dev, "request_irq %d failed!\n", irq); | 402 | dev_err(dev, "request_irq %d failed!\n", irq); |
401 | dma_controller_destroy(&controller->controller); | 403 | musb_dma_controller_destroy(&controller->controller); |
402 | 404 | ||
403 | return NULL; | 405 | return NULL; |
404 | } | 406 | } |
@@ -407,3 +409,4 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba | |||
407 | 409 | ||
408 | return &controller->controller; | 410 | return &controller->controller; |
409 | } | 411 | } |
412 | EXPORT_SYMBOL_GPL(musbhs_dma_controller_create); | ||
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index cc752d8c7773..70f2b8a2e6cf 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -493,6 +493,11 @@ static int omap2430_musb_exit(struct musb *musb) | |||
493 | } | 493 | } |
494 | 494 | ||
495 | static const struct musb_platform_ops omap2430_ops = { | 495 | static const struct musb_platform_ops omap2430_ops = { |
496 | .quirks = MUSB_DMA_INVENTRA, | ||
497 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
498 | .dma_init = musbhs_dma_controller_create, | ||
499 | .dma_exit = musbhs_dma_controller_destroy, | ||
500 | #endif | ||
496 | .init = omap2430_musb_init, | 501 | .init = omap2430_musb_init, |
497 | .exit = omap2430_musb_exit, | 502 | .exit = omap2430_musb_exit, |
498 | 503 | ||
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 3a5ffd575438..df7c9f46be54 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -890,7 +890,7 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci) | |||
890 | 890 | ||
891 | dev_dbg(musb->controller, "DMA IRQ %08x\n", dma_src); | 891 | dev_dbg(musb->controller, "DMA IRQ %08x\n", dma_src); |
892 | real_dma_src = ~real_dma_src & dma_src; | 892 | real_dma_src = ~real_dma_src & dma_src; |
893 | if (tusb_dma_omap() && real_dma_src) { | 893 | if (tusb_dma_omap(musb) && real_dma_src) { |
894 | int tx_source = (real_dma_src & 0xffff); | 894 | int tx_source = (real_dma_src & 0xffff); |
895 | int i; | 895 | int i; |
896 | 896 | ||
@@ -1181,7 +1181,7 @@ static int tusb_musb_exit(struct musb *musb) | |||
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | static const struct musb_platform_ops tusb_ops = { | 1183 | static const struct musb_platform_ops tusb_ops = { |
1184 | .quirks = MUSB_IN_TUSB, | 1184 | .quirks = MUSB_DMA_TUSB_OMAP | MUSB_IN_TUSB, |
1185 | .init = tusb_musb_init, | 1185 | .init = tusb_musb_init, |
1186 | .exit = tusb_musb_exit, | 1186 | .exit = tusb_musb_exit, |
1187 | 1187 | ||
@@ -1192,6 +1192,10 @@ static const struct musb_platform_ops tusb_ops = { | |||
1192 | .writeb = tusb_writeb, | 1192 | .writeb = tusb_writeb, |
1193 | .read_fifo = tusb_read_fifo, | 1193 | .read_fifo = tusb_read_fifo, |
1194 | .write_fifo = tusb_write_fifo, | 1194 | .write_fifo = tusb_write_fifo, |
1195 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | ||
1196 | .dma_init = tusb_dma_controller_create, | ||
1197 | .dma_exit = tusb_dma_controller_destroy, | ||
1198 | #endif | ||
1195 | .enable = tusb_musb_enable, | 1199 | .enable = tusb_musb_enable, |
1196 | .disable = tusb_musb_disable, | 1200 | .disable = tusb_musb_disable, |
1197 | 1201 | ||
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h index aec86c86ce32..72cdad23ced9 100644 --- a/drivers/usb/musb/tusb6010.h +++ b/drivers/usb/musb/tusb6010.h | |||
@@ -12,12 +12,6 @@ | |||
12 | #ifndef __TUSB6010_H__ | 12 | #ifndef __TUSB6010_H__ |
13 | #define __TUSB6010_H__ | 13 | #define __TUSB6010_H__ |
14 | 14 | ||
15 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | ||
16 | #define tusb_dma_omap() 1 | ||
17 | #else | ||
18 | #define tusb_dma_omap() 0 | ||
19 | #endif | ||
20 | |||
21 | /* VLYNQ control register. 32-bit at offset 0x000 */ | 15 | /* VLYNQ control register. 32-bit at offset 0x000 */ |
22 | #define TUSB_VLYNQ_CTRL 0x004 | 16 | #define TUSB_VLYNQ_CTRL 0x004 |
23 | 17 | ||
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 3ce152c0408e..4c82077da475 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -625,7 +625,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel) | |||
625 | channel = NULL; | 625 | channel = NULL; |
626 | } | 626 | } |
627 | 627 | ||
628 | void dma_controller_destroy(struct dma_controller *c) | 628 | void tusb_dma_controller_destroy(struct dma_controller *c) |
629 | { | 629 | { |
630 | struct tusb_omap_dma *tusb_dma; | 630 | struct tusb_omap_dma *tusb_dma; |
631 | int i; | 631 | int i; |
@@ -644,8 +644,10 @@ void dma_controller_destroy(struct dma_controller *c) | |||
644 | 644 | ||
645 | kfree(tusb_dma); | 645 | kfree(tusb_dma); |
646 | } | 646 | } |
647 | EXPORT_SYMBOL_GPL(tusb_dma_controller_destroy); | ||
647 | 648 | ||
648 | struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) | 649 | struct dma_controller * |
650 | tusb_dma_controller_create(struct musb *musb, void __iomem *base) | ||
649 | { | 651 | { |
650 | void __iomem *tbase = musb->ctrl_base; | 652 | void __iomem *tbase = musb->ctrl_base; |
651 | struct tusb_omap_dma *tusb_dma; | 653 | struct tusb_omap_dma *tusb_dma; |
@@ -701,7 +703,8 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba | |||
701 | return &tusb_dma->controller; | 703 | return &tusb_dma->controller; |
702 | 704 | ||
703 | cleanup: | 705 | cleanup: |
704 | dma_controller_destroy(&tusb_dma->controller); | 706 | musb_dma_controller_destroy(&tusb_dma->controller); |
705 | out: | 707 | out: |
706 | return NULL; | 708 | return NULL; |
707 | } | 709 | } |
710 | EXPORT_SYMBOL_GPL(tusb_dma_controller_create); | ||
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index abf72728825f..39168fe9b406 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -188,7 +188,11 @@ static int ux500_musb_exit(struct musb *musb) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | static const struct musb_platform_ops ux500_ops = { | 190 | static const struct musb_platform_ops ux500_ops = { |
191 | .quirks = MUSB_INDEXED_EP, | 191 | .quirks = MUSB_DMA_UX500 | MUSB_INDEXED_EP, |
192 | #ifdef CONFIG_USB_UX500_DMA | ||
193 | .dma_init = ux500_dma_controller_create, | ||
194 | .dma_exit = ux500_dma_controller_destroy, | ||
195 | #endif | ||
192 | .init = ux500_musb_init, | 196 | .init = ux500_musb_init, |
193 | .exit = ux500_musb_exit, | 197 | .exit = ux500_musb_exit, |
194 | .fifo_mode = 5, | 198 | .fifo_mode = 5, |
@@ -338,7 +342,7 @@ static int ux500_remove(struct platform_device *pdev) | |||
338 | return 0; | 342 | return 0; |
339 | } | 343 | } |
340 | 344 | ||
341 | #ifdef CONFIG_PM | 345 | #ifdef CONFIG_PM_SLEEP |
342 | static int ux500_suspend(struct device *dev) | 346 | static int ux500_suspend(struct device *dev) |
343 | { | 347 | { |
344 | struct ux500_glue *glue = dev_get_drvdata(dev); | 348 | struct ux500_glue *glue = dev_get_drvdata(dev); |
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index e93845c26bdb..d0b6a1cd7f62 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c | |||
@@ -359,7 +359,7 @@ static int ux500_dma_controller_start(struct ux500_dma_controller *controller) | |||
359 | return 0; | 359 | return 0; |
360 | } | 360 | } |
361 | 361 | ||
362 | void dma_controller_destroy(struct dma_controller *c) | 362 | void ux500_dma_controller_destroy(struct dma_controller *c) |
363 | { | 363 | { |
364 | struct ux500_dma_controller *controller = container_of(c, | 364 | struct ux500_dma_controller *controller = container_of(c, |
365 | struct ux500_dma_controller, controller); | 365 | struct ux500_dma_controller, controller); |
@@ -367,9 +367,10 @@ void dma_controller_destroy(struct dma_controller *c) | |||
367 | ux500_dma_controller_stop(controller); | 367 | ux500_dma_controller_stop(controller); |
368 | kfree(controller); | 368 | kfree(controller); |
369 | } | 369 | } |
370 | EXPORT_SYMBOL_GPL(ux500_dma_controller_destroy); | ||
370 | 371 | ||
371 | struct dma_controller *dma_controller_create(struct musb *musb, | 372 | struct dma_controller * |
372 | void __iomem *base) | 373 | ux500_dma_controller_create(struct musb *musb, void __iomem *base) |
373 | { | 374 | { |
374 | struct ux500_dma_controller *controller; | 375 | struct ux500_dma_controller *controller; |
375 | struct platform_device *pdev = to_platform_device(musb->controller); | 376 | struct platform_device *pdev = to_platform_device(musb->controller); |
@@ -407,3 +408,4 @@ plat_get_fail: | |||
407 | kzalloc_fail: | 408 | kzalloc_fail: |
408 | return NULL; | 409 | return NULL; |
409 | } | 410 | } |
411 | EXPORT_SYMBOL_GPL(ux500_dma_controller_create); | ||
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 2175678e674e..869c0cfcad98 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
@@ -91,7 +91,7 @@ config TWL6030_USB | |||
91 | 91 | ||
92 | config USB_GPIO_VBUS | 92 | config USB_GPIO_VBUS |
93 | tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" | 93 | tristate "GPIO based peripheral-only VBUS sensing 'transceiver'" |
94 | depends on GPIOLIB | 94 | depends on GPIOLIB || COMPILE_TEST |
95 | select USB_PHY | 95 | select USB_PHY |
96 | help | 96 | help |
97 | Provides simple GPIO VBUS sensing for controllers with an | 97 | Provides simple GPIO VBUS sensing for controllers with an |
@@ -141,6 +141,7 @@ config USB_MSM_OTG | |||
141 | tristate "Qualcomm on-chip USB OTG controller support" | 141 | tristate "Qualcomm on-chip USB OTG controller support" |
142 | depends on (USB || USB_GADGET) && (ARCH_QCOM || COMPILE_TEST) | 142 | depends on (USB || USB_GADGET) && (ARCH_QCOM || COMPILE_TEST) |
143 | depends on RESET_CONTROLLER | 143 | depends on RESET_CONTROLLER |
144 | depends on EXTCON | ||
144 | select USB_PHY | 145 | select USB_PHY |
145 | help | 146 | help |
146 | Enable this to support the USB OTG transceiver on Qualcomm chips. It | 147 | Enable this to support the USB OTG transceiver on Qualcomm chips. It |
@@ -186,19 +187,6 @@ config USB_RCAR_PHY | |||
186 | To compile this driver as a module, choose M here: the | 187 | To compile this driver as a module, choose M here: the |
187 | module will be called phy-rcar-usb. | 188 | module will be called phy-rcar-usb. |
188 | 189 | ||
189 | config USB_RCAR_GEN2_PHY | ||
190 | tristate "Renesas R-Car Gen2 USB PHY support" | ||
191 | depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST | ||
192 | select USB_PHY | ||
193 | help | ||
194 | Say Y here to add support for the Renesas R-Car Gen2 USB PHY driver. | ||
195 | It is typically used to control internal USB PHY for USBHS, | ||
196 | and to configure shared USB channels 0 and 2. | ||
197 | This driver supports R8A7790 and R8A7791. | ||
198 | |||
199 | To compile this driver as a module, choose M here: the | ||
200 | module will be called phy-rcar-gen2-usb. | ||
201 | |||
202 | config USB_ULPI | 190 | config USB_ULPI |
203 | bool "Generic ULPI Transceiver Driver" | 191 | bool "Generic ULPI Transceiver Driver" |
204 | depends on ARM || ARM64 | 192 | depends on ARM || ARM64 |
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 75f2bba58c84..e36ab1d46d8b 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile | |||
@@ -23,7 +23,6 @@ obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o | |||
23 | obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o | 23 | obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o |
24 | obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o | 24 | obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o |
25 | obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o | 25 | obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o |
26 | obj-$(CONFIG_USB_RCAR_GEN2_PHY) += phy-rcar-gen2-usb.o | ||
27 | obj-$(CONFIG_USB_ULPI) += phy-ulpi.o | 26 | obj-$(CONFIG_USB_ULPI) += phy-ulpi.o |
28 | obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o | 27 | obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o |
29 | obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o | 28 | obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o |
diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c index 03ab0c699f74..0c912d3950a5 100644 --- a/drivers/usb/phy/phy-ab8500-usb.c +++ b/drivers/usb/phy/phy-ab8500-usb.c | |||
@@ -1504,7 +1504,7 @@ static int ab8500_usb_remove(struct platform_device *pdev) | |||
1504 | return 0; | 1504 | return 0; |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | static struct platform_device_id ab8500_usb_devtype[] = { | 1507 | static const struct platform_device_id ab8500_usb_devtype[] = { |
1508 | { .name = "ab8500-usb", }, | 1508 | { .name = "ab8500-usb", }, |
1509 | { .name = "ab8540-usb", }, | 1509 | { .name = "ab8540-usb", }, |
1510 | { .name = "ab9540-usb", }, | 1510 | { .name = "ab9540-usb", }, |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c9156beeadef..00c49bb1bd29 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -240,8 +240,14 @@ static void ulpi_init(struct msm_otg *motg) | |||
240 | static int msm_phy_notify_disconnect(struct usb_phy *phy, | 240 | static int msm_phy_notify_disconnect(struct usb_phy *phy, |
241 | enum usb_device_speed speed) | 241 | enum usb_device_speed speed) |
242 | { | 242 | { |
243 | struct msm_otg *motg = container_of(phy, struct msm_otg, phy); | ||
243 | int val; | 244 | int val; |
244 | 245 | ||
246 | if (motg->manual_pullup) { | ||
247 | val = ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL; | ||
248 | usb_phy_io_write(phy, val, ULPI_CLR(ULPI_MISC_A)); | ||
249 | } | ||
250 | |||
245 | /* | 251 | /* |
246 | * Put the transceiver in non-driving mode. Otherwise host | 252 | * Put the transceiver in non-driving mode. Otherwise host |
247 | * may not detect soft-disconnection. | 253 | * may not detect soft-disconnection. |
@@ -422,6 +428,24 @@ static int msm_phy_init(struct usb_phy *phy) | |||
422 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); | 428 | ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); |
423 | } | 429 | } |
424 | 430 | ||
431 | if (motg->manual_pullup) { | ||
432 | val = ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT; | ||
433 | ulpi_write(phy, val, ULPI_SET(ULPI_MISC_A)); | ||
434 | |||
435 | val = readl(USB_GENCONFIG_2); | ||
436 | val |= GENCONFIG_2_SESS_VLD_CTRL_EN; | ||
437 | writel(val, USB_GENCONFIG_2); | ||
438 | |||
439 | val = readl(USB_USBCMD); | ||
440 | val |= USBCMD_SESS_VLD_CTRL; | ||
441 | writel(val, USB_USBCMD); | ||
442 | |||
443 | val = ulpi_read(phy, ULPI_FUNC_CTRL); | ||
444 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
445 | val |= ULPI_FUNC_CTRL_OPMODE_NORMAL; | ||
446 | ulpi_write(phy, val, ULPI_FUNC_CTRL); | ||
447 | } | ||
448 | |||
425 | if (motg->phy_number) | 449 | if (motg->phy_number) |
426 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); | 450 | writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); |
427 | 451 | ||
@@ -1436,9 +1460,42 @@ static const struct of_device_id msm_otg_dt_match[] = { | |||
1436 | }; | 1460 | }; |
1437 | MODULE_DEVICE_TABLE(of, msm_otg_dt_match); | 1461 | MODULE_DEVICE_TABLE(of, msm_otg_dt_match); |
1438 | 1462 | ||
1463 | static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event, | ||
1464 | void *ptr) | ||
1465 | { | ||
1466 | struct msm_usb_cable *vbus = container_of(nb, struct msm_usb_cable, nb); | ||
1467 | struct msm_otg *motg = container_of(vbus, struct msm_otg, vbus); | ||
1468 | |||
1469 | if (event) | ||
1470 | set_bit(B_SESS_VLD, &motg->inputs); | ||
1471 | else | ||
1472 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
1473 | |||
1474 | schedule_work(&motg->sm_work); | ||
1475 | |||
1476 | return NOTIFY_DONE; | ||
1477 | } | ||
1478 | |||
1479 | static int msm_otg_id_notifier(struct notifier_block *nb, unsigned long event, | ||
1480 | void *ptr) | ||
1481 | { | ||
1482 | struct msm_usb_cable *id = container_of(nb, struct msm_usb_cable, nb); | ||
1483 | struct msm_otg *motg = container_of(id, struct msm_otg, id); | ||
1484 | |||
1485 | if (event) | ||
1486 | clear_bit(ID, &motg->inputs); | ||
1487 | else | ||
1488 | set_bit(ID, &motg->inputs); | ||
1489 | |||
1490 | schedule_work(&motg->sm_work); | ||
1491 | |||
1492 | return NOTIFY_DONE; | ||
1493 | } | ||
1494 | |||
1439 | static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) | 1495 | static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) |
1440 | { | 1496 | { |
1441 | struct msm_otg_platform_data *pdata; | 1497 | struct msm_otg_platform_data *pdata; |
1498 | struct extcon_dev *ext_id, *ext_vbus; | ||
1442 | const struct of_device_id *id; | 1499 | const struct of_device_id *id; |
1443 | struct device_node *node = pdev->dev.of_node; | 1500 | struct device_node *node = pdev->dev.of_node; |
1444 | struct property *prop; | 1501 | struct property *prop; |
@@ -1487,6 +1544,54 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) | |||
1487 | motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; | 1544 | motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; |
1488 | } | 1545 | } |
1489 | 1546 | ||
1547 | motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup"); | ||
1548 | |||
1549 | ext_id = ERR_PTR(-ENODEV); | ||
1550 | ext_vbus = ERR_PTR(-ENODEV); | ||
1551 | if (of_property_read_bool(node, "extcon")) { | ||
1552 | |||
1553 | /* Each one of them is not mandatory */ | ||
1554 | ext_vbus = extcon_get_edev_by_phandle(&pdev->dev, 0); | ||
1555 | if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV) | ||
1556 | return PTR_ERR(ext_vbus); | ||
1557 | |||
1558 | ext_id = extcon_get_edev_by_phandle(&pdev->dev, 1); | ||
1559 | if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV) | ||
1560 | return PTR_ERR(ext_id); | ||
1561 | } | ||
1562 | |||
1563 | if (!IS_ERR(ext_vbus)) { | ||
1564 | motg->vbus.nb.notifier_call = msm_otg_vbus_notifier; | ||
1565 | ret = extcon_register_interest(&motg->vbus.conn, ext_vbus->name, | ||
1566 | "USB", &motg->vbus.nb); | ||
1567 | if (ret < 0) { | ||
1568 | dev_err(&pdev->dev, "register VBUS notifier failed\n"); | ||
1569 | return ret; | ||
1570 | } | ||
1571 | |||
1572 | ret = extcon_get_cable_state(ext_vbus, "USB"); | ||
1573 | if (ret) | ||
1574 | set_bit(B_SESS_VLD, &motg->inputs); | ||
1575 | else | ||
1576 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
1577 | } | ||
1578 | |||
1579 | if (!IS_ERR(ext_id)) { | ||
1580 | motg->id.nb.notifier_call = msm_otg_id_notifier; | ||
1581 | ret = extcon_register_interest(&motg->id.conn, ext_id->name, | ||
1582 | "USB-HOST", &motg->id.nb); | ||
1583 | if (ret < 0) { | ||
1584 | dev_err(&pdev->dev, "register ID notifier failed\n"); | ||
1585 | return ret; | ||
1586 | } | ||
1587 | |||
1588 | ret = extcon_get_cable_state(ext_id, "USB-HOST"); | ||
1589 | if (ret) | ||
1590 | clear_bit(ID, &motg->inputs); | ||
1591 | else | ||
1592 | set_bit(ID, &motg->inputs); | ||
1593 | } | ||
1594 | |||
1490 | prop = of_find_property(node, "qcom,phy-init-sequence", &len); | 1595 | prop = of_find_property(node, "qcom,phy-init-sequence", &len); |
1491 | if (!prop || !len) | 1596 | if (!prop || !len) |
1492 | return 0; | 1597 | return 0; |
@@ -1700,6 +1805,11 @@ static int msm_otg_remove(struct platform_device *pdev) | |||
1700 | if (phy->otg->host || phy->otg->gadget) | 1805 | if (phy->otg->host || phy->otg->gadget) |
1701 | return -EBUSY; | 1806 | return -EBUSY; |
1702 | 1807 | ||
1808 | if (motg->id.conn.edev) | ||
1809 | extcon_unregister_interest(&motg->id.conn); | ||
1810 | if (motg->vbus.conn.edev) | ||
1811 | extcon_unregister_interest(&motg->vbus.conn); | ||
1812 | |||
1703 | msm_otg_debugfs_cleanup(); | 1813 | msm_otg_debugfs_cleanup(); |
1704 | cancel_delayed_work_sync(&motg->chg_work); | 1814 | cancel_delayed_work_sync(&motg->chg_work); |
1705 | cancel_work_sync(&motg->sm_work); | 1815 | cancel_work_sync(&motg->sm_work); |
diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c deleted file mode 100644 index f81800b6562a..000000000000 --- a/drivers/usb/phy/phy-rcar-gen2-usb.c +++ /dev/null | |||
@@ -1,246 +0,0 @@ | |||
1 | /* | ||
2 | * Renesas R-Car Gen2 USB phy driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Renesas Solutions Corp. | ||
5 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_data/usb-rcar-gen2-phy.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/usb/otg.h> | ||
20 | |||
21 | struct rcar_gen2_usb_phy_priv { | ||
22 | struct usb_phy phy; | ||
23 | void __iomem *base; | ||
24 | struct clk *clk; | ||
25 | spinlock_t lock; | ||
26 | int usecount; | ||
27 | u32 ugctrl2; | ||
28 | }; | ||
29 | |||
30 | #define usb_phy_to_priv(p) container_of(p, struct rcar_gen2_usb_phy_priv, phy) | ||
31 | |||
32 | /* Low Power Status register */ | ||
33 | #define USBHS_LPSTS_REG 0x02 | ||
34 | #define USBHS_LPSTS_SUSPM (1 << 14) | ||
35 | |||
36 | /* USB General control register */ | ||
37 | #define USBHS_UGCTRL_REG 0x80 | ||
38 | #define USBHS_UGCTRL_CONNECT (1 << 2) | ||
39 | #define USBHS_UGCTRL_PLLRESET (1 << 0) | ||
40 | |||
41 | /* USB General control register 2 */ | ||
42 | #define USBHS_UGCTRL2_REG 0x84 | ||
43 | #define USBHS_UGCTRL2_USB0_PCI (1 << 4) | ||
44 | #define USBHS_UGCTRL2_USB0_HS (3 << 4) | ||
45 | #define USBHS_UGCTRL2_USB2_PCI (0 << 31) | ||
46 | #define USBHS_UGCTRL2_USB2_SS (1 << 31) | ||
47 | |||
48 | /* USB General status register */ | ||
49 | #define USBHS_UGSTS_REG 0x88 | ||
50 | #define USBHS_UGSTS_LOCK (1 << 8) | ||
51 | |||
52 | /* Enable USBHS internal phy */ | ||
53 | static int __rcar_gen2_usbhs_phy_enable(void __iomem *base) | ||
54 | { | ||
55 | u32 val; | ||
56 | int i; | ||
57 | |||
58 | /* USBHS PHY power on */ | ||
59 | val = ioread32(base + USBHS_UGCTRL_REG); | ||
60 | val &= ~USBHS_UGCTRL_PLLRESET; | ||
61 | iowrite32(val, base + USBHS_UGCTRL_REG); | ||
62 | |||
63 | val = ioread16(base + USBHS_LPSTS_REG); | ||
64 | val |= USBHS_LPSTS_SUSPM; | ||
65 | iowrite16(val, base + USBHS_LPSTS_REG); | ||
66 | |||
67 | for (i = 0; i < 20; i++) { | ||
68 | val = ioread32(base + USBHS_UGSTS_REG); | ||
69 | if ((val & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) { | ||
70 | val = ioread32(base + USBHS_UGCTRL_REG); | ||
71 | val |= USBHS_UGCTRL_CONNECT; | ||
72 | iowrite32(val, base + USBHS_UGCTRL_REG); | ||
73 | return 0; | ||
74 | } | ||
75 | udelay(1); | ||
76 | } | ||
77 | |||
78 | /* Timed out waiting for the PLL lock */ | ||
79 | return -ETIMEDOUT; | ||
80 | } | ||
81 | |||
82 | /* Disable USBHS internal phy */ | ||
83 | static int __rcar_gen2_usbhs_phy_disable(void __iomem *base) | ||
84 | { | ||
85 | u32 val; | ||
86 | |||
87 | /* USBHS PHY power off */ | ||
88 | val = ioread32(base + USBHS_UGCTRL_REG); | ||
89 | val &= ~USBHS_UGCTRL_CONNECT; | ||
90 | iowrite32(val, base + USBHS_UGCTRL_REG); | ||
91 | |||
92 | val = ioread16(base + USBHS_LPSTS_REG); | ||
93 | val &= ~USBHS_LPSTS_SUSPM; | ||
94 | iowrite16(val, base + USBHS_LPSTS_REG); | ||
95 | |||
96 | val = ioread32(base + USBHS_UGCTRL_REG); | ||
97 | val |= USBHS_UGCTRL_PLLRESET; | ||
98 | iowrite32(val, base + USBHS_UGCTRL_REG); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | /* Setup USB channels */ | ||
103 | static void __rcar_gen2_usb_phy_init(struct rcar_gen2_usb_phy_priv *priv) | ||
104 | { | ||
105 | u32 val; | ||
106 | |||
107 | clk_prepare_enable(priv->clk); | ||
108 | |||
109 | /* Set USB channels in the USBHS UGCTRL2 register */ | ||
110 | val = ioread32(priv->base + USBHS_UGCTRL2_REG); | ||
111 | val &= ~(USBHS_UGCTRL2_USB0_HS | USBHS_UGCTRL2_USB2_SS); | ||
112 | val |= priv->ugctrl2; | ||
113 | iowrite32(val, priv->base + USBHS_UGCTRL2_REG); | ||
114 | } | ||
115 | |||
116 | /* Shutdown USB channels */ | ||
117 | static void __rcar_gen2_usb_phy_shutdown(struct rcar_gen2_usb_phy_priv *priv) | ||
118 | { | ||
119 | __rcar_gen2_usbhs_phy_disable(priv->base); | ||
120 | clk_disable_unprepare(priv->clk); | ||
121 | } | ||
122 | |||
123 | static int rcar_gen2_usb_phy_set_suspend(struct usb_phy *phy, int suspend) | ||
124 | { | ||
125 | struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); | ||
126 | unsigned long flags; | ||
127 | int retval; | ||
128 | |||
129 | spin_lock_irqsave(&priv->lock, flags); | ||
130 | retval = suspend ? __rcar_gen2_usbhs_phy_disable(priv->base) : | ||
131 | __rcar_gen2_usbhs_phy_enable(priv->base); | ||
132 | spin_unlock_irqrestore(&priv->lock, flags); | ||
133 | return retval; | ||
134 | } | ||
135 | |||
136 | static int rcar_gen2_usb_phy_init(struct usb_phy *phy) | ||
137 | { | ||
138 | struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); | ||
139 | unsigned long flags; | ||
140 | |||
141 | spin_lock_irqsave(&priv->lock, flags); | ||
142 | /* | ||
143 | * Enable the clock and setup USB channels | ||
144 | * if it's the first user | ||
145 | */ | ||
146 | if (!priv->usecount++) | ||
147 | __rcar_gen2_usb_phy_init(priv); | ||
148 | spin_unlock_irqrestore(&priv->lock, flags); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void rcar_gen2_usb_phy_shutdown(struct usb_phy *phy) | ||
153 | { | ||
154 | struct rcar_gen2_usb_phy_priv *priv = usb_phy_to_priv(phy); | ||
155 | unsigned long flags; | ||
156 | |||
157 | spin_lock_irqsave(&priv->lock, flags); | ||
158 | if (!priv->usecount) { | ||
159 | dev_warn(phy->dev, "Trying to disable phy with 0 usecount\n"); | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | /* Disable everything if it's the last user */ | ||
164 | if (!--priv->usecount) | ||
165 | __rcar_gen2_usb_phy_shutdown(priv); | ||
166 | out: | ||
167 | spin_unlock_irqrestore(&priv->lock, flags); | ||
168 | } | ||
169 | |||
170 | static int rcar_gen2_usb_phy_probe(struct platform_device *pdev) | ||
171 | { | ||
172 | struct device *dev = &pdev->dev; | ||
173 | struct rcar_gen2_phy_platform_data *pdata; | ||
174 | struct rcar_gen2_usb_phy_priv *priv; | ||
175 | struct resource *res; | ||
176 | void __iomem *base; | ||
177 | struct clk *clk; | ||
178 | int retval; | ||
179 | |||
180 | pdata = dev_get_platdata(dev); | ||
181 | if (!pdata) { | ||
182 | dev_err(dev, "No platform data\n"); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | clk = devm_clk_get(dev, "usbhs"); | ||
187 | if (IS_ERR(clk)) { | ||
188 | dev_err(dev, "Can't get the clock\n"); | ||
189 | return PTR_ERR(clk); | ||
190 | } | ||
191 | |||
192 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
193 | base = devm_ioremap_resource(dev, res); | ||
194 | if (IS_ERR(base)) | ||
195 | return PTR_ERR(base); | ||
196 | |||
197 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
198 | if (!priv) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | spin_lock_init(&priv->lock); | ||
202 | priv->clk = clk; | ||
203 | priv->base = base; | ||
204 | priv->ugctrl2 = pdata->chan0_pci ? | ||
205 | USBHS_UGCTRL2_USB0_PCI : USBHS_UGCTRL2_USB0_HS; | ||
206 | priv->ugctrl2 |= pdata->chan2_pci ? | ||
207 | USBHS_UGCTRL2_USB2_PCI : USBHS_UGCTRL2_USB2_SS; | ||
208 | priv->phy.dev = dev; | ||
209 | priv->phy.label = dev_name(dev); | ||
210 | priv->phy.init = rcar_gen2_usb_phy_init; | ||
211 | priv->phy.shutdown = rcar_gen2_usb_phy_shutdown; | ||
212 | priv->phy.set_suspend = rcar_gen2_usb_phy_set_suspend; | ||
213 | |||
214 | retval = usb_add_phy_dev(&priv->phy); | ||
215 | if (retval < 0) { | ||
216 | dev_err(dev, "Failed to add USB phy\n"); | ||
217 | return retval; | ||
218 | } | ||
219 | |||
220 | platform_set_drvdata(pdev, priv); | ||
221 | |||
222 | return retval; | ||
223 | } | ||
224 | |||
225 | static int rcar_gen2_usb_phy_remove(struct platform_device *pdev) | ||
226 | { | ||
227 | struct rcar_gen2_usb_phy_priv *priv = platform_get_drvdata(pdev); | ||
228 | |||
229 | usb_remove_phy(&priv->phy); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static struct platform_driver rcar_gen2_usb_phy_driver = { | ||
235 | .driver = { | ||
236 | .name = "usb_phy_rcar_gen2", | ||
237 | }, | ||
238 | .probe = rcar_gen2_usb_phy_probe, | ||
239 | .remove = rcar_gen2_usb_phy_remove, | ||
240 | }; | ||
241 | |||
242 | module_platform_driver(rcar_gen2_usb_phy_driver); | ||
243 | |||
244 | MODULE_LICENSE("GPL v2"); | ||
245 | MODULE_DESCRIPTION("Renesas R-Car Gen2 USB phy"); | ||
246 | MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>"); | ||
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index d1cd6b50f520..98f75d2842b7 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
@@ -22,6 +22,11 @@ static LIST_HEAD(phy_list); | |||
22 | static LIST_HEAD(phy_bind_list); | 22 | static LIST_HEAD(phy_bind_list); |
23 | static DEFINE_SPINLOCK(phy_lock); | 23 | static DEFINE_SPINLOCK(phy_lock); |
24 | 24 | ||
25 | struct phy_devm { | ||
26 | struct usb_phy *phy; | ||
27 | struct notifier_block *nb; | ||
28 | }; | ||
29 | |||
25 | static struct usb_phy *__usb_find_phy(struct list_head *list, | 30 | static struct usb_phy *__usb_find_phy(struct list_head *list, |
26 | enum usb_phy_type type) | 31 | enum usb_phy_type type) |
27 | { | 32 | { |
@@ -79,6 +84,15 @@ static void devm_usb_phy_release(struct device *dev, void *res) | |||
79 | usb_put_phy(phy); | 84 | usb_put_phy(phy); |
80 | } | 85 | } |
81 | 86 | ||
87 | static void devm_usb_phy_release2(struct device *dev, void *_res) | ||
88 | { | ||
89 | struct phy_devm *res = _res; | ||
90 | |||
91 | if (res->nb) | ||
92 | usb_unregister_notifier(res->phy, res->nb); | ||
93 | usb_put_phy(res->phy); | ||
94 | } | ||
95 | |||
82 | static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) | 96 | static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) |
83 | { | 97 | { |
84 | struct usb_phy **phy = res; | 98 | struct usb_phy **phy = res; |
@@ -153,40 +167,30 @@ err0: | |||
153 | EXPORT_SYMBOL_GPL(usb_get_phy); | 167 | EXPORT_SYMBOL_GPL(usb_get_phy); |
154 | 168 | ||
155 | /** | 169 | /** |
156 | * devm_usb_get_phy_by_phandle - find the USB PHY by phandle | 170 | * devm_usb_get_phy_by_node - find the USB PHY by device_node |
157 | * @dev - device that requests this phy | 171 | * @dev - device that requests this phy |
158 | * @phandle - name of the property holding the phy phandle value | 172 | * @node - the device_node for the phy device. |
159 | * @index - the index of the phy | 173 | * @nb - a notifier_block to register with the phy. |
160 | * | 174 | * |
161 | * Returns the phy driver associated with the given phandle value, | 175 | * Returns the phy driver associated with the given device_node, |
162 | * after getting a refcount to it, -ENODEV if there is no such phy or | 176 | * after getting a refcount to it, -ENODEV if there is no such phy or |
163 | * -EPROBE_DEFER if there is a phandle to the phy, but the device is | 177 | * -EPROBE_DEFER if the device is not yet loaded. While at that, it |
164 | * not yet loaded. While at that, it also associates the device with | 178 | * also associates the device with |
165 | * the phy using devres. On driver detach, release function is invoked | 179 | * the phy using devres. On driver detach, release function is invoked |
166 | * on the devres data, then, devres data is freed. | 180 | * on the devres data, then, devres data is freed. |
167 | * | 181 | * |
168 | * For use by USB host and peripheral drivers. | 182 | * For use by peripheral drivers for devices related to a phy, |
183 | * such as a charger. | ||
169 | */ | 184 | */ |
170 | struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | 185 | struct usb_phy *devm_usb_get_phy_by_node(struct device *dev, |
171 | const char *phandle, u8 index) | 186 | struct device_node *node, |
187 | struct notifier_block *nb) | ||
172 | { | 188 | { |
173 | struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr; | 189 | struct usb_phy *phy = ERR_PTR(-ENOMEM); |
190 | struct phy_devm *ptr; | ||
174 | unsigned long flags; | 191 | unsigned long flags; |
175 | struct device_node *node; | ||
176 | 192 | ||
177 | if (!dev->of_node) { | 193 | ptr = devres_alloc(devm_usb_phy_release2, sizeof(*ptr), GFP_KERNEL); |
178 | dev_dbg(dev, "device does not have a device node entry\n"); | ||
179 | return ERR_PTR(-EINVAL); | ||
180 | } | ||
181 | |||
182 | node = of_parse_phandle(dev->of_node, phandle, index); | ||
183 | if (!node) { | ||
184 | dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, | ||
185 | dev->of_node->full_name); | ||
186 | return ERR_PTR(-ENODEV); | ||
187 | } | ||
188 | |||
189 | ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
190 | if (!ptr) { | 194 | if (!ptr) { |
191 | dev_dbg(dev, "failed to allocate memory for devres\n"); | 195 | dev_dbg(dev, "failed to allocate memory for devres\n"); |
192 | goto err0; | 196 | goto err0; |
@@ -205,8 +209,10 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | |||
205 | devres_free(ptr); | 209 | devres_free(ptr); |
206 | goto err1; | 210 | goto err1; |
207 | } | 211 | } |
208 | 212 | if (nb) | |
209 | *ptr = phy; | 213 | usb_register_notifier(phy, nb); |
214 | ptr->phy = phy; | ||
215 | ptr->nb = nb; | ||
210 | devres_add(dev, ptr); | 216 | devres_add(dev, ptr); |
211 | 217 | ||
212 | get_device(phy->dev); | 218 | get_device(phy->dev); |
@@ -215,10 +221,47 @@ err1: | |||
215 | spin_unlock_irqrestore(&phy_lock, flags); | 221 | spin_unlock_irqrestore(&phy_lock, flags); |
216 | 222 | ||
217 | err0: | 223 | err0: |
218 | of_node_put(node); | ||
219 | 224 | ||
220 | return phy; | 225 | return phy; |
221 | } | 226 | } |
227 | EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_node); | ||
228 | |||
229 | /** | ||
230 | * devm_usb_get_phy_by_phandle - find the USB PHY by phandle | ||
231 | * @dev - device that requests this phy | ||
232 | * @phandle - name of the property holding the phy phandle value | ||
233 | * @index - the index of the phy | ||
234 | * | ||
235 | * Returns the phy driver associated with the given phandle value, | ||
236 | * after getting a refcount to it, -ENODEV if there is no such phy or | ||
237 | * -EPROBE_DEFER if there is a phandle to the phy, but the device is | ||
238 | * not yet loaded. While at that, it also associates the device with | ||
239 | * the phy using devres. On driver detach, release function is invoked | ||
240 | * on the devres data, then, devres data is freed. | ||
241 | * | ||
242 | * For use by USB host and peripheral drivers. | ||
243 | */ | ||
244 | struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | ||
245 | const char *phandle, u8 index) | ||
246 | { | ||
247 | struct device_node *node; | ||
248 | struct usb_phy *phy; | ||
249 | |||
250 | if (!dev->of_node) { | ||
251 | dev_dbg(dev, "device does not have a device node entry\n"); | ||
252 | return ERR_PTR(-EINVAL); | ||
253 | } | ||
254 | |||
255 | node = of_parse_phandle(dev->of_node, phandle, index); | ||
256 | if (!node) { | ||
257 | dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, | ||
258 | dev->of_node->full_name); | ||
259 | return ERR_PTR(-ENODEV); | ||
260 | } | ||
261 | phy = devm_usb_get_phy_by_node(dev, node, NULL); | ||
262 | of_node_put(node); | ||
263 | return phy; | ||
264 | } | ||
222 | EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle); | 265 | EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle); |
223 | 266 | ||
224 | /** | 267 | /** |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 0f7e850fd4aa..e8bf40808b39 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -466,11 +466,15 @@ static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | |||
466 | static const struct of_device_id usbhs_of_match[] = { | 466 | static const struct of_device_id usbhs_of_match[] = { |
467 | { | 467 | { |
468 | .compatible = "renesas,usbhs-r8a7790", | 468 | .compatible = "renesas,usbhs-r8a7790", |
469 | .data = (void *)USBHS_TYPE_R8A7790, | 469 | .data = (void *)USBHS_TYPE_RCAR_GEN2, |
470 | }, | 470 | }, |
471 | { | 471 | { |
472 | .compatible = "renesas,usbhs-r8a7791", | 472 | .compatible = "renesas,usbhs-r8a7791", |
473 | .data = (void *)USBHS_TYPE_R8A7791, | 473 | .data = (void *)USBHS_TYPE_RCAR_GEN2, |
474 | }, | ||
475 | { | ||
476 | .compatible = "renesas,usbhs-r8a7794", | ||
477 | .data = (void *)USBHS_TYPE_RCAR_GEN2, | ||
474 | }, | 478 | }, |
475 | { }, | 479 | { }, |
476 | }; | 480 | }; |
@@ -497,14 +501,8 @@ static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev) | |||
497 | if (gpio > 0) | 501 | if (gpio > 0) |
498 | dparam->enable_gpio = gpio; | 502 | dparam->enable_gpio = gpio; |
499 | 503 | ||
500 | switch (dparam->type) { | 504 | if (dparam->type == USBHS_TYPE_RCAR_GEN2) |
501 | case USBHS_TYPE_R8A7790: | ||
502 | case USBHS_TYPE_R8A7791: | ||
503 | dparam->has_usb_dmac = 1; | 505 | dparam->has_usb_dmac = 1; |
504 | break; | ||
505 | default: | ||
506 | break; | ||
507 | } | ||
508 | 506 | ||
509 | return info; | 507 | return info; |
510 | } | 508 | } |
@@ -559,8 +557,7 @@ static int usbhs_probe(struct platform_device *pdev) | |||
559 | sizeof(struct renesas_usbhs_driver_param)); | 557 | sizeof(struct renesas_usbhs_driver_param)); |
560 | 558 | ||
561 | switch (priv->dparam.type) { | 559 | switch (priv->dparam.type) { |
562 | case USBHS_TYPE_R8A7790: | 560 | case USBHS_TYPE_RCAR_GEN2: |
563 | case USBHS_TYPE_R8A7791: | ||
564 | priv->pfunc = usbhs_rcar2_ops; | 561 | priv->pfunc = usbhs_rcar2_ops; |
565 | if (!priv->dparam.pipe_type) { | 562 | if (!priv->dparam.pipe_type) { |
566 | priv->dparam.pipe_type = usbhsc_new_pipe_type; | 563 | priv->dparam.pipe_type = usbhsc_new_pipe_type; |
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index 04d3f8abad9e..c7d9b86d51bf 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -44,10 +44,11 @@ struct usbhs_fifo_info { | |||
44 | struct usbhs_fifo dfifo[USBHS_MAX_NUM_DFIFO]; | 44 | struct usbhs_fifo dfifo[USBHS_MAX_NUM_DFIFO]; |
45 | }; | 45 | }; |
46 | #define usbhsf_get_dnfifo(p, n) (&((p)->fifo_info.dfifo[n])) | 46 | #define usbhsf_get_dnfifo(p, n) (&((p)->fifo_info.dfifo[n])) |
47 | #define usbhs_for_each_dfifo(priv, dfifo, i) \ | 47 | #define usbhs_for_each_dfifo(priv, dfifo, i) \ |
48 | for ((i) = 0, dfifo = usbhsf_get_dnfifo(priv, (i)); \ | 48 | for ((i) = 0; \ |
49 | ((i) < USBHS_MAX_NUM_DFIFO); \ | 49 | ((i) < USBHS_MAX_NUM_DFIFO) && \ |
50 | (i)++, dfifo = usbhsf_get_dnfifo(priv, (i))) | 50 | ((dfifo) = usbhsf_get_dnfifo(priv, (i))); \ |
51 | (i)++) | ||
51 | 52 | ||
52 | struct usbhs_pkt_handle; | 53 | struct usbhs_pkt_handle; |
53 | struct usbhs_pkt { | 54 | struct usbhs_pkt { |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 9a705b15b3a1..d4be5d594896 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -218,10 +218,14 @@ static int usbhs_status_get_each_irq(struct usbhs_priv *priv, | |||
218 | /******************** spin lock ********************/ | 218 | /******************** spin lock ********************/ |
219 | usbhs_lock(priv, flags); | 219 | usbhs_lock(priv, flags); |
220 | state->intsts0 = usbhs_read(priv, INTSTS0); | 220 | state->intsts0 = usbhs_read(priv, INTSTS0); |
221 | state->intsts1 = usbhs_read(priv, INTSTS1); | ||
222 | |||
223 | intenb0 = usbhs_read(priv, INTENB0); | 221 | intenb0 = usbhs_read(priv, INTENB0); |
224 | intenb1 = usbhs_read(priv, INTENB1); | 222 | |
223 | if (usbhs_mod_is_host(priv)) { | ||
224 | state->intsts1 = usbhs_read(priv, INTSTS1); | ||
225 | intenb1 = usbhs_read(priv, INTENB1); | ||
226 | } else { | ||
227 | state->intsts1 = intenb1 = 0; | ||
228 | } | ||
225 | 229 | ||
226 | /* mask */ | 230 | /* mask */ |
227 | if (mod) { | 231 | if (mod) { |
@@ -275,7 +279,8 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) | |||
275 | * - Function :: VALID bit should 0 | 279 | * - Function :: VALID bit should 0 |
276 | */ | 280 | */ |
277 | usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); | 281 | usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); |
278 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); | 282 | if (usbhs_mod_is_host(priv)) |
283 | usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); | ||
279 | 284 | ||
280 | usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); | 285 | usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); |
281 | usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); | 286 | usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); |
@@ -303,19 +308,20 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) | |||
303 | if (irq_state.intsts0 & BRDY) | 308 | if (irq_state.intsts0 & BRDY) |
304 | usbhs_mod_call(priv, irq_ready, priv, &irq_state); | 309 | usbhs_mod_call(priv, irq_ready, priv, &irq_state); |
305 | 310 | ||
306 | /* INTSTS1 */ | 311 | if (usbhs_mod_is_host(priv)) { |
307 | if (irq_state.intsts1 & ATTCH) | 312 | /* INTSTS1 */ |
308 | usbhs_mod_call(priv, irq_attch, priv, &irq_state); | 313 | if (irq_state.intsts1 & ATTCH) |
309 | 314 | usbhs_mod_call(priv, irq_attch, priv, &irq_state); | |
310 | if (irq_state.intsts1 & DTCH) | ||
311 | usbhs_mod_call(priv, irq_dtch, priv, &irq_state); | ||
312 | 315 | ||
313 | if (irq_state.intsts1 & SIGN) | 316 | if (irq_state.intsts1 & DTCH) |
314 | usbhs_mod_call(priv, irq_sign, priv, &irq_state); | 317 | usbhs_mod_call(priv, irq_dtch, priv, &irq_state); |
315 | 318 | ||
316 | if (irq_state.intsts1 & SACK) | 319 | if (irq_state.intsts1 & SIGN) |
317 | usbhs_mod_call(priv, irq_sack, priv, &irq_state); | 320 | usbhs_mod_call(priv, irq_sign, priv, &irq_state); |
318 | 321 | ||
322 | if (irq_state.intsts1 & SACK) | ||
323 | usbhs_mod_call(priv, irq_sack, priv, &irq_state); | ||
324 | } | ||
319 | return IRQ_HANDLED; | 325 | return IRQ_HANDLED; |
320 | } | 326 | } |
321 | 327 | ||
@@ -334,7 +340,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) | |||
334 | * - update INTSTS0 | 340 | * - update INTSTS0 |
335 | */ | 341 | */ |
336 | usbhs_write(priv, INTENB0, 0); | 342 | usbhs_write(priv, INTENB0, 0); |
337 | usbhs_write(priv, INTENB1, 0); | 343 | if (usbhs_mod_is_host(priv)) |
344 | usbhs_write(priv, INTENB1, 0); | ||
338 | 345 | ||
339 | usbhs_write(priv, BEMPENB, 0); | 346 | usbhs_write(priv, BEMPENB, 0); |
340 | usbhs_write(priv, BRDYENB, 0); | 347 | usbhs_write(priv, BRDYENB, 0); |
@@ -368,25 +375,27 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) | |||
368 | intenb0 |= BRDYE; | 375 | intenb0 |= BRDYE; |
369 | } | 376 | } |
370 | 377 | ||
371 | /* | 378 | if (usbhs_mod_is_host(priv)) { |
372 | * INTSTS1 | 379 | /* |
373 | */ | 380 | * INTSTS1 |
374 | if (mod->irq_attch) | 381 | */ |
375 | intenb1 |= ATTCHE; | 382 | if (mod->irq_attch) |
383 | intenb1 |= ATTCHE; | ||
376 | 384 | ||
377 | if (mod->irq_dtch) | 385 | if (mod->irq_dtch) |
378 | intenb1 |= DTCHE; | 386 | intenb1 |= DTCHE; |
379 | 387 | ||
380 | if (mod->irq_sign) | 388 | if (mod->irq_sign) |
381 | intenb1 |= SIGNE; | 389 | intenb1 |= SIGNE; |
382 | 390 | ||
383 | if (mod->irq_sack) | 391 | if (mod->irq_sack) |
384 | intenb1 |= SACKE; | 392 | intenb1 |= SACKE; |
393 | } | ||
385 | } | 394 | } |
386 | 395 | ||
387 | if (intenb0) | 396 | if (intenb0) |
388 | usbhs_write(priv, INTENB0, intenb0); | 397 | usbhs_write(priv, INTENB0, intenb0); |
389 | 398 | ||
390 | if (intenb1) | 399 | if (usbhs_mod_is_host(priv) && intenb1) |
391 | usbhs_write(priv, INTENB1, intenb1); | 400 | usbhs_write(priv, INTENB1, intenb1); |
392 | } | 401 | } |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index e4473a9109cf..8ac9b55f05af 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -2301,17 +2301,14 @@ static int mos7840_port_probe(struct usb_serial_port *port) | |||
2301 | goto error; | 2301 | goto error; |
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | init_timer(&mos7840_port->led_timer1); | 2304 | setup_timer(&mos7840_port->led_timer1, mos7840_led_off, |
2305 | mos7840_port->led_timer1.function = mos7840_led_off; | 2305 | (unsigned long)mos7840_port); |
2306 | mos7840_port->led_timer1.expires = | 2306 | mos7840_port->led_timer1.expires = |
2307 | jiffies + msecs_to_jiffies(LED_ON_MS); | 2307 | jiffies + msecs_to_jiffies(LED_ON_MS); |
2308 | mos7840_port->led_timer1.data = (unsigned long)mos7840_port; | 2308 | setup_timer(&mos7840_port->led_timer2, mos7840_led_flag_off, |
2309 | 2309 | (unsigned long)mos7840_port); | |
2310 | init_timer(&mos7840_port->led_timer2); | ||
2311 | mos7840_port->led_timer2.function = mos7840_led_flag_off; | ||
2312 | mos7840_port->led_timer2.expires = | 2310 | mos7840_port->led_timer2.expires = |
2313 | jiffies + msecs_to_jiffies(LED_OFF_MS); | 2311 | jiffies + msecs_to_jiffies(LED_OFF_MS); |
2314 | mos7840_port->led_timer2.data = (unsigned long)mos7840_port; | ||
2315 | 2312 | ||
2316 | /* Turn off LED */ | 2313 | /* Turn off LED */ |
2317 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); | 2314 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); |
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 4b55ab66a534..171fa7d793bc 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #include "transport.h" | 42 | #include "transport.h" |
43 | #include "protocol.h" | 43 | #include "protocol.h" |
44 | #include "debug.h" | 44 | #include "debug.h" |
45 | #include "scsiglue.h" | ||
46 | |||
47 | #define DRV_NAME "ums-alauda" | ||
45 | 48 | ||
46 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); | 49 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); |
47 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); | 50 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); |
@@ -1232,6 +1235,8 @@ static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1232 | return USB_STOR_TRANSPORT_FAILED; | 1235 | return USB_STOR_TRANSPORT_FAILED; |
1233 | } | 1236 | } |
1234 | 1237 | ||
1238 | static struct scsi_host_template alauda_host_template; | ||
1239 | |||
1235 | static int alauda_probe(struct usb_interface *intf, | 1240 | static int alauda_probe(struct usb_interface *intf, |
1236 | const struct usb_device_id *id) | 1241 | const struct usb_device_id *id) |
1237 | { | 1242 | { |
@@ -1239,7 +1244,8 @@ static int alauda_probe(struct usb_interface *intf, | |||
1239 | int result; | 1244 | int result; |
1240 | 1245 | ||
1241 | result = usb_stor_probe1(&us, intf, id, | 1246 | result = usb_stor_probe1(&us, intf, id, |
1242 | (id - alauda_usb_ids) + alauda_unusual_dev_list); | 1247 | (id - alauda_usb_ids) + alauda_unusual_dev_list, |
1248 | &alauda_host_template); | ||
1243 | if (result) | 1249 | if (result) |
1244 | return result; | 1250 | return result; |
1245 | 1251 | ||
@@ -1253,7 +1259,7 @@ static int alauda_probe(struct usb_interface *intf, | |||
1253 | } | 1259 | } |
1254 | 1260 | ||
1255 | static struct usb_driver alauda_driver = { | 1261 | static struct usb_driver alauda_driver = { |
1256 | .name = "ums-alauda", | 1262 | .name = DRV_NAME, |
1257 | .probe = alauda_probe, | 1263 | .probe = alauda_probe, |
1258 | .disconnect = usb_stor_disconnect, | 1264 | .disconnect = usb_stor_disconnect, |
1259 | .suspend = usb_stor_suspend, | 1265 | .suspend = usb_stor_suspend, |
@@ -1266,4 +1272,4 @@ static struct usb_driver alauda_driver = { | |||
1266 | .no_dynamic_id = 1, | 1272 | .no_dynamic_id = 1, |
1267 | }; | 1273 | }; |
1268 | 1274 | ||
1269 | module_usb_driver(alauda_driver); | 1275 | module_usb_stor_driver(alauda_driver, alauda_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index b3466d1395f2..c80d3dec9a34 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "scsiglue.h" | 30 | #include "scsiglue.h" |
31 | #include "debug.h" | 31 | #include "debug.h" |
32 | 32 | ||
33 | #define DRV_NAME "ums-cypress" | ||
34 | |||
33 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); | 35 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); |
34 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); | 36 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); |
35 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
@@ -241,6 +243,7 @@ end: | |||
241 | srb->cmd_len = 12; | 243 | srb->cmd_len = 12; |
242 | } | 244 | } |
243 | 245 | ||
246 | static struct scsi_host_template cypress_host_template; | ||
244 | 247 | ||
245 | static int cypress_probe(struct usb_interface *intf, | 248 | static int cypress_probe(struct usb_interface *intf, |
246 | const struct usb_device_id *id) | 249 | const struct usb_device_id *id) |
@@ -250,7 +253,8 @@ static int cypress_probe(struct usb_interface *intf, | |||
250 | struct usb_device *device; | 253 | struct usb_device *device; |
251 | 254 | ||
252 | result = usb_stor_probe1(&us, intf, id, | 255 | result = usb_stor_probe1(&us, intf, id, |
253 | (id - cypress_usb_ids) + cypress_unusual_dev_list); | 256 | (id - cypress_usb_ids) + cypress_unusual_dev_list, |
257 | &cypress_host_template); | ||
254 | if (result) | 258 | if (result) |
255 | return result; | 259 | return result; |
256 | 260 | ||
@@ -273,7 +277,7 @@ static int cypress_probe(struct usb_interface *intf, | |||
273 | } | 277 | } |
274 | 278 | ||
275 | static struct usb_driver cypress_driver = { | 279 | static struct usb_driver cypress_driver = { |
276 | .name = "ums-cypress", | 280 | .name = DRV_NAME, |
277 | .probe = cypress_probe, | 281 | .probe = cypress_probe, |
278 | .disconnect = usb_stor_disconnect, | 282 | .disconnect = usb_stor_disconnect, |
279 | .suspend = usb_stor_suspend, | 283 | .suspend = usb_stor_suspend, |
@@ -286,4 +290,4 @@ static struct usb_driver cypress_driver = { | |||
286 | .no_dynamic_id = 1, | 290 | .no_dynamic_id = 1, |
287 | }; | 291 | }; |
288 | 292 | ||
289 | module_usb_driver(cypress_driver); | 293 | module_usb_stor_driver(cypress_driver, cypress_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 7b17c2169812..aa4f51944a4a 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
@@ -59,6 +59,9 @@ | |||
59 | #include "transport.h" | 59 | #include "transport.h" |
60 | #include "protocol.h" | 60 | #include "protocol.h" |
61 | #include "debug.h" | 61 | #include "debug.h" |
62 | #include "scsiglue.h" | ||
63 | |||
64 | #define DRV_NAME "ums-datafab" | ||
62 | 65 | ||
63 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); | 66 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); |
64 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); | 67 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); |
@@ -721,6 +724,8 @@ static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
721 | return USB_STOR_TRANSPORT_FAILED; | 724 | return USB_STOR_TRANSPORT_FAILED; |
722 | } | 725 | } |
723 | 726 | ||
727 | static struct scsi_host_template datafab_host_template; | ||
728 | |||
724 | static int datafab_probe(struct usb_interface *intf, | 729 | static int datafab_probe(struct usb_interface *intf, |
725 | const struct usb_device_id *id) | 730 | const struct usb_device_id *id) |
726 | { | 731 | { |
@@ -728,7 +733,8 @@ static int datafab_probe(struct usb_interface *intf, | |||
728 | int result; | 733 | int result; |
729 | 734 | ||
730 | result = usb_stor_probe1(&us, intf, id, | 735 | result = usb_stor_probe1(&us, intf, id, |
731 | (id - datafab_usb_ids) + datafab_unusual_dev_list); | 736 | (id - datafab_usb_ids) + datafab_unusual_dev_list, |
737 | &datafab_host_template); | ||
732 | if (result) | 738 | if (result) |
733 | return result; | 739 | return result; |
734 | 740 | ||
@@ -742,7 +748,7 @@ static int datafab_probe(struct usb_interface *intf, | |||
742 | } | 748 | } |
743 | 749 | ||
744 | static struct usb_driver datafab_driver = { | 750 | static struct usb_driver datafab_driver = { |
745 | .name = "ums-datafab", | 751 | .name = DRV_NAME, |
746 | .probe = datafab_probe, | 752 | .probe = datafab_probe, |
747 | .disconnect = usb_stor_disconnect, | 753 | .disconnect = usb_stor_disconnect, |
748 | .suspend = usb_stor_suspend, | 754 | .suspend = usb_stor_suspend, |
@@ -755,4 +761,4 @@ static struct usb_driver datafab_driver = { | |||
755 | .no_dynamic_id = 1, | 761 | .no_dynamic_id = 1, |
756 | }; | 762 | }; |
757 | 763 | ||
758 | module_usb_driver(datafab_driver); | 764 | module_usb_stor_driver(datafab_driver, datafab_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 56f782bef36b..f3cf4cecd2b7 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "transport.h" | 28 | #include "transport.h" |
29 | #include "protocol.h" | 29 | #include "protocol.h" |
30 | #include "debug.h" | 30 | #include "debug.h" |
31 | #include "scsiglue.h" | ||
31 | 32 | ||
32 | #define SD_INIT1_FIRMWARE "ene-ub6250/sd_init1.bin" | 33 | #define SD_INIT1_FIRMWARE "ene-ub6250/sd_init1.bin" |
33 | #define SD_INIT2_FIRMWARE "ene-ub6250/sd_init2.bin" | 34 | #define SD_INIT2_FIRMWARE "ene-ub6250/sd_init2.bin" |
@@ -36,6 +37,8 @@ | |||
36 | #define MSP_RW_FIRMWARE "ene-ub6250/msp_rdwr.bin" | 37 | #define MSP_RW_FIRMWARE "ene-ub6250/msp_rdwr.bin" |
37 | #define MS_RW_FIRMWARE "ene-ub6250/ms_rdwr.bin" | 38 | #define MS_RW_FIRMWARE "ene-ub6250/ms_rdwr.bin" |
38 | 39 | ||
40 | #define DRV_NAME "ums_eneub6250" | ||
41 | |||
39 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); | 42 | MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); |
40 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
41 | MODULE_FIRMWARE(SD_INIT1_FIRMWARE); | 44 | MODULE_FIRMWARE(SD_INIT1_FIRMWARE); |
@@ -2307,6 +2310,7 @@ static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
2307 | return 0; | 2310 | return 0; |
2308 | } | 2311 | } |
2309 | 2312 | ||
2313 | static struct scsi_host_template ene_ub6250_host_template; | ||
2310 | 2314 | ||
2311 | static int ene_ub6250_probe(struct usb_interface *intf, | 2315 | static int ene_ub6250_probe(struct usb_interface *intf, |
2312 | const struct usb_device_id *id) | 2316 | const struct usb_device_id *id) |
@@ -2316,7 +2320,8 @@ static int ene_ub6250_probe(struct usb_interface *intf, | |||
2316 | struct us_data *us; | 2320 | struct us_data *us; |
2317 | 2321 | ||
2318 | result = usb_stor_probe1(&us, intf, id, | 2322 | result = usb_stor_probe1(&us, intf, id, |
2319 | (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list); | 2323 | (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list, |
2324 | &ene_ub6250_host_template); | ||
2320 | if (result) | 2325 | if (result) |
2321 | return result; | 2326 | return result; |
2322 | 2327 | ||
@@ -2404,7 +2409,7 @@ static int ene_ub6250_reset_resume(struct usb_interface *iface) | |||
2404 | #endif | 2409 | #endif |
2405 | 2410 | ||
2406 | static struct usb_driver ene_ub6250_driver = { | 2411 | static struct usb_driver ene_ub6250_driver = { |
2407 | .name = "ums_eneub6250", | 2412 | .name = DRV_NAME, |
2408 | .probe = ene_ub6250_probe, | 2413 | .probe = ene_ub6250_probe, |
2409 | .disconnect = usb_stor_disconnect, | 2414 | .disconnect = usb_stor_disconnect, |
2410 | .suspend = usb_stor_suspend, | 2415 | .suspend = usb_stor_suspend, |
@@ -2417,4 +2422,4 @@ static struct usb_driver ene_ub6250_driver = { | |||
2417 | .no_dynamic_id = 1, | 2422 | .no_dynamic_id = 1, |
2418 | }; | 2423 | }; |
2419 | 2424 | ||
2420 | module_usb_driver(ene_ub6250_driver); | 2425 | module_usb_stor_driver(ene_ub6250_driver, ene_ub6250_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index ef16068b7087..3f2b08966b9d 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include "transport.h" | 34 | #include "transport.h" |
35 | #include "protocol.h" | 35 | #include "protocol.h" |
36 | #include "debug.h" | 36 | #include "debug.h" |
37 | #include "scsiglue.h" | ||
38 | |||
39 | #define DRV_NAME "ums-freecom" | ||
37 | 40 | ||
38 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); | 41 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); |
39 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); | 42 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); |
@@ -523,6 +526,8 @@ static void pdump(struct us_data *us, void *ibuffer, int length) | |||
523 | } | 526 | } |
524 | #endif | 527 | #endif |
525 | 528 | ||
529 | static struct scsi_host_template freecom_host_template; | ||
530 | |||
526 | static int freecom_probe(struct usb_interface *intf, | 531 | static int freecom_probe(struct usb_interface *intf, |
527 | const struct usb_device_id *id) | 532 | const struct usb_device_id *id) |
528 | { | 533 | { |
@@ -530,7 +535,8 @@ static int freecom_probe(struct usb_interface *intf, | |||
530 | int result; | 535 | int result; |
531 | 536 | ||
532 | result = usb_stor_probe1(&us, intf, id, | 537 | result = usb_stor_probe1(&us, intf, id, |
533 | (id - freecom_usb_ids) + freecom_unusual_dev_list); | 538 | (id - freecom_usb_ids) + freecom_unusual_dev_list, |
539 | &freecom_host_template); | ||
534 | if (result) | 540 | if (result) |
535 | return result; | 541 | return result; |
536 | 542 | ||
@@ -544,7 +550,7 @@ static int freecom_probe(struct usb_interface *intf, | |||
544 | } | 550 | } |
545 | 551 | ||
546 | static struct usb_driver freecom_driver = { | 552 | static struct usb_driver freecom_driver = { |
547 | .name = "ums-freecom", | 553 | .name = DRV_NAME, |
548 | .probe = freecom_probe, | 554 | .probe = freecom_probe, |
549 | .disconnect = usb_stor_disconnect, | 555 | .disconnect = usb_stor_disconnect, |
550 | .suspend = usb_stor_suspend, | 556 | .suspend = usb_stor_suspend, |
@@ -557,4 +563,4 @@ static struct usb_driver freecom_driver = { | |||
557 | .no_dynamic_id = 1, | 563 | .no_dynamic_id = 1, |
558 | }; | 564 | }; |
559 | 565 | ||
560 | module_usb_driver(freecom_driver); | 566 | module_usb_stor_driver(freecom_driver, freecom_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 076178645ba4..1bac215202d2 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #include "debug.h" | 60 | #include "debug.h" |
61 | #include "scsiglue.h" | 61 | #include "scsiglue.h" |
62 | 62 | ||
63 | #define DRV_NAME "ums-isd200" | ||
64 | |||
63 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); | 65 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); |
64 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); | 66 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); |
65 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
@@ -1537,6 +1539,8 @@ static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) | |||
1537 | isd200_srb_set_bufflen(srb, orig_bufflen); | 1539 | isd200_srb_set_bufflen(srb, orig_bufflen); |
1538 | } | 1540 | } |
1539 | 1541 | ||
1542 | static struct scsi_host_template isd200_host_template; | ||
1543 | |||
1540 | static int isd200_probe(struct usb_interface *intf, | 1544 | static int isd200_probe(struct usb_interface *intf, |
1541 | const struct usb_device_id *id) | 1545 | const struct usb_device_id *id) |
1542 | { | 1546 | { |
@@ -1544,7 +1548,8 @@ static int isd200_probe(struct usb_interface *intf, | |||
1544 | int result; | 1548 | int result; |
1545 | 1549 | ||
1546 | result = usb_stor_probe1(&us, intf, id, | 1550 | result = usb_stor_probe1(&us, intf, id, |
1547 | (id - isd200_usb_ids) + isd200_unusual_dev_list); | 1551 | (id - isd200_usb_ids) + isd200_unusual_dev_list, |
1552 | &isd200_host_template); | ||
1548 | if (result) | 1553 | if (result) |
1549 | return result; | 1554 | return result; |
1550 | 1555 | ||
@@ -1556,7 +1561,7 @@ static int isd200_probe(struct usb_interface *intf, | |||
1556 | } | 1561 | } |
1557 | 1562 | ||
1558 | static struct usb_driver isd200_driver = { | 1563 | static struct usb_driver isd200_driver = { |
1559 | .name = "ums-isd200", | 1564 | .name = DRV_NAME, |
1560 | .probe = isd200_probe, | 1565 | .probe = isd200_probe, |
1561 | .disconnect = usb_stor_disconnect, | 1566 | .disconnect = usb_stor_disconnect, |
1562 | .suspend = usb_stor_suspend, | 1567 | .suspend = usb_stor_suspend, |
@@ -1569,4 +1574,4 @@ static struct usb_driver isd200_driver = { | |||
1569 | .no_dynamic_id = 1, | 1574 | .no_dynamic_id = 1, |
1570 | }; | 1575 | }; |
1571 | 1576 | ||
1572 | module_usb_driver(isd200_driver); | 1577 | module_usb_stor_driver(isd200_driver, isd200_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 563078be6547..ee613e258db0 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c | |||
@@ -56,7 +56,9 @@ | |||
56 | #include "transport.h" | 56 | #include "transport.h" |
57 | #include "protocol.h" | 57 | #include "protocol.h" |
58 | #include "debug.h" | 58 | #include "debug.h" |
59 | #include "scsiglue.h" | ||
59 | 60 | ||
61 | #define DRV_NAME "ums-jumpshot" | ||
60 | 62 | ||
61 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); | 63 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); |
62 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); | 64 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); |
@@ -647,6 +649,8 @@ static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
647 | return USB_STOR_TRANSPORT_FAILED; | 649 | return USB_STOR_TRANSPORT_FAILED; |
648 | } | 650 | } |
649 | 651 | ||
652 | static struct scsi_host_template jumpshot_host_template; | ||
653 | |||
650 | static int jumpshot_probe(struct usb_interface *intf, | 654 | static int jumpshot_probe(struct usb_interface *intf, |
651 | const struct usb_device_id *id) | 655 | const struct usb_device_id *id) |
652 | { | 656 | { |
@@ -654,7 +658,8 @@ static int jumpshot_probe(struct usb_interface *intf, | |||
654 | int result; | 658 | int result; |
655 | 659 | ||
656 | result = usb_stor_probe1(&us, intf, id, | 660 | result = usb_stor_probe1(&us, intf, id, |
657 | (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list); | 661 | (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list, |
662 | &jumpshot_host_template); | ||
658 | if (result) | 663 | if (result) |
659 | return result; | 664 | return result; |
660 | 665 | ||
@@ -668,7 +673,7 @@ static int jumpshot_probe(struct usb_interface *intf, | |||
668 | } | 673 | } |
669 | 674 | ||
670 | static struct usb_driver jumpshot_driver = { | 675 | static struct usb_driver jumpshot_driver = { |
671 | .name = "ums-jumpshot", | 676 | .name = DRV_NAME, |
672 | .probe = jumpshot_probe, | 677 | .probe = jumpshot_probe, |
673 | .disconnect = usb_stor_disconnect, | 678 | .disconnect = usb_stor_disconnect, |
674 | .suspend = usb_stor_suspend, | 679 | .suspend = usb_stor_suspend, |
@@ -681,4 +686,4 @@ static struct usb_driver jumpshot_driver = { | |||
681 | .no_dynamic_id = 1, | 686 | .no_dynamic_id = 1, |
682 | }; | 687 | }; |
683 | 688 | ||
684 | module_usb_driver(jumpshot_driver); | 689 | module_usb_stor_driver(jumpshot_driver, jumpshot_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 94d16ee5e84b..ae201e69475c 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include "usb.h" | 28 | #include "usb.h" |
29 | #include "transport.h" | 29 | #include "transport.h" |
30 | #include "debug.h" | 30 | #include "debug.h" |
31 | #include "scsiglue.h" | ||
32 | |||
33 | #define DRV_NAME "ums-karma" | ||
31 | 34 | ||
32 | MODULE_DESCRIPTION("Driver for Rio Karma"); | 35 | MODULE_DESCRIPTION("Driver for Rio Karma"); |
33 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); | 36 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); |
@@ -200,6 +203,8 @@ out: | |||
200 | return ret; | 203 | return ret; |
201 | } | 204 | } |
202 | 205 | ||
206 | static struct scsi_host_template karma_host_template; | ||
207 | |||
203 | static int karma_probe(struct usb_interface *intf, | 208 | static int karma_probe(struct usb_interface *intf, |
204 | const struct usb_device_id *id) | 209 | const struct usb_device_id *id) |
205 | { | 210 | { |
@@ -207,7 +212,8 @@ static int karma_probe(struct usb_interface *intf, | |||
207 | int result; | 212 | int result; |
208 | 213 | ||
209 | result = usb_stor_probe1(&us, intf, id, | 214 | result = usb_stor_probe1(&us, intf, id, |
210 | (id - karma_usb_ids) + karma_unusual_dev_list); | 215 | (id - karma_usb_ids) + karma_unusual_dev_list, |
216 | &karma_host_template); | ||
211 | if (result) | 217 | if (result) |
212 | return result; | 218 | return result; |
213 | 219 | ||
@@ -220,7 +226,7 @@ static int karma_probe(struct usb_interface *intf, | |||
220 | } | 226 | } |
221 | 227 | ||
222 | static struct usb_driver karma_driver = { | 228 | static struct usb_driver karma_driver = { |
223 | .name = "ums-karma", | 229 | .name = DRV_NAME, |
224 | .probe = karma_probe, | 230 | .probe = karma_probe, |
225 | .disconnect = usb_stor_disconnect, | 231 | .disconnect = usb_stor_disconnect, |
226 | .suspend = usb_stor_suspend, | 232 | .suspend = usb_stor_suspend, |
@@ -233,4 +239,4 @@ static struct usb_driver karma_driver = { | |||
233 | .no_dynamic_id = 1, | 239 | .no_dynamic_id = 1, |
234 | }; | 240 | }; |
235 | 241 | ||
236 | module_usb_driver(karma_driver); | 242 | module_usb_stor_driver(karma_driver, karma_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 74e2aa23b045..acc3d03d8c1e 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -35,6 +35,9 @@ | |||
35 | #include <linux/usb/input.h> | 35 | #include <linux/usb/input.h> |
36 | #include "usb.h" | 36 | #include "usb.h" |
37 | #include "debug.h" | 37 | #include "debug.h" |
38 | #include "scsiglue.h" | ||
39 | |||
40 | #define DRV_NAME "ums-onetouch" | ||
38 | 41 | ||
39 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); | 42 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); |
40 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); | 43 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); |
@@ -283,6 +286,8 @@ static void onetouch_release_input(void *onetouch_) | |||
283 | } | 286 | } |
284 | } | 287 | } |
285 | 288 | ||
289 | static struct scsi_host_template onetouch_host_template; | ||
290 | |||
286 | static int onetouch_probe(struct usb_interface *intf, | 291 | static int onetouch_probe(struct usb_interface *intf, |
287 | const struct usb_device_id *id) | 292 | const struct usb_device_id *id) |
288 | { | 293 | { |
@@ -290,7 +295,8 @@ static int onetouch_probe(struct usb_interface *intf, | |||
290 | int result; | 295 | int result; |
291 | 296 | ||
292 | result = usb_stor_probe1(&us, intf, id, | 297 | result = usb_stor_probe1(&us, intf, id, |
293 | (id - onetouch_usb_ids) + onetouch_unusual_dev_list); | 298 | (id - onetouch_usb_ids) + onetouch_unusual_dev_list, |
299 | &onetouch_host_template); | ||
294 | if (result) | 300 | if (result) |
295 | return result; | 301 | return result; |
296 | 302 | ||
@@ -301,7 +307,7 @@ static int onetouch_probe(struct usb_interface *intf, | |||
301 | } | 307 | } |
302 | 308 | ||
303 | static struct usb_driver onetouch_driver = { | 309 | static struct usb_driver onetouch_driver = { |
304 | .name = "ums-onetouch", | 310 | .name = DRV_NAME, |
305 | .probe = onetouch_probe, | 311 | .probe = onetouch_probe, |
306 | .disconnect = usb_stor_disconnect, | 312 | .disconnect = usb_stor_disconnect, |
307 | .suspend = usb_stor_suspend, | 313 | .suspend = usb_stor_suspend, |
@@ -314,4 +320,4 @@ static struct usb_driver onetouch_driver = { | |||
314 | .no_dynamic_id = 1, | 320 | .no_dynamic_id = 1, |
315 | }; | 321 | }; |
316 | 322 | ||
317 | module_usb_driver(onetouch_driver); | 323 | module_usb_stor_driver(onetouch_driver, onetouch_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 27e4a580d2ed..20433563a601 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #include "transport.h" | 39 | #include "transport.h" |
40 | #include "protocol.h" | 40 | #include "protocol.h" |
41 | #include "debug.h" | 41 | #include "debug.h" |
42 | #include "scsiglue.h" | ||
43 | |||
44 | #define DRV_NAME "ums-realtek" | ||
42 | 45 | ||
43 | MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); | 46 | MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); |
44 | MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>"); | 47 | MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>"); |
@@ -1034,6 +1037,8 @@ INIT_FAIL: | |||
1034 | return -EIO; | 1037 | return -EIO; |
1035 | } | 1038 | } |
1036 | 1039 | ||
1040 | static struct scsi_host_template realtek_cr_host_template; | ||
1041 | |||
1037 | static int realtek_cr_probe(struct usb_interface *intf, | 1042 | static int realtek_cr_probe(struct usb_interface *intf, |
1038 | const struct usb_device_id *id) | 1043 | const struct usb_device_id *id) |
1039 | { | 1044 | { |
@@ -1044,7 +1049,8 @@ static int realtek_cr_probe(struct usb_interface *intf, | |||
1044 | 1049 | ||
1045 | result = usb_stor_probe1(&us, intf, id, | 1050 | result = usb_stor_probe1(&us, intf, id, |
1046 | (id - realtek_cr_ids) + | 1051 | (id - realtek_cr_ids) + |
1047 | realtek_cr_unusual_dev_list); | 1052 | realtek_cr_unusual_dev_list, |
1053 | &realtek_cr_host_template); | ||
1048 | if (result) | 1054 | if (result) |
1049 | return result; | 1055 | return result; |
1050 | 1056 | ||
@@ -1054,7 +1060,7 @@ static int realtek_cr_probe(struct usb_interface *intf, | |||
1054 | } | 1060 | } |
1055 | 1061 | ||
1056 | static struct usb_driver realtek_cr_driver = { | 1062 | static struct usb_driver realtek_cr_driver = { |
1057 | .name = "ums-realtek", | 1063 | .name = DRV_NAME, |
1058 | .probe = realtek_cr_probe, | 1064 | .probe = realtek_cr_probe, |
1059 | .disconnect = usb_stor_disconnect, | 1065 | .disconnect = usb_stor_disconnect, |
1060 | /* .suspend = usb_stor_suspend, */ | 1066 | /* .suspend = usb_stor_suspend, */ |
@@ -1070,4 +1076,4 @@ static struct usb_driver realtek_cr_driver = { | |||
1070 | .no_dynamic_id = 1, | 1076 | .no_dynamic_id = 1, |
1071 | }; | 1077 | }; |
1072 | 1078 | ||
1073 | module_usb_driver(realtek_cr_driver); | 1079 | module_usb_stor_driver(realtek_cr_driver, realtek_cr_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 996ef1e882d3..dba51362d2e2 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -456,17 +456,13 @@ static int write_info(struct Scsi_Host *host, char *buffer, int length) | |||
456 | return length; | 456 | return length; |
457 | } | 457 | } |
458 | 458 | ||
459 | /* we use this macro to help us write into the buffer */ | ||
460 | #undef SPRINTF | ||
461 | #define SPRINTF(args...) seq_printf(m, ## args) | ||
462 | |||
463 | static int show_info (struct seq_file *m, struct Scsi_Host *host) | 459 | static int show_info (struct seq_file *m, struct Scsi_Host *host) |
464 | { | 460 | { |
465 | struct us_data *us = host_to_us(host); | 461 | struct us_data *us = host_to_us(host); |
466 | const char *string; | 462 | const char *string; |
467 | 463 | ||
468 | /* print the controller name */ | 464 | /* print the controller name */ |
469 | SPRINTF(" Host scsi%d: usb-storage\n", host->host_no); | 465 | seq_printf(m, " Host scsi%d: usb-storage\n", host->host_no); |
470 | 466 | ||
471 | /* print product, vendor, and serial number strings */ | 467 | /* print product, vendor, and serial number strings */ |
472 | if (us->pusb_dev->manufacturer) | 468 | if (us->pusb_dev->manufacturer) |
@@ -475,26 +471,26 @@ static int show_info (struct seq_file *m, struct Scsi_Host *host) | |||
475 | string = us->unusual_dev->vendorName; | 471 | string = us->unusual_dev->vendorName; |
476 | else | 472 | else |
477 | string = "Unknown"; | 473 | string = "Unknown"; |
478 | SPRINTF(" Vendor: %s\n", string); | 474 | seq_printf(m, " Vendor: %s\n", string); |
479 | if (us->pusb_dev->product) | 475 | if (us->pusb_dev->product) |
480 | string = us->pusb_dev->product; | 476 | string = us->pusb_dev->product; |
481 | else if (us->unusual_dev->productName) | 477 | else if (us->unusual_dev->productName) |
482 | string = us->unusual_dev->productName; | 478 | string = us->unusual_dev->productName; |
483 | else | 479 | else |
484 | string = "Unknown"; | 480 | string = "Unknown"; |
485 | SPRINTF(" Product: %s\n", string); | 481 | seq_printf(m, " Product: %s\n", string); |
486 | if (us->pusb_dev->serial) | 482 | if (us->pusb_dev->serial) |
487 | string = us->pusb_dev->serial; | 483 | string = us->pusb_dev->serial; |
488 | else | 484 | else |
489 | string = "None"; | 485 | string = "None"; |
490 | SPRINTF("Serial Number: %s\n", string); | 486 | seq_printf(m, "Serial Number: %s\n", string); |
491 | 487 | ||
492 | /* show the protocol and transport */ | 488 | /* show the protocol and transport */ |
493 | SPRINTF(" Protocol: %s\n", us->protocol_name); | 489 | seq_printf(m, " Protocol: %s\n", us->protocol_name); |
494 | SPRINTF(" Transport: %s\n", us->transport_name); | 490 | seq_printf(m, " Transport: %s\n", us->transport_name); |
495 | 491 | ||
496 | /* show the device flags */ | 492 | /* show the device flags */ |
497 | SPRINTF(" Quirks:"); | 493 | seq_printf(m, " Quirks:"); |
498 | 494 | ||
499 | #define US_FLAG(name, value) \ | 495 | #define US_FLAG(name, value) \ |
500 | if (us->fflags & value) seq_printf(m, " " #name); | 496 | if (us->fflags & value) seq_printf(m, " " #name); |
@@ -540,7 +536,7 @@ static struct device_attribute *sysfs_device_attr_list[] = { | |||
540 | * this defines our host template, with which we'll allocate hosts | 536 | * this defines our host template, with which we'll allocate hosts |
541 | */ | 537 | */ |
542 | 538 | ||
543 | struct scsi_host_template usb_stor_host_template = { | 539 | static const struct scsi_host_template usb_stor_host_template = { |
544 | /* basic userland interface stuff */ | 540 | /* basic userland interface stuff */ |
545 | .name = "usb-storage", | 541 | .name = "usb-storage", |
546 | .proc_name = "usb-storage", | 542 | .proc_name = "usb-storage", |
@@ -591,6 +587,16 @@ struct scsi_host_template usb_stor_host_template = { | |||
591 | .module = THIS_MODULE | 587 | .module = THIS_MODULE |
592 | }; | 588 | }; |
593 | 589 | ||
590 | void usb_stor_host_template_init(struct scsi_host_template *sht, | ||
591 | const char *name, struct module *owner) | ||
592 | { | ||
593 | *sht = usb_stor_host_template; | ||
594 | sht->name = name; | ||
595 | sht->proc_name = name; | ||
596 | sht->module = owner; | ||
597 | } | ||
598 | EXPORT_SYMBOL_GPL(usb_stor_host_template_init); | ||
599 | |||
594 | /* To Report "Illegal Request: Invalid Field in CDB */ | 600 | /* To Report "Illegal Request: Invalid Field in CDB */ |
595 | unsigned char usb_stor_sense_invalidCDB[18] = { | 601 | unsigned char usb_stor_sense_invalidCDB[18] = { |
596 | [0] = 0x70, /* current error */ | 602 | [0] = 0x70, /* current error */ |
diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h index ffa1cca93d2c..5494d87607fb 100644 --- a/drivers/usb/storage/scsiglue.h +++ b/drivers/usb/storage/scsiglue.h | |||
@@ -41,8 +41,9 @@ | |||
41 | 41 | ||
42 | extern void usb_stor_report_device_reset(struct us_data *us); | 42 | extern void usb_stor_report_device_reset(struct us_data *us); |
43 | extern void usb_stor_report_bus_reset(struct us_data *us); | 43 | extern void usb_stor_report_bus_reset(struct us_data *us); |
44 | extern void usb_stor_host_template_init(struct scsi_host_template *sht, | ||
45 | const char *name, struct module *owner); | ||
44 | 46 | ||
45 | extern unsigned char usb_stor_sense_invalidCDB[18]; | 47 | extern unsigned char usb_stor_sense_invalidCDB[18]; |
46 | extern struct scsi_host_template usb_stor_host_template; | ||
47 | 48 | ||
48 | #endif | 49 | #endif |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 3847053d732c..b74603689b9e 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -52,6 +52,9 @@ | |||
52 | #include "transport.h" | 52 | #include "transport.h" |
53 | #include "protocol.h" | 53 | #include "protocol.h" |
54 | #include "debug.h" | 54 | #include "debug.h" |
55 | #include "scsiglue.h" | ||
56 | |||
57 | #define DRV_NAME "ums-sddr09" | ||
55 | 58 | ||
56 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); | 59 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); |
57 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); | 60 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); |
@@ -1738,6 +1741,8 @@ usb_stor_sddr09_init(struct us_data *us) { | |||
1738 | return sddr09_common_init(us); | 1741 | return sddr09_common_init(us); |
1739 | } | 1742 | } |
1740 | 1743 | ||
1744 | static struct scsi_host_template sddr09_host_template; | ||
1745 | |||
1741 | static int sddr09_probe(struct usb_interface *intf, | 1746 | static int sddr09_probe(struct usb_interface *intf, |
1742 | const struct usb_device_id *id) | 1747 | const struct usb_device_id *id) |
1743 | { | 1748 | { |
@@ -1745,7 +1750,8 @@ static int sddr09_probe(struct usb_interface *intf, | |||
1745 | int result; | 1750 | int result; |
1746 | 1751 | ||
1747 | result = usb_stor_probe1(&us, intf, id, | 1752 | result = usb_stor_probe1(&us, intf, id, |
1748 | (id - sddr09_usb_ids) + sddr09_unusual_dev_list); | 1753 | (id - sddr09_usb_ids) + sddr09_unusual_dev_list, |
1754 | &sddr09_host_template); | ||
1749 | if (result) | 1755 | if (result) |
1750 | return result; | 1756 | return result; |
1751 | 1757 | ||
@@ -1766,7 +1772,7 @@ static int sddr09_probe(struct usb_interface *intf, | |||
1766 | } | 1772 | } |
1767 | 1773 | ||
1768 | static struct usb_driver sddr09_driver = { | 1774 | static struct usb_driver sddr09_driver = { |
1769 | .name = "ums-sddr09", | 1775 | .name = DRV_NAME, |
1770 | .probe = sddr09_probe, | 1776 | .probe = sddr09_probe, |
1771 | .disconnect = usb_stor_disconnect, | 1777 | .disconnect = usb_stor_disconnect, |
1772 | .suspend = usb_stor_suspend, | 1778 | .suspend = usb_stor_suspend, |
@@ -1779,4 +1785,4 @@ static struct usb_driver sddr09_driver = { | |||
1779 | .no_dynamic_id = 1, | 1785 | .no_dynamic_id = 1, |
1780 | }; | 1786 | }; |
1781 | 1787 | ||
1782 | module_usb_driver(sddr09_driver); | 1788 | module_usb_stor_driver(sddr09_driver, sddr09_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index aacedef9667c..e5e0a25ecd96 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include "transport.h" | 34 | #include "transport.h" |
35 | #include "protocol.h" | 35 | #include "protocol.h" |
36 | #include "debug.h" | 36 | #include "debug.h" |
37 | #include "scsiglue.h" | ||
38 | |||
39 | #define DRV_NAME "ums-sddr55" | ||
37 | 40 | ||
38 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); | 41 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); |
39 | MODULE_AUTHOR("Simon Munton"); | 42 | MODULE_AUTHOR("Simon Munton"); |
@@ -968,6 +971,7 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
968 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? | 971 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? |
969 | } | 972 | } |
970 | 973 | ||
974 | static struct scsi_host_template sddr55_host_template; | ||
971 | 975 | ||
972 | static int sddr55_probe(struct usb_interface *intf, | 976 | static int sddr55_probe(struct usb_interface *intf, |
973 | const struct usb_device_id *id) | 977 | const struct usb_device_id *id) |
@@ -976,7 +980,8 @@ static int sddr55_probe(struct usb_interface *intf, | |||
976 | int result; | 980 | int result; |
977 | 981 | ||
978 | result = usb_stor_probe1(&us, intf, id, | 982 | result = usb_stor_probe1(&us, intf, id, |
979 | (id - sddr55_usb_ids) + sddr55_unusual_dev_list); | 983 | (id - sddr55_usb_ids) + sddr55_unusual_dev_list, |
984 | &sddr55_host_template); | ||
980 | if (result) | 985 | if (result) |
981 | return result; | 986 | return result; |
982 | 987 | ||
@@ -990,7 +995,7 @@ static int sddr55_probe(struct usb_interface *intf, | |||
990 | } | 995 | } |
991 | 996 | ||
992 | static struct usb_driver sddr55_driver = { | 997 | static struct usb_driver sddr55_driver = { |
993 | .name = "ums-sddr55", | 998 | .name = DRV_NAME, |
994 | .probe = sddr55_probe, | 999 | .probe = sddr55_probe, |
995 | .disconnect = usb_stor_disconnect, | 1000 | .disconnect = usb_stor_disconnect, |
996 | .suspend = usb_stor_suspend, | 1001 | .suspend = usb_stor_suspend, |
@@ -1003,4 +1008,4 @@ static struct usb_driver sddr55_driver = { | |||
1003 | .no_dynamic_id = 1, | 1008 | .no_dynamic_id = 1, |
1004 | }; | 1009 | }; |
1005 | 1010 | ||
1006 | module_usb_driver(sddr55_driver); | 1011 | module_usb_stor_driver(sddr55_driver, sddr55_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 008d805c3d21..a3ec86b913a1 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -53,6 +53,9 @@ | |||
53 | #include "transport.h" | 53 | #include "transport.h" |
54 | #include "protocol.h" | 54 | #include "protocol.h" |
55 | #include "debug.h" | 55 | #include "debug.h" |
56 | #include "scsiglue.h" | ||
57 | |||
58 | #define DRV_NAME "ums-usbat" | ||
56 | 59 | ||
57 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); | 60 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); |
58 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); | 61 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); |
@@ -1834,6 +1837,8 @@ static int init_usbat_flash(struct us_data *us) | |||
1834 | return init_usbat(us, USBAT_DEV_FLASH); | 1837 | return init_usbat(us, USBAT_DEV_FLASH); |
1835 | } | 1838 | } |
1836 | 1839 | ||
1840 | static struct scsi_host_template usbat_host_template; | ||
1841 | |||
1837 | static int usbat_probe(struct usb_interface *intf, | 1842 | static int usbat_probe(struct usb_interface *intf, |
1838 | const struct usb_device_id *id) | 1843 | const struct usb_device_id *id) |
1839 | { | 1844 | { |
@@ -1841,7 +1846,8 @@ static int usbat_probe(struct usb_interface *intf, | |||
1841 | int result; | 1846 | int result; |
1842 | 1847 | ||
1843 | result = usb_stor_probe1(&us, intf, id, | 1848 | result = usb_stor_probe1(&us, intf, id, |
1844 | (id - usbat_usb_ids) + usbat_unusual_dev_list); | 1849 | (id - usbat_usb_ids) + usbat_unusual_dev_list, |
1850 | &usbat_host_template); | ||
1845 | if (result) | 1851 | if (result) |
1846 | return result; | 1852 | return result; |
1847 | 1853 | ||
@@ -1858,7 +1864,7 @@ static int usbat_probe(struct usb_interface *intf, | |||
1858 | } | 1864 | } |
1859 | 1865 | ||
1860 | static struct usb_driver usbat_driver = { | 1866 | static struct usb_driver usbat_driver = { |
1861 | .name = "ums-usbat", | 1867 | .name = DRV_NAME, |
1862 | .probe = usbat_probe, | 1868 | .probe = usbat_probe, |
1863 | .disconnect = usb_stor_disconnect, | 1869 | .disconnect = usb_stor_disconnect, |
1864 | .suspend = usb_stor_suspend, | 1870 | .suspend = usb_stor_suspend, |
@@ -1871,4 +1877,4 @@ static struct usb_driver usbat_driver = { | |||
1871 | .no_dynamic_id = 1, | 1877 | .no_dynamic_id = 1, |
1872 | }; | 1878 | }; |
1873 | 1879 | ||
1874 | module_usb_driver(usbat_driver); | 1880 | module_usb_stor_driver(usbat_driver, usbat_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 6c10c888f35f..43576ed31ccd 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -76,6 +76,8 @@ | |||
76 | #include "uas-detect.h" | 76 | #include "uas-detect.h" |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #define DRV_NAME "usb-storage" | ||
80 | |||
79 | /* Some informational data */ | 81 | /* Some informational data */ |
80 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 82 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
81 | MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); | 83 | MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); |
@@ -924,7 +926,8 @@ static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) | |||
924 | int usb_stor_probe1(struct us_data **pus, | 926 | int usb_stor_probe1(struct us_data **pus, |
925 | struct usb_interface *intf, | 927 | struct usb_interface *intf, |
926 | const struct usb_device_id *id, | 928 | const struct usb_device_id *id, |
927 | struct us_unusual_dev *unusual_dev) | 929 | struct us_unusual_dev *unusual_dev, |
930 | struct scsi_host_template *sht) | ||
928 | { | 931 | { |
929 | struct Scsi_Host *host; | 932 | struct Scsi_Host *host; |
930 | struct us_data *us; | 933 | struct us_data *us; |
@@ -936,7 +939,7 @@ int usb_stor_probe1(struct us_data **pus, | |||
936 | * Ask the SCSI layer to allocate a host structure, with extra | 939 | * Ask the SCSI layer to allocate a host structure, with extra |
937 | * space at the end for our private us_data structure. | 940 | * space at the end for our private us_data structure. |
938 | */ | 941 | */ |
939 | host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us)); | 942 | host = scsi_host_alloc(sht, sizeof(*us)); |
940 | if (!host) { | 943 | if (!host) { |
941 | dev_warn(&intf->dev, "Unable to allocate the scsi host\n"); | 944 | dev_warn(&intf->dev, "Unable to allocate the scsi host\n"); |
942 | return -ENOMEM; | 945 | return -ENOMEM; |
@@ -1073,6 +1076,8 @@ void usb_stor_disconnect(struct usb_interface *intf) | |||
1073 | } | 1076 | } |
1074 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); | 1077 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); |
1075 | 1078 | ||
1079 | static struct scsi_host_template usb_stor_host_template; | ||
1080 | |||
1076 | /* The main probe routine for standard devices */ | 1081 | /* The main probe routine for standard devices */ |
1077 | static int storage_probe(struct usb_interface *intf, | 1082 | static int storage_probe(struct usb_interface *intf, |
1078 | const struct usb_device_id *id) | 1083 | const struct usb_device_id *id) |
@@ -1113,7 +1118,8 @@ static int storage_probe(struct usb_interface *intf, | |||
1113 | id->idVendor, id->idProduct); | 1118 | id->idVendor, id->idProduct); |
1114 | } | 1119 | } |
1115 | 1120 | ||
1116 | result = usb_stor_probe1(&us, intf, id, unusual_dev); | 1121 | result = usb_stor_probe1(&us, intf, id, unusual_dev, |
1122 | &usb_stor_host_template); | ||
1117 | if (result) | 1123 | if (result) |
1118 | return result; | 1124 | return result; |
1119 | 1125 | ||
@@ -1124,7 +1130,7 @@ static int storage_probe(struct usb_interface *intf, | |||
1124 | } | 1130 | } |
1125 | 1131 | ||
1126 | static struct usb_driver usb_storage_driver = { | 1132 | static struct usb_driver usb_storage_driver = { |
1127 | .name = "usb-storage", | 1133 | .name = DRV_NAME, |
1128 | .probe = storage_probe, | 1134 | .probe = storage_probe, |
1129 | .disconnect = usb_stor_disconnect, | 1135 | .disconnect = usb_stor_disconnect, |
1130 | .suspend = usb_stor_suspend, | 1136 | .suspend = usb_stor_suspend, |
@@ -1137,4 +1143,4 @@ static struct usb_driver usb_storage_driver = { | |||
1137 | .soft_unbind = 1, | 1143 | .soft_unbind = 1, |
1138 | }; | 1144 | }; |
1139 | 1145 | ||
1140 | module_usb_driver(usb_storage_driver); | 1146 | module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 307e339a9478..da0ad3241728 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -197,11 +197,25 @@ extern int usb_stor_post_reset(struct usb_interface *iface); | |||
197 | extern int usb_stor_probe1(struct us_data **pus, | 197 | extern int usb_stor_probe1(struct us_data **pus, |
198 | struct usb_interface *intf, | 198 | struct usb_interface *intf, |
199 | const struct usb_device_id *id, | 199 | const struct usb_device_id *id, |
200 | struct us_unusual_dev *unusual_dev); | 200 | struct us_unusual_dev *unusual_dev, |
201 | struct scsi_host_template *sht); | ||
201 | extern int usb_stor_probe2(struct us_data *us); | 202 | extern int usb_stor_probe2(struct us_data *us); |
202 | extern void usb_stor_disconnect(struct usb_interface *intf); | 203 | extern void usb_stor_disconnect(struct usb_interface *intf); |
203 | 204 | ||
204 | extern void usb_stor_adjust_quirks(struct usb_device *dev, | 205 | extern void usb_stor_adjust_quirks(struct usb_device *dev, |
205 | unsigned long *fflags); | 206 | unsigned long *fflags); |
206 | 207 | ||
208 | #define module_usb_stor_driver(__driver, __sht, __name) \ | ||
209 | static int __init __driver##_init(void) \ | ||
210 | { \ | ||
211 | usb_stor_host_template_init(&(__sht), __name, THIS_MODULE); \ | ||
212 | return usb_register(&(__driver)); \ | ||
213 | } \ | ||
214 | module_init(__driver##_init); \ | ||
215 | static void __exit __driver##_exit(void) \ | ||
216 | { \ | ||
217 | usb_deregister(&(__driver)); \ | ||
218 | } \ | ||
219 | module_exit(__driver##_exit) | ||
220 | |||
207 | #endif | 221 | #endif |
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index a82296af413f..2a2f56b292c1 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define FSL_USB_VER_1_6 1 | 24 | #define FSL_USB_VER_1_6 1 |
25 | #define FSL_USB_VER_2_2 2 | 25 | #define FSL_USB_VER_2_2 2 |
26 | #define FSL_USB_VER_2_4 3 | 26 | #define FSL_USB_VER_2_4 3 |
27 | #define FSL_USB_VER_2_5 4 | ||
27 | 28 | ||
28 | #include <linux/types.h> | 29 | #include <linux/types.h> |
29 | 30 | ||
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 048c270822f9..8183d6640ca7 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -642,4 +642,10 @@ struct mcb_device_id { | |||
642 | kernel_ulong_t driver_data; | 642 | kernel_ulong_t driver_data; |
643 | }; | 643 | }; |
644 | 644 | ||
645 | struct ulpi_device_id { | ||
646 | __u16 vendor; | ||
647 | __u16 product; | ||
648 | kernel_ulong_t driver_data; | ||
649 | }; | ||
650 | |||
645 | #endif /* LINUX_MOD_DEVICETABLE_H */ | 651 | #endif /* LINUX_MOD_DEVICETABLE_H */ |
diff --git a/include/linux/phy/phy-sun4i-usb.h b/include/linux/phy/phy-sun4i-usb.h new file mode 100644 index 000000000000..50aed92ea89c --- /dev/null +++ b/include/linux/phy/phy-sun4i-usb.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Hans de Goede <hdegoede@redhat.com> | ||
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 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef PHY_SUN4I_USB_H_ | ||
15 | #define PHY_SUN4I_USB_H_ | ||
16 | |||
17 | #include "phy.h" | ||
18 | |||
19 | /** | ||
20 | * sun4i_usb_phy_set_squelch_detect() - Enable/disable squelch detect | ||
21 | * @phy: reference to a sun4i usb phy | ||
22 | * @enabled: wether to enable or disable squelch detect | ||
23 | */ | ||
24 | void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled); | ||
25 | |||
26 | #endif | ||
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index a0197fa1b116..8cf05e341cff 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h | |||
@@ -133,6 +133,8 @@ struct phy *devm_phy_get(struct device *dev, const char *string); | |||
133 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); | 133 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); |
134 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, | 134 | struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, |
135 | const char *con_id); | 135 | const char *con_id); |
136 | struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, | ||
137 | int index); | ||
136 | void phy_put(struct phy *phy); | 138 | void phy_put(struct phy *phy); |
137 | void devm_phy_put(struct device *dev, struct phy *phy); | 139 | void devm_phy_put(struct device *dev, struct phy *phy); |
138 | struct phy *of_phy_get(struct device_node *np, const char *con_id); | 140 | struct phy *of_phy_get(struct device_node *np, const char *con_id); |
@@ -261,6 +263,13 @@ static inline struct phy *devm_of_phy_get(struct device *dev, | |||
261 | return ERR_PTR(-ENOSYS); | 263 | return ERR_PTR(-ENOSYS); |
262 | } | 264 | } |
263 | 265 | ||
266 | static inline struct phy *devm_of_phy_get_by_index(struct device *dev, | ||
267 | struct device_node *np, | ||
268 | int index) | ||
269 | { | ||
270 | return ERR_PTR(-ENOSYS); | ||
271 | } | ||
272 | |||
264 | static inline void phy_put(struct phy *phy) | 273 | static inline void phy_put(struct phy *phy) |
265 | { | 274 | { |
266 | } | 275 | } |
diff --git a/include/linux/platform_data/usb-rcar-gen2-phy.h b/include/linux/platform_data/usb-rcar-gen2-phy.h deleted file mode 100644 index dd3ba46c0d90..000000000000 --- a/include/linux/platform_data/usb-rcar-gen2-phy.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Renesas Solutions Corp. | ||
3 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #ifndef __USB_RCAR_GEN2_PHY_H | ||
11 | #define __USB_RCAR_GEN2_PHY_H | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | |||
15 | struct rcar_gen2_phy_platform_data { | ||
16 | /* USB channel 0 configuration */ | ||
17 | bool chan0_pci:1; /* true: PCI USB host 0, false: USBHS */ | ||
18 | /* USB channel 2 configuration */ | ||
19 | bool chan2_pci:1; /* true: PCI USB host 2, false: USBSS */ | ||
20 | }; | ||
21 | |||
22 | #endif | ||
diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h new file mode 100644 index 000000000000..388f6e08b9d4 --- /dev/null +++ b/include/linux/ulpi/driver.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef __LINUX_ULPI_DRIVER_H | ||
2 | #define __LINUX_ULPI_DRIVER_H | ||
3 | |||
4 | #include <linux/mod_devicetable.h> | ||
5 | |||
6 | #include <linux/device.h> | ||
7 | |||
8 | struct ulpi_ops; | ||
9 | |||
10 | /** | ||
11 | * struct ulpi - describes ULPI PHY device | ||
12 | * @id: vendor and product ids for ULPI device | ||
13 | * @ops: I/O access | ||
14 | * @dev: device interface | ||
15 | */ | ||
16 | struct ulpi { | ||
17 | struct ulpi_device_id id; | ||
18 | struct ulpi_ops *ops; | ||
19 | struct device dev; | ||
20 | }; | ||
21 | |||
22 | #define to_ulpi_dev(d) container_of(d, struct ulpi, dev) | ||
23 | |||
24 | static inline void ulpi_set_drvdata(struct ulpi *ulpi, void *data) | ||
25 | { | ||
26 | dev_set_drvdata(&ulpi->dev, data); | ||
27 | } | ||
28 | |||
29 | static inline void *ulpi_get_drvdata(struct ulpi *ulpi) | ||
30 | { | ||
31 | return dev_get_drvdata(&ulpi->dev); | ||
32 | } | ||
33 | |||
34 | /** | ||
35 | * struct ulpi_driver - describes a ULPI PHY driver | ||
36 | * @id_table: array of device identifiers supported by this driver | ||
37 | * @probe: binds this driver to ULPI device | ||
38 | * @remove: unbinds this driver from ULPI device | ||
39 | * @driver: the name and owner members must be initialized by the drivers | ||
40 | */ | ||
41 | struct ulpi_driver { | ||
42 | const struct ulpi_device_id *id_table; | ||
43 | int (*probe)(struct ulpi *ulpi); | ||
44 | void (*remove)(struct ulpi *ulpi); | ||
45 | struct device_driver driver; | ||
46 | }; | ||
47 | |||
48 | #define to_ulpi_driver(d) container_of(d, struct ulpi_driver, driver) | ||
49 | |||
50 | int ulpi_register_driver(struct ulpi_driver *drv); | ||
51 | void ulpi_unregister_driver(struct ulpi_driver *drv); | ||
52 | |||
53 | #define module_ulpi_driver(__ulpi_driver) \ | ||
54 | module_driver(__ulpi_driver, ulpi_register_driver, \ | ||
55 | ulpi_unregister_driver) | ||
56 | |||
57 | int ulpi_read(struct ulpi *ulpi, u8 addr); | ||
58 | int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val); | ||
59 | |||
60 | #endif /* __LINUX_ULPI_DRIVER_H */ | ||
diff --git a/include/linux/ulpi/interface.h b/include/linux/ulpi/interface.h new file mode 100644 index 000000000000..4de8ab491038 --- /dev/null +++ b/include/linux/ulpi/interface.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef __LINUX_ULPI_INTERFACE_H | ||
2 | #define __LINUX_ULPI_INTERFACE_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | struct ulpi; | ||
7 | |||
8 | /** | ||
9 | * struct ulpi_ops - ULPI register access | ||
10 | * @dev: the interface provider | ||
11 | * @read: read operation for ULPI register access | ||
12 | * @write: write operation for ULPI register access | ||
13 | */ | ||
14 | struct ulpi_ops { | ||
15 | struct device *dev; | ||
16 | int (*read)(struct ulpi_ops *ops, u8 addr); | ||
17 | int (*write)(struct ulpi_ops *ops, u8 addr, u8 val); | ||
18 | }; | ||
19 | |||
20 | struct ulpi *ulpi_register_interface(struct device *, struct ulpi_ops *); | ||
21 | void ulpi_unregister_interface(struct ulpi *); | ||
22 | |||
23 | #endif /* __LINUX_ULPI_INTERFACE_H */ | ||
diff --git a/include/linux/ulpi/regs.h b/include/linux/ulpi/regs.h new file mode 100644 index 000000000000..b5b8b8804560 --- /dev/null +++ b/include/linux/ulpi/regs.h | |||
@@ -0,0 +1,130 @@ | |||
1 | #ifndef __LINUX_ULPI_REGS_H | ||
2 | #define __LINUX_ULPI_REGS_H | ||
3 | |||
4 | /* | ||
5 | * Macros for Set and Clear | ||
6 | * See ULPI 1.1 specification to find the registers with Set and Clear offsets | ||
7 | */ | ||
8 | #define ULPI_SET(a) (a + 1) | ||
9 | #define ULPI_CLR(a) (a + 2) | ||
10 | |||
11 | /* | ||
12 | * Register Map | ||
13 | */ | ||
14 | #define ULPI_VENDOR_ID_LOW 0x00 | ||
15 | #define ULPI_VENDOR_ID_HIGH 0x01 | ||
16 | #define ULPI_PRODUCT_ID_LOW 0x02 | ||
17 | #define ULPI_PRODUCT_ID_HIGH 0x03 | ||
18 | #define ULPI_FUNC_CTRL 0x04 | ||
19 | #define ULPI_IFC_CTRL 0x07 | ||
20 | #define ULPI_OTG_CTRL 0x0a | ||
21 | #define ULPI_USB_INT_EN_RISE 0x0d | ||
22 | #define ULPI_USB_INT_EN_FALL 0x10 | ||
23 | #define ULPI_USB_INT_STS 0x13 | ||
24 | #define ULPI_USB_INT_LATCH 0x14 | ||
25 | #define ULPI_DEBUG 0x15 | ||
26 | #define ULPI_SCRATCH 0x16 | ||
27 | /* Optional Carkit Registers */ | ||
28 | #define ULPI_CARKIT_CTRL 0x19 | ||
29 | #define ULPI_CARKIT_INT_DELAY 0x1c | ||
30 | #define ULPI_CARKIT_INT_EN 0x1d | ||
31 | #define ULPI_CARKIT_INT_STS 0x20 | ||
32 | #define ULPI_CARKIT_INT_LATCH 0x21 | ||
33 | #define ULPI_CARKIT_PLS_CTRL 0x22 | ||
34 | /* Other Optional Registers */ | ||
35 | #define ULPI_TX_POS_WIDTH 0x25 | ||
36 | #define ULPI_TX_NEG_WIDTH 0x26 | ||
37 | #define ULPI_POLARITY_RECOVERY 0x27 | ||
38 | /* Access Extended Register Set */ | ||
39 | #define ULPI_ACCESS_EXTENDED 0x2f | ||
40 | /* Vendor Specific */ | ||
41 | #define ULPI_VENDOR_SPECIFIC 0x30 | ||
42 | /* Extended Registers */ | ||
43 | #define ULPI_EXT_VENDOR_SPECIFIC 0x80 | ||
44 | |||
45 | /* | ||
46 | * Register Bits | ||
47 | */ | ||
48 | |||
49 | /* Function Control */ | ||
50 | #define ULPI_FUNC_CTRL_XCVRSEL BIT(0) | ||
51 | #define ULPI_FUNC_CTRL_XCVRSEL_MASK 0x3 | ||
52 | #define ULPI_FUNC_CTRL_HIGH_SPEED 0x0 | ||
53 | #define ULPI_FUNC_CTRL_FULL_SPEED 0x1 | ||
54 | #define ULPI_FUNC_CTRL_LOW_SPEED 0x2 | ||
55 | #define ULPI_FUNC_CTRL_FS4LS 0x3 | ||
56 | #define ULPI_FUNC_CTRL_TERMSELECT BIT(2) | ||
57 | #define ULPI_FUNC_CTRL_OPMODE BIT(3) | ||
58 | #define ULPI_FUNC_CTRL_OPMODE_MASK (0x3 << 3) | ||
59 | #define ULPI_FUNC_CTRL_OPMODE_NORMAL (0x0 << 3) | ||
60 | #define ULPI_FUNC_CTRL_OPMODE_NONDRIVING (0x1 << 3) | ||
61 | #define ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI (0x2 << 3) | ||
62 | #define ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP (0x3 << 3) | ||
63 | #define ULPI_FUNC_CTRL_RESET BIT(5) | ||
64 | #define ULPI_FUNC_CTRL_SUSPENDM BIT(6) | ||
65 | |||
66 | /* Interface Control */ | ||
67 | #define ULPI_IFC_CTRL_6_PIN_SERIAL_MODE BIT(0) | ||
68 | #define ULPI_IFC_CTRL_3_PIN_SERIAL_MODE BIT(1) | ||
69 | #define ULPI_IFC_CTRL_CARKITMODE BIT(2) | ||
70 | #define ULPI_IFC_CTRL_CLOCKSUSPENDM BIT(3) | ||
71 | #define ULPI_IFC_CTRL_AUTORESUME BIT(4) | ||
72 | #define ULPI_IFC_CTRL_EXTERNAL_VBUS BIT(5) | ||
73 | #define ULPI_IFC_CTRL_PASSTHRU BIT(6) | ||
74 | #define ULPI_IFC_CTRL_PROTECT_IFC_DISABLE BIT(7) | ||
75 | |||
76 | /* OTG Control */ | ||
77 | #define ULPI_OTG_CTRL_ID_PULLUP BIT(0) | ||
78 | #define ULPI_OTG_CTRL_DP_PULLDOWN BIT(1) | ||
79 | #define ULPI_OTG_CTRL_DM_PULLDOWN BIT(2) | ||
80 | #define ULPI_OTG_CTRL_DISCHRGVBUS BIT(3) | ||
81 | #define ULPI_OTG_CTRL_CHRGVBUS BIT(4) | ||
82 | #define ULPI_OTG_CTRL_DRVVBUS BIT(5) | ||
83 | #define ULPI_OTG_CTRL_DRVVBUS_EXT BIT(6) | ||
84 | #define ULPI_OTG_CTRL_EXTVBUSIND BIT(7) | ||
85 | |||
86 | /* USB Interrupt Enable Rising, | ||
87 | * USB Interrupt Enable Falling, | ||
88 | * USB Interrupt Status and | ||
89 | * USB Interrupt Latch | ||
90 | */ | ||
91 | #define ULPI_INT_HOST_DISCONNECT BIT(0) | ||
92 | #define ULPI_INT_VBUS_VALID BIT(1) | ||
93 | #define ULPI_INT_SESS_VALID BIT(2) | ||
94 | #define ULPI_INT_SESS_END BIT(3) | ||
95 | #define ULPI_INT_IDGRD BIT(4) | ||
96 | |||
97 | /* Debug */ | ||
98 | #define ULPI_DEBUG_LINESTATE0 BIT(0) | ||
99 | #define ULPI_DEBUG_LINESTATE1 BIT(1) | ||
100 | |||
101 | /* Carkit Control */ | ||
102 | #define ULPI_CARKIT_CTRL_CARKITPWR BIT(0) | ||
103 | #define ULPI_CARKIT_CTRL_IDGNDDRV BIT(1) | ||
104 | #define ULPI_CARKIT_CTRL_TXDEN BIT(2) | ||
105 | #define ULPI_CARKIT_CTRL_RXDEN BIT(3) | ||
106 | #define ULPI_CARKIT_CTRL_SPKLEFTEN BIT(4) | ||
107 | #define ULPI_CARKIT_CTRL_SPKRIGHTEN BIT(5) | ||
108 | #define ULPI_CARKIT_CTRL_MICEN BIT(6) | ||
109 | |||
110 | /* Carkit Interrupt Enable */ | ||
111 | #define ULPI_CARKIT_INT_EN_IDFLOAT_RISE BIT(0) | ||
112 | #define ULPI_CARKIT_INT_EN_IDFLOAT_FALL BIT(1) | ||
113 | #define ULPI_CARKIT_INT_EN_CARINTDET BIT(2) | ||
114 | #define ULPI_CARKIT_INT_EN_DP_RISE BIT(3) | ||
115 | #define ULPI_CARKIT_INT_EN_DP_FALL BIT(4) | ||
116 | |||
117 | /* Carkit Interrupt Status and | ||
118 | * Carkit Interrupt Latch | ||
119 | */ | ||
120 | #define ULPI_CARKIT_INT_IDFLOAT BIT(0) | ||
121 | #define ULPI_CARKIT_INT_CARINTDET BIT(1) | ||
122 | #define ULPI_CARKIT_INT_DP BIT(2) | ||
123 | |||
124 | /* Carkit Pulse Control*/ | ||
125 | #define ULPI_CARKIT_PLS_CTRL_TXPLSEN BIT(0) | ||
126 | #define ULPI_CARKIT_PLS_CTRL_RXPLSEN BIT(1) | ||
127 | #define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN BIT(2) | ||
128 | #define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN BIT(3) | ||
129 | |||
130 | #endif /* __LINUX_ULPI_REGS_H */ | ||
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 68b1e836dff1..c9aa7792de10 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -622,8 +622,6 @@ extern struct list_head usb_bus_list; | |||
622 | extern struct mutex usb_bus_list_lock; | 622 | extern struct mutex usb_bus_list_lock; |
623 | extern wait_queue_head_t usb_kill_urb_queue; | 623 | extern wait_queue_head_t usb_kill_urb_queue; |
624 | 624 | ||
625 | extern int usb_find_interface_driver(struct usb_device *dev, | ||
626 | struct usb_interface *interface); | ||
627 | 625 | ||
628 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) | 626 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) |
629 | 627 | ||
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 7dbecf9a4656..e55a1504266e 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #ifndef __ASM_ARCH_MSM_HSUSB_H | 18 | #ifndef __ASM_ARCH_MSM_HSUSB_H |
19 | #define __ASM_ARCH_MSM_HSUSB_H | 19 | #define __ASM_ARCH_MSM_HSUSB_H |
20 | 20 | ||
21 | #include <linux/extcon.h> | ||
21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
22 | #include <linux/usb/otg.h> | 23 | #include <linux/usb/otg.h> |
23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
@@ -120,6 +121,17 @@ struct msm_otg_platform_data { | |||
120 | }; | 121 | }; |
121 | 122 | ||
122 | /** | 123 | /** |
124 | * struct msm_usb_cable - structure for exteternal connector cable | ||
125 | * state tracking | ||
126 | * @nb: hold event notification callback | ||
127 | * @conn: used for notification registration | ||
128 | */ | ||
129 | struct msm_usb_cable { | ||
130 | struct notifier_block nb; | ||
131 | struct extcon_specific_cable_nb conn; | ||
132 | }; | ||
133 | |||
134 | /** | ||
123 | * struct msm_otg: OTG driver data. Shared by HCD and DCD. | 135 | * struct msm_otg: OTG driver data. Shared by HCD and DCD. |
124 | * @otg: USB OTG Transceiver structure. | 136 | * @otg: USB OTG Transceiver structure. |
125 | * @pdata: otg device platform data. | 137 | * @pdata: otg device platform data. |
@@ -138,6 +150,11 @@ struct msm_otg_platform_data { | |||
138 | * @chg_type: The type of charger attached. | 150 | * @chg_type: The type of charger attached. |
139 | * @dcd_retires: The retry count used to track Data contact | 151 | * @dcd_retires: The retry count used to track Data contact |
140 | * detection process. | 152 | * detection process. |
153 | * @manual_pullup: true if VBUS is not routed to USB controller/phy | ||
154 | * and controller driver therefore enables pull-up explicitly before | ||
155 | * starting controller using usbcmd run/stop bit. | ||
156 | * @vbus: VBUS signal state trakining, using extcon framework | ||
157 | * @id: ID signal state trakining, using extcon framework | ||
141 | */ | 158 | */ |
142 | struct msm_otg { | 159 | struct msm_otg { |
143 | struct usb_phy phy; | 160 | struct usb_phy phy; |
@@ -166,6 +183,11 @@ struct msm_otg { | |||
166 | struct reset_control *phy_rst; | 183 | struct reset_control *phy_rst; |
167 | struct reset_control *link_rst; | 184 | struct reset_control *link_rst; |
168 | int vdd_levels[3]; | 185 | int vdd_levels[3]; |
186 | |||
187 | bool manual_pullup; | ||
188 | |||
189 | struct msm_usb_cable vbus; | ||
190 | struct msm_usb_cable id; | ||
169 | }; | 191 | }; |
170 | 192 | ||
171 | #endif | 193 | #endif |
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h index a29f6030afb1..e159b39f67a2 100644 --- a/include/linux/usb/msm_hsusb_hw.h +++ b/include/linux/usb/msm_hsusb_hw.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) | 22 | #define USB_AHBBURST (MSM_USB_BASE + 0x0090) |
23 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) | 23 | #define USB_AHBMODE (MSM_USB_BASE + 0x0098) |
24 | #define USB_GENCONFIG_2 (MSM_USB_BASE + 0x00a0) | ||
25 | |||
24 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ | 26 | #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ |
25 | 27 | ||
26 | #define USB_USBCMD (MSM_USB_BASE + 0x0140) | 28 | #define USB_USBCMD (MSM_USB_BASE + 0x0140) |
@@ -30,6 +32,9 @@ | |||
30 | #define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) | 32 | #define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) |
31 | #define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278) | 33 | #define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278) |
32 | 34 | ||
35 | #define GENCONFIG_2_SESS_VLD_CTRL_EN BIT(7) | ||
36 | #define USBCMD_SESS_VLD_CTRL BIT(25) | ||
37 | |||
33 | #define USBCMD_RESET 2 | 38 | #define USBCMD_RESET 2 |
34 | #define USB_USBINTR (MSM_USB_BASE + 0x0148) | 39 | #define USB_USBINTR (MSM_USB_BASE + 0x0148) |
35 | 40 | ||
@@ -50,6 +55,10 @@ | |||
50 | #define ULPI_PWR_CLK_MNG_REG 0x88 | 55 | #define ULPI_PWR_CLK_MNG_REG 0x88 |
51 | #define OTG_COMP_DISABLE BIT(0) | 56 | #define OTG_COMP_DISABLE BIT(0) |
52 | 57 | ||
58 | #define ULPI_MISC_A 0x96 | ||
59 | #define ULPI_MISC_A_VBUSVLDEXTSEL BIT(1) | ||
60 | #define ULPI_MISC_A_VBUSVLDEXT BIT(0) | ||
61 | |||
53 | #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ | 62 | #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ |
54 | #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ | 63 | #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ |
55 | #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ | 64 | #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ |
diff --git a/include/linux/usb/net2280.h b/include/linux/usb/net2280.h index 148b8fa5b1a2..725120224472 100644 --- a/include/linux/usb/net2280.h +++ b/include/linux/usb/net2280.h | |||
@@ -168,6 +168,9 @@ struct net2280_regs { | |||
168 | #define ENDPOINT_B_INTERRUPT 2 | 168 | #define ENDPOINT_B_INTERRUPT 2 |
169 | #define ENDPOINT_A_INTERRUPT 1 | 169 | #define ENDPOINT_A_INTERRUPT 1 |
170 | #define ENDPOINT_0_INTERRUPT 0 | 170 | #define ENDPOINT_0_INTERRUPT 0 |
171 | #define USB3380_IRQSTAT0_EP_INTR_MASK_IN (0xF << 17) | ||
172 | #define USB3380_IRQSTAT0_EP_INTR_MASK_OUT (0xF << 1) | ||
173 | |||
171 | u32 irqstat1; | 174 | u32 irqstat1; |
172 | #define POWER_STATE_CHANGE_INTERRUPT 27 | 175 | #define POWER_STATE_CHANGE_INTERRUPT 27 |
173 | #define PCI_ARBITER_TIMEOUT_INTERRUPT 26 | 176 | #define PCI_ARBITER_TIMEOUT_INTERRUPT 26 |
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index bc91b5d380fd..e39f251cf861 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h | |||
@@ -205,6 +205,8 @@ extern struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index); | |||
205 | extern struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index); | 205 | extern struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index); |
206 | extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | 206 | extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, |
207 | const char *phandle, u8 index); | 207 | const char *phandle, u8 index); |
208 | extern struct usb_phy *devm_usb_get_phy_by_node(struct device *dev, | ||
209 | struct device_node *node, struct notifier_block *nb); | ||
208 | extern void usb_put_phy(struct usb_phy *); | 210 | extern void usb_put_phy(struct usb_phy *); |
209 | extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); | 211 | extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); |
210 | extern int usb_bind_phy(const char *dev_name, u8 index, | 212 | extern int usb_bind_phy(const char *dev_name, u8 index, |
@@ -238,6 +240,12 @@ static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | |||
238 | return ERR_PTR(-ENXIO); | 240 | return ERR_PTR(-ENXIO); |
239 | } | 241 | } |
240 | 242 | ||
243 | static inline struct usb_phy *devm_usb_get_phy_by_node(struct device *dev, | ||
244 | struct device_node *node, struct notifier_block *nb) | ||
245 | { | ||
246 | return ERR_PTR(-ENXIO); | ||
247 | } | ||
248 | |||
241 | static inline void usb_put_phy(struct usb_phy *x) | 249 | static inline void usb_put_phy(struct usb_phy *x) |
242 | { | 250 | { |
243 | } | 251 | } |
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index f06529c14141..3dd5a781da99 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h | |||
@@ -169,8 +169,7 @@ struct renesas_usbhs_driver_param { | |||
169 | #define USBHS_USB_DMAC_XFER_SIZE 32 /* hardcode the xfer size */ | 169 | #define USBHS_USB_DMAC_XFER_SIZE 32 /* hardcode the xfer size */ |
170 | }; | 170 | }; |
171 | 171 | ||
172 | #define USBHS_TYPE_R8A7790 1 | 172 | #define USBHS_TYPE_RCAR_GEN2 1 |
173 | #define USBHS_TYPE_R8A7791 2 | ||
174 | 173 | ||
175 | /* | 174 | /* |
176 | * option: | 175 | * option: |
diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h index 5c295c26ad37..5f07407a367a 100644 --- a/include/linux/usb/ulpi.h +++ b/include/linux/usb/ulpi.h | |||
@@ -12,6 +12,8 @@ | |||
12 | #define __LINUX_USB_ULPI_H | 12 | #define __LINUX_USB_ULPI_H |
13 | 13 | ||
14 | #include <linux/usb/otg.h> | 14 | #include <linux/usb/otg.h> |
15 | #include <linux/ulpi/regs.h> | ||
16 | |||
15 | /*-------------------------------------------------------------------------*/ | 17 | /*-------------------------------------------------------------------------*/ |
16 | 18 | ||
17 | /* | 19 | /* |
@@ -49,138 +51,6 @@ | |||
49 | 51 | ||
50 | /*-------------------------------------------------------------------------*/ | 52 | /*-------------------------------------------------------------------------*/ |
51 | 53 | ||
52 | /* | ||
53 | * Macros for Set and Clear | ||
54 | * See ULPI 1.1 specification to find the registers with Set and Clear offsets | ||
55 | */ | ||
56 | #define ULPI_SET(a) (a + 1) | ||
57 | #define ULPI_CLR(a) (a + 2) | ||
58 | |||
59 | /*-------------------------------------------------------------------------*/ | ||
60 | |||
61 | /* | ||
62 | * Register Map | ||
63 | */ | ||
64 | #define ULPI_VENDOR_ID_LOW 0x00 | ||
65 | #define ULPI_VENDOR_ID_HIGH 0x01 | ||
66 | #define ULPI_PRODUCT_ID_LOW 0x02 | ||
67 | #define ULPI_PRODUCT_ID_HIGH 0x03 | ||
68 | #define ULPI_FUNC_CTRL 0x04 | ||
69 | #define ULPI_IFC_CTRL 0x07 | ||
70 | #define ULPI_OTG_CTRL 0x0a | ||
71 | #define ULPI_USB_INT_EN_RISE 0x0d | ||
72 | #define ULPI_USB_INT_EN_FALL 0x10 | ||
73 | #define ULPI_USB_INT_STS 0x13 | ||
74 | #define ULPI_USB_INT_LATCH 0x14 | ||
75 | #define ULPI_DEBUG 0x15 | ||
76 | #define ULPI_SCRATCH 0x16 | ||
77 | /* Optional Carkit Registers */ | ||
78 | #define ULPI_CARCIT_CTRL 0x19 | ||
79 | #define ULPI_CARCIT_INT_DELAY 0x1c | ||
80 | #define ULPI_CARCIT_INT_EN 0x1d | ||
81 | #define ULPI_CARCIT_INT_STS 0x20 | ||
82 | #define ULPI_CARCIT_INT_LATCH 0x21 | ||
83 | #define ULPI_CARCIT_PLS_CTRL 0x22 | ||
84 | /* Other Optional Registers */ | ||
85 | #define ULPI_TX_POS_WIDTH 0x25 | ||
86 | #define ULPI_TX_NEG_WIDTH 0x26 | ||
87 | #define ULPI_POLARITY_RECOVERY 0x27 | ||
88 | /* Access Extended Register Set */ | ||
89 | #define ULPI_ACCESS_EXTENDED 0x2f | ||
90 | /* Vendor Specific */ | ||
91 | #define ULPI_VENDOR_SPECIFIC 0x30 | ||
92 | /* Extended Registers */ | ||
93 | #define ULPI_EXT_VENDOR_SPECIFIC 0x80 | ||
94 | |||
95 | /*-------------------------------------------------------------------------*/ | ||
96 | |||
97 | /* | ||
98 | * Register Bits | ||
99 | */ | ||
100 | |||
101 | /* Function Control */ | ||
102 | #define ULPI_FUNC_CTRL_XCVRSEL (1 << 0) | ||
103 | #define ULPI_FUNC_CTRL_XCVRSEL_MASK (3 << 0) | ||
104 | #define ULPI_FUNC_CTRL_HIGH_SPEED (0 << 0) | ||
105 | #define ULPI_FUNC_CTRL_FULL_SPEED (1 << 0) | ||
106 | #define ULPI_FUNC_CTRL_LOW_SPEED (2 << 0) | ||
107 | #define ULPI_FUNC_CTRL_FS4LS (3 << 0) | ||
108 | #define ULPI_FUNC_CTRL_TERMSELECT (1 << 2) | ||
109 | #define ULPI_FUNC_CTRL_OPMODE (1 << 3) | ||
110 | #define ULPI_FUNC_CTRL_OPMODE_MASK (3 << 3) | ||
111 | #define ULPI_FUNC_CTRL_OPMODE_NORMAL (0 << 3) | ||
112 | #define ULPI_FUNC_CTRL_OPMODE_NONDRIVING (1 << 3) | ||
113 | #define ULPI_FUNC_CTRL_OPMODE_DISABLE_NRZI (2 << 3) | ||
114 | #define ULPI_FUNC_CTRL_OPMODE_NOSYNC_NOEOP (3 << 3) | ||
115 | #define ULPI_FUNC_CTRL_RESET (1 << 5) | ||
116 | #define ULPI_FUNC_CTRL_SUSPENDM (1 << 6) | ||
117 | |||
118 | /* Interface Control */ | ||
119 | #define ULPI_IFC_CTRL_6_PIN_SERIAL_MODE (1 << 0) | ||
120 | #define ULPI_IFC_CTRL_3_PIN_SERIAL_MODE (1 << 1) | ||
121 | #define ULPI_IFC_CTRL_CARKITMODE (1 << 2) | ||
122 | #define ULPI_IFC_CTRL_CLOCKSUSPENDM (1 << 3) | ||
123 | #define ULPI_IFC_CTRL_AUTORESUME (1 << 4) | ||
124 | #define ULPI_IFC_CTRL_EXTERNAL_VBUS (1 << 5) | ||
125 | #define ULPI_IFC_CTRL_PASSTHRU (1 << 6) | ||
126 | #define ULPI_IFC_CTRL_PROTECT_IFC_DISABLE (1 << 7) | ||
127 | |||
128 | /* OTG Control */ | ||
129 | #define ULPI_OTG_CTRL_ID_PULLUP (1 << 0) | ||
130 | #define ULPI_OTG_CTRL_DP_PULLDOWN (1 << 1) | ||
131 | #define ULPI_OTG_CTRL_DM_PULLDOWN (1 << 2) | ||
132 | #define ULPI_OTG_CTRL_DISCHRGVBUS (1 << 3) | ||
133 | #define ULPI_OTG_CTRL_CHRGVBUS (1 << 4) | ||
134 | #define ULPI_OTG_CTRL_DRVVBUS (1 << 5) | ||
135 | #define ULPI_OTG_CTRL_DRVVBUS_EXT (1 << 6) | ||
136 | #define ULPI_OTG_CTRL_EXTVBUSIND (1 << 7) | ||
137 | |||
138 | /* USB Interrupt Enable Rising, | ||
139 | * USB Interrupt Enable Falling, | ||
140 | * USB Interrupt Status and | ||
141 | * USB Interrupt Latch | ||
142 | */ | ||
143 | #define ULPI_INT_HOST_DISCONNECT (1 << 0) | ||
144 | #define ULPI_INT_VBUS_VALID (1 << 1) | ||
145 | #define ULPI_INT_SESS_VALID (1 << 2) | ||
146 | #define ULPI_INT_SESS_END (1 << 3) | ||
147 | #define ULPI_INT_IDGRD (1 << 4) | ||
148 | |||
149 | /* Debug */ | ||
150 | #define ULPI_DEBUG_LINESTATE0 (1 << 0) | ||
151 | #define ULPI_DEBUG_LINESTATE1 (1 << 1) | ||
152 | |||
153 | /* Carkit Control */ | ||
154 | #define ULPI_CARKIT_CTRL_CARKITPWR (1 << 0) | ||
155 | #define ULPI_CARKIT_CTRL_IDGNDDRV (1 << 1) | ||
156 | #define ULPI_CARKIT_CTRL_TXDEN (1 << 2) | ||
157 | #define ULPI_CARKIT_CTRL_RXDEN (1 << 3) | ||
158 | #define ULPI_CARKIT_CTRL_SPKLEFTEN (1 << 4) | ||
159 | #define ULPI_CARKIT_CTRL_SPKRIGHTEN (1 << 5) | ||
160 | #define ULPI_CARKIT_CTRL_MICEN (1 << 6) | ||
161 | |||
162 | /* Carkit Interrupt Enable */ | ||
163 | #define ULPI_CARKIT_INT_EN_IDFLOAT_RISE (1 << 0) | ||
164 | #define ULPI_CARKIT_INT_EN_IDFLOAT_FALL (1 << 1) | ||
165 | #define ULPI_CARKIT_INT_EN_CARINTDET (1 << 2) | ||
166 | #define ULPI_CARKIT_INT_EN_DP_RISE (1 << 3) | ||
167 | #define ULPI_CARKIT_INT_EN_DP_FALL (1 << 4) | ||
168 | |||
169 | /* Carkit Interrupt Status and | ||
170 | * Carkit Interrupt Latch | ||
171 | */ | ||
172 | #define ULPI_CARKIT_INT_IDFLOAT (1 << 0) | ||
173 | #define ULPI_CARKIT_INT_CARINTDET (1 << 1) | ||
174 | #define ULPI_CARKIT_INT_DP (1 << 2) | ||
175 | |||
176 | /* Carkit Pulse Control*/ | ||
177 | #define ULPI_CARKIT_PLS_CTRL_TXPLSEN (1 << 0) | ||
178 | #define ULPI_CARKIT_PLS_CTRL_RXPLSEN (1 << 1) | ||
179 | #define ULPI_CARKIT_PLS_CTRL_SPKRLEFT_BIASEN (1 << 2) | ||
180 | #define ULPI_CARKIT_PLS_CTRL_SPKRRIGHT_BIASEN (1 << 3) | ||
181 | |||
182 | /*-------------------------------------------------------------------------*/ | ||
183 | |||
184 | #if IS_ENABLED(CONFIG_USB_ULPI) | 54 | #if IS_ENABLED(CONFIG_USB_ULPI) |
185 | struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops, | 55 | struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops, |
186 | unsigned int flags); | 56 | unsigned int flags); |
diff --git a/include/linux/usb/usb338x.h b/include/linux/usb/usb338x.h index f92eb635b9d3..11525d8d89a7 100644 --- a/include/linux/usb/usb338x.h +++ b/include/linux/usb/usb338x.h | |||
@@ -43,6 +43,10 @@ | |||
43 | #define IN_ENDPOINT_TYPE 12 | 43 | #define IN_ENDPOINT_TYPE 12 |
44 | #define OUT_ENDPOINT_ENABLE 10 | 44 | #define OUT_ENDPOINT_ENABLE 10 |
45 | #define OUT_ENDPOINT_TYPE 8 | 45 | #define OUT_ENDPOINT_TYPE 8 |
46 | #define USB3380_EP_CFG_MASK_IN ((0x3 << IN_ENDPOINT_TYPE) | \ | ||
47 | BIT(IN_ENDPOINT_ENABLE)) | ||
48 | #define USB3380_EP_CFG_MASK_OUT ((0x3 << OUT_ENDPOINT_TYPE) | \ | ||
49 | BIT(OUT_ENDPOINT_ENABLE)) | ||
46 | 50 | ||
47 | struct usb338x_usb_ext_regs { | 51 | struct usb338x_usb_ext_regs { |
48 | u32 usbclass; | 52 | u32 usbclass; |
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 091f6290a651..eff7de1fc82e 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c | |||
@@ -190,5 +190,9 @@ int main(void) | |||
190 | DEVID_FIELD(rio_device_id, asm_did); | 190 | DEVID_FIELD(rio_device_id, asm_did); |
191 | DEVID_FIELD(rio_device_id, asm_vid); | 191 | DEVID_FIELD(rio_device_id, asm_vid); |
192 | 192 | ||
193 | DEVID(ulpi_device_id); | ||
194 | DEVID_FIELD(ulpi_device_id, vendor); | ||
195 | DEVID_FIELD(ulpi_device_id, product); | ||
196 | |||
193 | return 0; | 197 | return 0; |
194 | } | 198 | } |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 718b2a29bd43..84c86f3cd6cd 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -1209,6 +1209,19 @@ static int do_rio_entry(const char *filename, | |||
1209 | } | 1209 | } |
1210 | ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry); | 1210 | ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry); |
1211 | 1211 | ||
1212 | /* Looks like: ulpi:vNpN */ | ||
1213 | static int do_ulpi_entry(const char *filename, void *symval, | ||
1214 | char *alias) | ||
1215 | { | ||
1216 | DEF_FIELD(symval, ulpi_device_id, vendor); | ||
1217 | DEF_FIELD(symval, ulpi_device_id, product); | ||
1218 | |||
1219 | sprintf(alias, "ulpi:v%04xp%04x", vendor, product); | ||
1220 | |||
1221 | return 1; | ||
1222 | } | ||
1223 | ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry); | ||
1224 | |||
1212 | /* Does namelen bytes of name exactly match the symbol? */ | 1225 | /* Does namelen bytes of name exactly match the symbol? */ |
1213 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) | 1226 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) |
1214 | { | 1227 | { |