diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Kconfig | 16 | ||||
-rw-r--r-- | drivers/usb/musb/Makefile | 71 | ||||
-rw-r--r-- | drivers/usb/musb/am35x.c | 524 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/cppi_dma.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/da8xx.c | 469 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 57 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_debug.h | 11 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 132 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 11 | ||||
-rw-r--r-- | drivers/usb/musb/musbhsdma.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 4 |
16 files changed, 1164 insertions, 149 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index cfd38edfcf9e..341a37a469bd 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -45,6 +45,9 @@ config USB_MUSB_SOC | |||
45 | comment "DaVinci 35x and 644x USB support" | 45 | comment "DaVinci 35x and 644x USB support" |
46 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx | 46 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx |
47 | 47 | ||
48 | comment "DA8xx/OMAP-L1x USB support" | ||
49 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DA8XX | ||
50 | |||
48 | comment "OMAP 243x high speed USB support" | 51 | comment "OMAP 243x high speed USB support" |
49 | depends on USB_MUSB_HDRC && ARCH_OMAP2430 | 52 | depends on USB_MUSB_HDRC && ARCH_OMAP2430 |
50 | 53 | ||
@@ -57,6 +60,17 @@ comment "OMAP 44xx high speed USB support" | |||
57 | comment "Blackfin high speed USB Support" | 60 | comment "Blackfin high speed USB Support" |
58 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) | 61 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) |
59 | 62 | ||
63 | config USB_MUSB_AM35X | ||
64 | bool | ||
65 | depends on USB_MUSB_HDRC && !ARCH_OMAP2430 && !ARCH_OMAP4 | ||
66 | select NOP_USB_XCEIV | ||
67 | default MACH_OMAP3517EVM | ||
68 | help | ||
69 | Select this option if your platform is based on AM35x. As | ||
70 | AM35x has an updated MUSB with CPPI4.1 DMA so this config | ||
71 | is introduced to differentiate musb ip between OMAP3x and | ||
72 | AM35x platforms. | ||
73 | |||
60 | config USB_TUSB6010 | 74 | config USB_TUSB6010 |
61 | boolean "TUSB 6010 support" | 75 | boolean "TUSB 6010 support" |
62 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC | 76 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC |
@@ -144,7 +158,7 @@ config USB_MUSB_HDRC_HCD | |||
144 | config MUSB_PIO_ONLY | 158 | config MUSB_PIO_ONLY |
145 | bool 'Disable DMA (always use PIO)' | 159 | bool 'Disable DMA (always use PIO)' |
146 | depends on USB_MUSB_HDRC | 160 | depends on USB_MUSB_HDRC |
147 | default y if USB_TUSB6010 | 161 | default USB_TUSB6010 || ARCH_DAVINCI_DA8XX || USB_MUSB_AM35X |
148 | help | 162 | help |
149 | All data is copied between memory and FIFO by the CPU. | 163 | All data is copied between memory and FIFO by the CPU. |
150 | DMA controllers are ignored. | 164 | DMA controllers are ignored. |
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 9705f716386e..ce164e8998d8 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile | |||
@@ -2,49 +2,27 @@ | |||
2 | # for USB OTG silicon based on Mentor Graphics INVENTRA designs | 2 | # for USB OTG silicon based on Mentor Graphics INVENTRA designs |
3 | # | 3 | # |
4 | 4 | ||
5 | musb_hdrc-objs := musb_core.o | 5 | ccflags-$(CONFIG_USB_MUSB_DEBUG) := -DDEBUG |
6 | 6 | ||
7 | obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o | 7 | obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o |
8 | 8 | ||
9 | ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y) | 9 | musb_hdrc-y := musb_core.o |
10 | musb_hdrc-objs += davinci.o | ||
11 | endif | ||
12 | |||
13 | ifeq ($(CONFIG_USB_TUSB6010),y) | ||
14 | musb_hdrc-objs += tusb6010.o | ||
15 | endif | ||
16 | |||
17 | ifeq ($(CONFIG_ARCH_OMAP2430),y) | ||
18 | musb_hdrc-objs += omap2430.o | ||
19 | endif | ||
20 | |||
21 | ifeq ($(CONFIG_ARCH_OMAP3430),y) | ||
22 | musb_hdrc-objs += omap2430.o | ||
23 | endif | ||
24 | |||
25 | ifeq ($(CONFIG_ARCH_OMAP4),y) | ||
26 | musb_hdrc-objs += omap2430.o | ||
27 | endif | ||
28 | |||
29 | ifeq ($(CONFIG_BF54x),y) | ||
30 | musb_hdrc-objs += blackfin.o | ||
31 | endif | ||
32 | 10 | ||
33 | ifeq ($(CONFIG_BF52x),y) | 11 | musb_hdrc-$(CONFIG_ARCH_DAVINCI_DMx) += davinci.o |
34 | musb_hdrc-objs += blackfin.o | 12 | musb_hdrc-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx.o |
35 | endif | 13 | musb_hdrc-$(CONFIG_USB_TUSB6010) += tusb6010.o |
36 | 14 | musb_hdrc-$(CONFIG_ARCH_OMAP2430) += omap2430.o | |
37 | ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) | 15 | ifeq ($(CONFIG_USB_MUSB_AM35X),y) |
38 | musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o | 16 | musb_hdrc-$(CONFIG_ARCH_OMAP3430) += am35x.o |
39 | endif | 17 | else |
40 | 18 | musb_hdrc-$(CONFIG_ARCH_OMAP3430) += omap2430.o | |
41 | ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y) | ||
42 | musb_hdrc-objs += musb_virthub.o musb_host.o | ||
43 | endif | ||
44 | |||
45 | ifeq ($(CONFIG_DEBUG_FS),y) | ||
46 | musb_hdrc-objs += musb_debugfs.o | ||
47 | endif | 19 | endif |
20 | musb_hdrc-$(CONFIG_ARCH_OMAP4) += omap2430.o | ||
21 | musb_hdrc-$(CONFIG_BF54x) += blackfin.o | ||
22 | musb_hdrc-$(CONFIG_BF52x) += blackfin.o | ||
23 | musb_hdrc-$(CONFIG_USB_GADGET_MUSB_HDRC) += musb_gadget_ep0.o musb_gadget.o | ||
24 | musb_hdrc-$(CONFIG_USB_MUSB_HDRC_HCD) += musb_virthub.o musb_host.o | ||
25 | musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o | ||
48 | 26 | ||
49 | # the kconfig must guarantee that only one of the | 27 | # the kconfig must guarantee that only one of the |
50 | # possible I/O schemes will be enabled at a time ... | 28 | # possible I/O schemes will be enabled at a time ... |
@@ -54,26 +32,17 @@ endif | |||
54 | ifneq ($(CONFIG_MUSB_PIO_ONLY),y) | 32 | ifneq ($(CONFIG_MUSB_PIO_ONLY),y) |
55 | 33 | ||
56 | ifeq ($(CONFIG_USB_INVENTRA_DMA),y) | 34 | ifeq ($(CONFIG_USB_INVENTRA_DMA),y) |
57 | musb_hdrc-objs += musbhsdma.o | 35 | musb_hdrc-y += musbhsdma.o |
58 | 36 | ||
59 | else | 37 | else |
60 | ifeq ($(CONFIG_USB_TI_CPPI_DMA),y) | 38 | ifeq ($(CONFIG_USB_TI_CPPI_DMA),y) |
61 | musb_hdrc-objs += cppi_dma.o | 39 | musb_hdrc-y += cppi_dma.o |
62 | 40 | ||
63 | else | 41 | else |
64 | ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y) | 42 | ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y) |
65 | musb_hdrc-objs += tusb6010_omap.o | 43 | musb_hdrc-y += tusb6010_omap.o |
66 | 44 | ||
67 | endif | 45 | endif |
68 | endif | 46 | endif |
69 | endif | 47 | endif |
70 | endif | 48 | endif |
71 | |||
72 | |||
73 | ################################################################################ | ||
74 | |||
75 | # Debugging | ||
76 | |||
77 | ifeq ($(CONFIG_USB_MUSB_DEBUG),y) | ||
78 | EXTRA_CFLAGS += -DDEBUG | ||
79 | endif | ||
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c new file mode 100644 index 000000000000..b0aabf3a606f --- /dev/null +++ b/drivers/usb/musb/am35x.c | |||
@@ -0,0 +1,524 @@ | |||
1 | /* | ||
2 | * Texas Instruments AM35x "glue layer" | ||
3 | * | ||
4 | * Copyright (c) 2010, by Texas Instruments | ||
5 | * | ||
6 | * Based on the DA8xx "glue layer" code. | ||
7 | * Copyright (c) 2008-2009, MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This file is part of the Inventra Controller Driver for Linux. | ||
10 | * | ||
11 | * The Inventra Controller Driver for Linux is free software; you | ||
12 | * can redistribute it and/or modify it under the terms of the GNU | ||
13 | * General Public License version 2 as published by the Free Software | ||
14 | * Foundation. | ||
15 | * | ||
16 | * The Inventra Controller Driver for Linux is distributed in | ||
17 | * the hope that it will be useful, but WITHOUT ANY WARRANTY; | ||
18 | * without even the implied warranty of MERCHANTABILITY or | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||
20 | * License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with The Inventra Controller Driver for Linux ; if not, | ||
24 | * write to the Free Software Foundation, Inc., 59 Temple Place, | ||
25 | * Suite 330, Boston, MA 02111-1307 USA | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/io.h> | ||
32 | |||
33 | #include <plat/control.h> | ||
34 | #include <plat/usb.h> | ||
35 | |||
36 | #include "musb_core.h" | ||
37 | |||
38 | /* | ||
39 | * AM35x specific definitions | ||
40 | */ | ||
41 | /* USB 2.0 OTG module registers */ | ||
42 | #define USB_REVISION_REG 0x00 | ||
43 | #define USB_CTRL_REG 0x04 | ||
44 | #define USB_STAT_REG 0x08 | ||
45 | #define USB_EMULATION_REG 0x0c | ||
46 | /* 0x10 Reserved */ | ||
47 | #define USB_AUTOREQ_REG 0x14 | ||
48 | #define USB_SRP_FIX_TIME_REG 0x18 | ||
49 | #define USB_TEARDOWN_REG 0x1c | ||
50 | #define EP_INTR_SRC_REG 0x20 | ||
51 | #define EP_INTR_SRC_SET_REG 0x24 | ||
52 | #define EP_INTR_SRC_CLEAR_REG 0x28 | ||
53 | #define EP_INTR_MASK_REG 0x2c | ||
54 | #define EP_INTR_MASK_SET_REG 0x30 | ||
55 | #define EP_INTR_MASK_CLEAR_REG 0x34 | ||
56 | #define EP_INTR_SRC_MASKED_REG 0x38 | ||
57 | #define CORE_INTR_SRC_REG 0x40 | ||
58 | #define CORE_INTR_SRC_SET_REG 0x44 | ||
59 | #define CORE_INTR_SRC_CLEAR_REG 0x48 | ||
60 | #define CORE_INTR_MASK_REG 0x4c | ||
61 | #define CORE_INTR_MASK_SET_REG 0x50 | ||
62 | #define CORE_INTR_MASK_CLEAR_REG 0x54 | ||
63 | #define CORE_INTR_SRC_MASKED_REG 0x58 | ||
64 | /* 0x5c Reserved */ | ||
65 | #define USB_END_OF_INTR_REG 0x60 | ||
66 | |||
67 | /* Control register bits */ | ||
68 | #define AM35X_SOFT_RESET_MASK 1 | ||
69 | |||
70 | /* USB interrupt register bits */ | ||
71 | #define AM35X_INTR_USB_SHIFT 16 | ||
72 | #define AM35X_INTR_USB_MASK (0x1ff << AM35X_INTR_USB_SHIFT) | ||
73 | #define AM35X_INTR_DRVVBUS 0x100 | ||
74 | #define AM35X_INTR_RX_SHIFT 16 | ||
75 | #define AM35X_INTR_TX_SHIFT 0 | ||
76 | #define AM35X_TX_EP_MASK 0xffff /* EP0 + 15 Tx EPs */ | ||
77 | #define AM35X_RX_EP_MASK 0xfffe /* 15 Rx EPs */ | ||
78 | #define AM35X_TX_INTR_MASK (AM35X_TX_EP_MASK << AM35X_INTR_TX_SHIFT) | ||
79 | #define AM35X_RX_INTR_MASK (AM35X_RX_EP_MASK << AM35X_INTR_RX_SHIFT) | ||
80 | |||
81 | #define USB_MENTOR_CORE_OFFSET 0x400 | ||
82 | |||
83 | static inline void phy_on(void) | ||
84 | { | ||
85 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
86 | u32 devconf2; | ||
87 | |||
88 | /* | ||
89 | * Start the on-chip PHY and its PLL. | ||
90 | */ | ||
91 | devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | ||
92 | |||
93 | devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); | ||
94 | devconf2 |= CONF2_PHY_PLLON; | ||
95 | |||
96 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | ||
97 | |||
98 | DBG(1, "Waiting for PHY clock good...\n"); | ||
99 | while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) | ||
100 | & CONF2_PHYCLKGD)) { | ||
101 | cpu_relax(); | ||
102 | |||
103 | if (time_after(jiffies, timeout)) { | ||
104 | DBG(1, "musb PHY clock good timed out\n"); | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static inline void phy_off(void) | ||
111 | { | ||
112 | u32 devconf2; | ||
113 | |||
114 | /* | ||
115 | * Power down the on-chip PHY. | ||
116 | */ | ||
117 | devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | ||
118 | |||
119 | devconf2 &= ~CONF2_PHY_PLLON; | ||
120 | devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; | ||
121 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * musb_platform_enable - enable interrupts | ||
126 | */ | ||
127 | void musb_platform_enable(struct musb *musb) | ||
128 | { | ||
129 | void __iomem *reg_base = musb->ctrl_base; | ||
130 | u32 epmask; | ||
131 | |||
132 | /* Workaround: setup IRQs through both register sets. */ | ||
133 | epmask = ((musb->epmask & AM35X_TX_EP_MASK) << AM35X_INTR_TX_SHIFT) | | ||
134 | ((musb->epmask & AM35X_RX_EP_MASK) << AM35X_INTR_RX_SHIFT); | ||
135 | |||
136 | musb_writel(reg_base, EP_INTR_MASK_SET_REG, epmask); | ||
137 | musb_writel(reg_base, CORE_INTR_MASK_SET_REG, AM35X_INTR_USB_MASK); | ||
138 | |||
139 | /* Force the DRVVBUS IRQ so we can start polling for ID change. */ | ||
140 | if (is_otg_enabled(musb)) | ||
141 | musb_writel(reg_base, CORE_INTR_SRC_SET_REG, | ||
142 | AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * musb_platform_disable - disable HDRC and flush interrupts | ||
147 | */ | ||
148 | void musb_platform_disable(struct musb *musb) | ||
149 | { | ||
150 | void __iomem *reg_base = musb->ctrl_base; | ||
151 | |||
152 | musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK); | ||
153 | musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG, | ||
154 | AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK); | ||
155 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
156 | musb_writel(reg_base, USB_END_OF_INTR_REG, 0); | ||
157 | } | ||
158 | |||
159 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
160 | #define portstate(stmt) stmt | ||
161 | #else | ||
162 | #define portstate(stmt) | ||
163 | #endif | ||
164 | |||
165 | static void am35x_set_vbus(struct musb *musb, int is_on) | ||
166 | { | ||
167 | WARN_ON(is_on && is_peripheral_active(musb)); | ||
168 | } | ||
169 | |||
170 | #define POLL_SECONDS 2 | ||
171 | |||
172 | static struct timer_list otg_workaround; | ||
173 | |||
174 | static void otg_timer(unsigned long _musb) | ||
175 | { | ||
176 | struct musb *musb = (void *)_musb; | ||
177 | void __iomem *mregs = musb->mregs; | ||
178 | u8 devctl; | ||
179 | unsigned long flags; | ||
180 | |||
181 | /* | ||
182 | * We poll because AM35x's won't expose several OTG-critical | ||
183 | * status change events (from the transceiver) otherwise. | ||
184 | */ | ||
185 | devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
186 | DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); | ||
187 | |||
188 | spin_lock_irqsave(&musb->lock, flags); | ||
189 | switch (musb->xceiv->state) { | ||
190 | case OTG_STATE_A_WAIT_BCON: | ||
191 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
192 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
193 | |||
194 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
195 | if (devctl & MUSB_DEVCTL_BDEVICE) { | ||
196 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
197 | MUSB_DEV_MODE(musb); | ||
198 | } else { | ||
199 | musb->xceiv->state = OTG_STATE_A_IDLE; | ||
200 | MUSB_HST_MODE(musb); | ||
201 | } | ||
202 | break; | ||
203 | case OTG_STATE_A_WAIT_VFALL: | ||
204 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
205 | musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG, | ||
206 | MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT); | ||
207 | break; | ||
208 | case OTG_STATE_B_IDLE: | ||
209 | if (!is_peripheral_enabled(musb)) | ||
210 | break; | ||
211 | |||
212 | devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
213 | if (devctl & MUSB_DEVCTL_BDEVICE) | ||
214 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
215 | else | ||
216 | musb->xceiv->state = OTG_STATE_A_IDLE; | ||
217 | break; | ||
218 | default: | ||
219 | break; | ||
220 | } | ||
221 | spin_unlock_irqrestore(&musb->lock, flags); | ||
222 | } | ||
223 | |||
224 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
225 | { | ||
226 | static unsigned long last_timer; | ||
227 | |||
228 | if (!is_otg_enabled(musb)) | ||
229 | return; | ||
230 | |||
231 | if (timeout == 0) | ||
232 | timeout = jiffies + msecs_to_jiffies(3); | ||
233 | |||
234 | /* Never idle if active, or when VBUS timeout is not set as host */ | ||
235 | if (musb->is_active || (musb->a_wait_bcon == 0 && | ||
236 | musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { | ||
237 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); | ||
238 | del_timer(&otg_workaround); | ||
239 | last_timer = jiffies; | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) { | ||
244 | DBG(4, "Longer idle timer already pending, ignoring...\n"); | ||
245 | return; | ||
246 | } | ||
247 | last_timer = timeout; | ||
248 | |||
249 | DBG(4, "%s inactive, starting idle timer for %u ms\n", | ||
250 | otg_state_string(musb), jiffies_to_msecs(timeout - jiffies)); | ||
251 | mod_timer(&otg_workaround, timeout); | ||
252 | } | ||
253 | |||
254 | static irqreturn_t am35x_interrupt(int irq, void *hci) | ||
255 | { | ||
256 | struct musb *musb = hci; | ||
257 | void __iomem *reg_base = musb->ctrl_base; | ||
258 | unsigned long flags; | ||
259 | irqreturn_t ret = IRQ_NONE; | ||
260 | u32 epintr, usbintr, lvl_intr; | ||
261 | |||
262 | spin_lock_irqsave(&musb->lock, flags); | ||
263 | |||
264 | /* Get endpoint interrupts */ | ||
265 | epintr = musb_readl(reg_base, EP_INTR_SRC_MASKED_REG); | ||
266 | |||
267 | if (epintr) { | ||
268 | musb_writel(reg_base, EP_INTR_SRC_CLEAR_REG, epintr); | ||
269 | |||
270 | musb->int_rx = | ||
271 | (epintr & AM35X_RX_INTR_MASK) >> AM35X_INTR_RX_SHIFT; | ||
272 | musb->int_tx = | ||
273 | (epintr & AM35X_TX_INTR_MASK) >> AM35X_INTR_TX_SHIFT; | ||
274 | } | ||
275 | |||
276 | /* Get usb core interrupts */ | ||
277 | usbintr = musb_readl(reg_base, CORE_INTR_SRC_MASKED_REG); | ||
278 | if (!usbintr && !epintr) | ||
279 | goto eoi; | ||
280 | |||
281 | if (usbintr) { | ||
282 | musb_writel(reg_base, CORE_INTR_SRC_CLEAR_REG, usbintr); | ||
283 | |||
284 | musb->int_usb = | ||
285 | (usbintr & AM35X_INTR_USB_MASK) >> AM35X_INTR_USB_SHIFT; | ||
286 | } | ||
287 | /* | ||
288 | * DRVVBUS IRQs are the only proxy we have (a very poor one!) for | ||
289 | * AM35x's missing ID change IRQ. We need an ID change IRQ to | ||
290 | * switch appropriately between halves of the OTG state machine. | ||
291 | * Managing DEVCTL.SESSION per Mentor docs requires that we know its | ||
292 | * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. | ||
293 | * Also, DRVVBUS pulses for SRP (but not at 5V) ... | ||
294 | */ | ||
295 | if (usbintr & (AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT)) { | ||
296 | int drvvbus = musb_readl(reg_base, USB_STAT_REG); | ||
297 | void __iomem *mregs = musb->mregs; | ||
298 | u8 devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
299 | int err; | ||
300 | |||
301 | err = is_host_enabled(musb) && (musb->int_usb & | ||
302 | MUSB_INTR_VBUSERROR); | ||
303 | if (err) { | ||
304 | /* | ||
305 | * The Mentor core doesn't debounce VBUS as needed | ||
306 | * to cope with device connect current spikes. This | ||
307 | * means it's not uncommon for bus-powered devices | ||
308 | * to get VBUS errors during enumeration. | ||
309 | * | ||
310 | * This is a workaround, but newer RTL from Mentor | ||
311 | * seems to allow a better one: "re"-starting sessions | ||
312 | * without waiting for VBUS to stop registering in | ||
313 | * devctl. | ||
314 | */ | ||
315 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; | ||
316 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | ||
317 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
318 | WARNING("VBUS error workaround (delay coming)\n"); | ||
319 | } else if (is_host_enabled(musb) && drvvbus) { | ||
320 | MUSB_HST_MODE(musb); | ||
321 | musb->xceiv->default_a = 1; | ||
322 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
323 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); | ||
324 | del_timer(&otg_workaround); | ||
325 | } else { | ||
326 | musb->is_active = 0; | ||
327 | MUSB_DEV_MODE(musb); | ||
328 | musb->xceiv->default_a = 0; | ||
329 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
330 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | ||
331 | } | ||
332 | |||
333 | /* NOTE: this must complete power-on within 100 ms. */ | ||
334 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | ||
335 | drvvbus ? "on" : "off", | ||
336 | otg_state_string(musb), | ||
337 | err ? " ERROR" : "", | ||
338 | devctl); | ||
339 | ret = IRQ_HANDLED; | ||
340 | } | ||
341 | |||
342 | if (musb->int_tx || musb->int_rx || musb->int_usb) | ||
343 | ret |= musb_interrupt(musb); | ||
344 | |||
345 | eoi: | ||
346 | /* EOI needs to be written for the IRQ to be re-asserted. */ | ||
347 | if (ret == IRQ_HANDLED || epintr || usbintr) { | ||
348 | /* clear level interrupt */ | ||
349 | lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); | ||
350 | lvl_intr |= AM35XX_USBOTGSS_INT_CLR; | ||
351 | omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR); | ||
352 | /* write EOI */ | ||
353 | musb_writel(reg_base, USB_END_OF_INTR_REG, 0); | ||
354 | } | ||
355 | |||
356 | /* Poll for ID change */ | ||
357 | if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE) | ||
358 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
359 | |||
360 | spin_unlock_irqrestore(&musb->lock, flags); | ||
361 | |||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
366 | { | ||
367 | u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | ||
368 | |||
369 | devconf2 &= ~CONF2_OTGMODE; | ||
370 | switch (musb_mode) { | ||
371 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
372 | case MUSB_HOST: /* Force VBUS valid, ID = 0 */ | ||
373 | devconf2 |= CONF2_FORCE_HOST; | ||
374 | break; | ||
375 | #endif | ||
376 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
377 | case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ | ||
378 | devconf2 |= CONF2_FORCE_DEVICE; | ||
379 | break; | ||
380 | #endif | ||
381 | #ifdef CONFIG_USB_MUSB_OTG | ||
382 | case MUSB_OTG: /* Don't override the VBUS/ID comparators */ | ||
383 | devconf2 |= CONF2_NO_OVERRIDE; | ||
384 | break; | ||
385 | #endif | ||
386 | default: | ||
387 | DBG(2, "Trying to set unsupported mode %u\n", musb_mode); | ||
388 | } | ||
389 | |||
390 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | int __init musb_platform_init(struct musb *musb, void *board_data) | ||
395 | { | ||
396 | void __iomem *reg_base = musb->ctrl_base; | ||
397 | u32 rev, lvl_intr, sw_reset; | ||
398 | int status; | ||
399 | |||
400 | musb->mregs += USB_MENTOR_CORE_OFFSET; | ||
401 | |||
402 | clk_enable(musb->clock); | ||
403 | DBG(2, "musb->clock=%lud\n", clk_get_rate(musb->clock)); | ||
404 | |||
405 | musb->phy_clock = clk_get(musb->controller, "fck"); | ||
406 | if (IS_ERR(musb->phy_clock)) { | ||
407 | status = PTR_ERR(musb->phy_clock); | ||
408 | goto exit0; | ||
409 | } | ||
410 | clk_enable(musb->phy_clock); | ||
411 | DBG(2, "musb->phy_clock=%lud\n", clk_get_rate(musb->phy_clock)); | ||
412 | |||
413 | /* Returns zero if e.g. not clocked */ | ||
414 | rev = musb_readl(reg_base, USB_REVISION_REG); | ||
415 | if (!rev) { | ||
416 | status = -ENODEV; | ||
417 | goto exit1; | ||
418 | } | ||
419 | |||
420 | usb_nop_xceiv_register(); | ||
421 | musb->xceiv = otg_get_transceiver(); | ||
422 | if (!musb->xceiv) { | ||
423 | status = -ENODEV; | ||
424 | goto exit1; | ||
425 | } | ||
426 | |||
427 | if (is_host_enabled(musb)) | ||
428 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | ||
429 | |||
430 | musb->board_set_vbus = am35x_set_vbus; | ||
431 | |||
432 | /* Global reset */ | ||
433 | sw_reset = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); | ||
434 | |||
435 | sw_reset |= AM35XX_USBOTGSS_SW_RST; | ||
436 | omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET); | ||
437 | |||
438 | sw_reset &= ~AM35XX_USBOTGSS_SW_RST; | ||
439 | omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET); | ||
440 | |||
441 | /* Reset the controller */ | ||
442 | musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); | ||
443 | |||
444 | /* Start the on-chip PHY and its PLL. */ | ||
445 | phy_on(); | ||
446 | |||
447 | msleep(5); | ||
448 | |||
449 | musb->isr = am35x_interrupt; | ||
450 | |||
451 | /* clear level interrupt */ | ||
452 | lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); | ||
453 | lvl_intr |= AM35XX_USBOTGSS_INT_CLR; | ||
454 | omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR); | ||
455 | return 0; | ||
456 | exit1: | ||
457 | clk_disable(musb->phy_clock); | ||
458 | clk_put(musb->phy_clock); | ||
459 | exit0: | ||
460 | clk_disable(musb->clock); | ||
461 | return status; | ||
462 | } | ||
463 | |||
464 | int musb_platform_exit(struct musb *musb) | ||
465 | { | ||
466 | if (is_host_enabled(musb)) | ||
467 | del_timer_sync(&otg_workaround); | ||
468 | |||
469 | phy_off(); | ||
470 | |||
471 | otg_put_transceiver(musb->xceiv); | ||
472 | usb_nop_xceiv_unregister(); | ||
473 | |||
474 | clk_disable(musb->clock); | ||
475 | |||
476 | clk_disable(musb->phy_clock); | ||
477 | clk_put(musb->phy_clock); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | #ifdef CONFIG_PM | ||
483 | void musb_platform_save_context(struct musb *musb, | ||
484 | struct musb_context_registers *musb_context) | ||
485 | { | ||
486 | phy_off(); | ||
487 | } | ||
488 | |||
489 | void musb_platform_restore_context(struct musb *musb, | ||
490 | struct musb_context_registers *musb_context) | ||
491 | { | ||
492 | phy_on(); | ||
493 | } | ||
494 | #endif | ||
495 | |||
496 | /* AM35x supports only 32bit read operation */ | ||
497 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | ||
498 | { | ||
499 | void __iomem *fifo = hw_ep->fifo; | ||
500 | u32 val; | ||
501 | int i; | ||
502 | |||
503 | /* Read for 32bit-aligned destination address */ | ||
504 | if (likely((0x03 & (unsigned long) dst) == 0) && len >= 4) { | ||
505 | readsl(fifo, dst, len >> 2); | ||
506 | dst += len & ~0x03; | ||
507 | len &= 0x03; | ||
508 | } | ||
509 | /* | ||
510 | * Now read the remaining 1 to 3 byte or complete length if | ||
511 | * unaligned address. | ||
512 | */ | ||
513 | if (len > 4) { | ||
514 | for (i = 0; i < (len >> 2); i++) { | ||
515 | *(u32 *) dst = musb_readl(fifo, 0); | ||
516 | dst += 4; | ||
517 | } | ||
518 | len &= 0x03; | ||
519 | } | ||
520 | if (len > 0) { | ||
521 | val = musb_readl(fifo, 0); | ||
522 | memcpy(dst, &val, len); | ||
523 | } | ||
524 | } | ||
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index b611420a8050..611a9d274363 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -342,8 +342,10 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
342 | 342 | ||
343 | usb_nop_xceiv_register(); | 343 | usb_nop_xceiv_register(); |
344 | musb->xceiv = otg_get_transceiver(); | 344 | musb->xceiv = otg_get_transceiver(); |
345 | if (!musb->xceiv) | 345 | if (!musb->xceiv) { |
346 | gpio_free(musb->config->gpio_vrsel); | ||
346 | return -ENODEV; | 347 | return -ENODEV; |
348 | } | ||
347 | 349 | ||
348 | if (ANOMALY_05000346) { | 350 | if (ANOMALY_05000346) { |
349 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | 351 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); |
@@ -394,8 +396,9 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
394 | 396 | ||
395 | int musb_platform_exit(struct musb *musb) | 397 | int musb_platform_exit(struct musb *musb) |
396 | { | 398 | { |
397 | |||
398 | gpio_free(musb->config->gpio_vrsel); | 399 | gpio_free(musb->config->gpio_vrsel); |
399 | 400 | ||
401 | otg_put_transceiver(musb->xceiv); | ||
402 | usb_nop_xceiv_unregister(); | ||
400 | return 0; | 403 | return 0; |
401 | } | 404 | } |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 5ab5bb89bae3..f5a65ff0ac2b 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -1156,7 +1156,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1156 | struct musb_hw_ep *hw_ep = NULL; | 1156 | struct musb_hw_ep *hw_ep = NULL; |
1157 | u32 rx, tx; | 1157 | u32 rx, tx; |
1158 | int i, index; | 1158 | int i, index; |
1159 | unsigned long flags; | 1159 | unsigned long uninitialized_var(flags); |
1160 | 1160 | ||
1161 | cppi = container_of(musb->dma_controller, struct cppi, controller); | 1161 | cppi = container_of(musb->dma_controller, struct cppi, controller); |
1162 | if (cppi->irq) | 1162 | if (cppi->irq) |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c new file mode 100644 index 000000000000..84427bebbf62 --- /dev/null +++ b/drivers/usb/musb/da8xx.c | |||
@@ -0,0 +1,469 @@ | |||
1 | /* | ||
2 | * Texas Instruments DA8xx/OMAP-L1x "glue layer" | ||
3 | * | ||
4 | * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | ||
6 | * Based on the DaVinci "glue layer" code. | ||
7 | * Copyright (C) 2005-2006 by Texas Instruments | ||
8 | * | ||
9 | * This file is part of the Inventra Controller Driver for Linux. | ||
10 | * | ||
11 | * The Inventra Controller Driver for Linux is free software; you | ||
12 | * can redistribute it and/or modify it under the terms of the GNU | ||
13 | * General Public License version 2 as published by the Free Software | ||
14 | * Foundation. | ||
15 | * | ||
16 | * The Inventra Controller Driver for Linux is distributed in | ||
17 | * the hope that it will be useful, but WITHOUT ANY WARRANTY; | ||
18 | * without even the implied warranty of MERCHANTABILITY or | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | ||
20 | * License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with The Inventra Controller Driver for Linux ; if not, | ||
24 | * write to the Free Software Foundation, Inc., 59 Temple Place, | ||
25 | * Suite 330, Boston, MA 02111-1307 USA | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/io.h> | ||
32 | |||
33 | #include <mach/da8xx.h> | ||
34 | #include <mach/usb.h> | ||
35 | |||
36 | #include "musb_core.h" | ||
37 | |||
38 | /* | ||
39 | * DA8XX specific definitions | ||
40 | */ | ||
41 | |||
42 | /* USB 2.0 OTG module registers */ | ||
43 | #define DA8XX_USB_REVISION_REG 0x00 | ||
44 | #define DA8XX_USB_CTRL_REG 0x04 | ||
45 | #define DA8XX_USB_STAT_REG 0x08 | ||
46 | #define DA8XX_USB_EMULATION_REG 0x0c | ||
47 | #define DA8XX_USB_MODE_REG 0x10 /* Transparent, CDC, [Generic] RNDIS */ | ||
48 | #define DA8XX_USB_AUTOREQ_REG 0x14 | ||
49 | #define DA8XX_USB_SRP_FIX_TIME_REG 0x18 | ||
50 | #define DA8XX_USB_TEARDOWN_REG 0x1c | ||
51 | #define DA8XX_USB_INTR_SRC_REG 0x20 | ||
52 | #define DA8XX_USB_INTR_SRC_SET_REG 0x24 | ||
53 | #define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28 | ||
54 | #define DA8XX_USB_INTR_MASK_REG 0x2c | ||
55 | #define DA8XX_USB_INTR_MASK_SET_REG 0x30 | ||
56 | #define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34 | ||
57 | #define DA8XX_USB_INTR_SRC_MASKED_REG 0x38 | ||
58 | #define DA8XX_USB_END_OF_INTR_REG 0x3c | ||
59 | #define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2)) | ||
60 | |||
61 | /* Control register bits */ | ||
62 | #define DA8XX_SOFT_RESET_MASK 1 | ||
63 | |||
64 | #define DA8XX_USB_TX_EP_MASK 0x1f /* EP0 + 4 Tx EPs */ | ||
65 | #define DA8XX_USB_RX_EP_MASK 0x1e /* 4 Rx EPs */ | ||
66 | |||
67 | /* USB interrupt register bits */ | ||
68 | #define DA8XX_INTR_USB_SHIFT 16 | ||
69 | #define DA8XX_INTR_USB_MASK (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */ | ||
70 | /* interrupts and DRVVBUS interrupt */ | ||
71 | #define DA8XX_INTR_DRVVBUS 0x100 | ||
72 | #define DA8XX_INTR_RX_SHIFT 8 | ||
73 | #define DA8XX_INTR_RX_MASK (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT) | ||
74 | #define DA8XX_INTR_TX_SHIFT 0 | ||
75 | #define DA8XX_INTR_TX_MASK (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT) | ||
76 | |||
77 | #define DA8XX_MENTOR_CORE_OFFSET 0x400 | ||
78 | |||
79 | #define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG) | ||
80 | |||
81 | /* | ||
82 | * REVISIT (PM): we should be able to keep the PHY in low power mode most | ||
83 | * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 | ||
84 | * and, when in host mode, autosuspending idle root ports... PHY_PLLON | ||
85 | * (overriding SUSPENDM?) then likely needs to stay off. | ||
86 | */ | ||
87 | |||
88 | static inline void phy_on(void) | ||
89 | { | ||
90 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | ||
91 | |||
92 | /* | ||
93 | * Start the on-chip PHY and its PLL. | ||
94 | */ | ||
95 | cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN); | ||
96 | cfgchip2 |= CFGCHIP2_PHY_PLLON; | ||
97 | __raw_writel(cfgchip2, CFGCHIP2); | ||
98 | |||
99 | pr_info("Waiting for USB PHY clock good...\n"); | ||
100 | while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD)) | ||
101 | cpu_relax(); | ||
102 | } | ||
103 | |||
104 | static inline void phy_off(void) | ||
105 | { | ||
106 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | ||
107 | |||
108 | /* | ||
109 | * Ensure that USB 1.1 reference clock is not being sourced from | ||
110 | * USB 2.0 PHY. Otherwise do not power down the PHY. | ||
111 | */ | ||
112 | if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) && | ||
113 | (cfgchip2 & CFGCHIP2_USB1SUSPENDM)) { | ||
114 | pr_warning("USB 1.1 clocked from USB 2.0 PHY -- " | ||
115 | "can't power it down\n"); | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Power down the on-chip PHY. | ||
121 | */ | ||
122 | cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN; | ||
123 | __raw_writel(cfgchip2, CFGCHIP2); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Because we don't set CTRL.UINT, it's "important" to: | ||
128 | * - not read/write INTRUSB/INTRUSBE (except during | ||
129 | * initial setup, as a workaround); | ||
130 | * - use INTSET/INTCLR instead. | ||
131 | */ | ||
132 | |||
133 | /** | ||
134 | * musb_platform_enable - enable interrupts | ||
135 | */ | ||
136 | void musb_platform_enable(struct musb *musb) | ||
137 | { | ||
138 | void __iomem *reg_base = musb->ctrl_base; | ||
139 | u32 mask; | ||
140 | |||
141 | /* Workaround: setup IRQs through both register sets. */ | ||
142 | mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) | | ||
143 | ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) | | ||
144 | DA8XX_INTR_USB_MASK; | ||
145 | musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask); | ||
146 | |||
147 | /* Force the DRVVBUS IRQ so we can start polling for ID change. */ | ||
148 | if (is_otg_enabled(musb)) | ||
149 | musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG, | ||
150 | DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT); | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * musb_platform_disable - disable HDRC and flush interrupts | ||
155 | */ | ||
156 | void musb_platform_disable(struct musb *musb) | ||
157 | { | ||
158 | void __iomem *reg_base = musb->ctrl_base; | ||
159 | |||
160 | musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG, | ||
161 | DA8XX_INTR_USB_MASK | | ||
162 | DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK); | ||
163 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
164 | musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); | ||
165 | } | ||
166 | |||
167 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
168 | #define portstate(stmt) stmt | ||
169 | #else | ||
170 | #define portstate(stmt) | ||
171 | #endif | ||
172 | |||
173 | static void da8xx_set_vbus(struct musb *musb, int is_on) | ||
174 | { | ||
175 | WARN_ON(is_on && is_peripheral_active(musb)); | ||
176 | } | ||
177 | |||
178 | #define POLL_SECONDS 2 | ||
179 | |||
180 | static struct timer_list otg_workaround; | ||
181 | |||
182 | static void otg_timer(unsigned long _musb) | ||
183 | { | ||
184 | struct musb *musb = (void *)_musb; | ||
185 | void __iomem *mregs = musb->mregs; | ||
186 | u8 devctl; | ||
187 | unsigned long flags; | ||
188 | |||
189 | /* | ||
190 | * We poll because DaVinci's won't expose several OTG-critical | ||
191 | * status change events (from the transceiver) otherwise. | ||
192 | */ | ||
193 | devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
194 | DBG(7, "Poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); | ||
195 | |||
196 | spin_lock_irqsave(&musb->lock, flags); | ||
197 | switch (musb->xceiv->state) { | ||
198 | case OTG_STATE_A_WAIT_BCON: | ||
199 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
200 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
201 | |||
202 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
203 | if (devctl & MUSB_DEVCTL_BDEVICE) { | ||
204 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
205 | MUSB_DEV_MODE(musb); | ||
206 | } else { | ||
207 | musb->xceiv->state = OTG_STATE_A_IDLE; | ||
208 | MUSB_HST_MODE(musb); | ||
209 | } | ||
210 | break; | ||
211 | case OTG_STATE_A_WAIT_VFALL: | ||
212 | /* | ||
213 | * Wait till VBUS falls below SessionEnd (~0.2 V); the 1.3 | ||
214 | * RTL seems to mis-handle session "start" otherwise (or in | ||
215 | * our case "recover"), in routine "VBUS was valid by the time | ||
216 | * VBUSERR got reported during enumeration" cases. | ||
217 | */ | ||
218 | if (devctl & MUSB_DEVCTL_VBUS) { | ||
219 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
220 | break; | ||
221 | } | ||
222 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
223 | musb_writel(musb->ctrl_base, DA8XX_USB_INTR_SRC_SET_REG, | ||
224 | MUSB_INTR_VBUSERROR << DA8XX_INTR_USB_SHIFT); | ||
225 | break; | ||
226 | case OTG_STATE_B_IDLE: | ||
227 | if (!is_peripheral_enabled(musb)) | ||
228 | break; | ||
229 | |||
230 | /* | ||
231 | * There's no ID-changed IRQ, so we have no good way to tell | ||
232 | * when to switch to the A-Default state machine (by setting | ||
233 | * the DEVCTL.Session bit). | ||
234 | * | ||
235 | * Workaround: whenever we're in B_IDLE, try setting the | ||
236 | * session flag every few seconds. If it works, ID was | ||
237 | * grounded and we're now in the A-Default state machine. | ||
238 | * | ||
239 | * NOTE: setting the session flag is _supposed_ to trigger | ||
240 | * SRP but clearly it doesn't. | ||
241 | */ | ||
242 | musb_writeb(mregs, MUSB_DEVCTL, devctl | MUSB_DEVCTL_SESSION); | ||
243 | devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
244 | if (devctl & MUSB_DEVCTL_BDEVICE) | ||
245 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
246 | else | ||
247 | musb->xceiv->state = OTG_STATE_A_IDLE; | ||
248 | break; | ||
249 | default: | ||
250 | break; | ||
251 | } | ||
252 | spin_unlock_irqrestore(&musb->lock, flags); | ||
253 | } | ||
254 | |||
255 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
256 | { | ||
257 | static unsigned long last_timer; | ||
258 | |||
259 | if (!is_otg_enabled(musb)) | ||
260 | return; | ||
261 | |||
262 | if (timeout == 0) | ||
263 | timeout = jiffies + msecs_to_jiffies(3); | ||
264 | |||
265 | /* Never idle if active, or when VBUS timeout is not set as host */ | ||
266 | if (musb->is_active || (musb->a_wait_bcon == 0 && | ||
267 | musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { | ||
268 | DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); | ||
269 | del_timer(&otg_workaround); | ||
270 | last_timer = jiffies; | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | if (time_after(last_timer, timeout) && timer_pending(&otg_workaround)) { | ||
275 | DBG(4, "Longer idle timer already pending, ignoring...\n"); | ||
276 | return; | ||
277 | } | ||
278 | last_timer = timeout; | ||
279 | |||
280 | DBG(4, "%s inactive, starting idle timer for %u ms\n", | ||
281 | otg_state_string(musb), jiffies_to_msecs(timeout - jiffies)); | ||
282 | mod_timer(&otg_workaround, timeout); | ||
283 | } | ||
284 | |||
285 | static irqreturn_t da8xx_interrupt(int irq, void *hci) | ||
286 | { | ||
287 | struct musb *musb = hci; | ||
288 | void __iomem *reg_base = musb->ctrl_base; | ||
289 | unsigned long flags; | ||
290 | irqreturn_t ret = IRQ_NONE; | ||
291 | u32 status; | ||
292 | |||
293 | spin_lock_irqsave(&musb->lock, flags); | ||
294 | |||
295 | /* | ||
296 | * NOTE: DA8XX shadows the Mentor IRQs. Don't manage them through | ||
297 | * the Mentor registers (except for setup), use the TI ones and EOI. | ||
298 | */ | ||
299 | |||
300 | /* Acknowledge and handle non-CPPI interrupts */ | ||
301 | status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG); | ||
302 | if (!status) | ||
303 | goto eoi; | ||
304 | |||
305 | musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status); | ||
306 | DBG(4, "USB IRQ %08x\n", status); | ||
307 | |||
308 | musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT; | ||
309 | musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT; | ||
310 | musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT; | ||
311 | |||
312 | /* | ||
313 | * DRVVBUS IRQs are the only proxy we have (a very poor one!) for | ||
314 | * DA8xx's missing ID change IRQ. We need an ID change IRQ to | ||
315 | * switch appropriately between halves of the OTG state machine. | ||
316 | * Managing DEVCTL.Session per Mentor docs requires that we know its | ||
317 | * value but DEVCTL.BDevice is invalid without DEVCTL.Session set. | ||
318 | * Also, DRVVBUS pulses for SRP (but not at 5 V)... | ||
319 | */ | ||
320 | if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) { | ||
321 | int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG); | ||
322 | void __iomem *mregs = musb->mregs; | ||
323 | u8 devctl = musb_readb(mregs, MUSB_DEVCTL); | ||
324 | int err; | ||
325 | |||
326 | err = is_host_enabled(musb) && (musb->int_usb & | ||
327 | MUSB_INTR_VBUSERROR); | ||
328 | if (err) { | ||
329 | /* | ||
330 | * The Mentor core doesn't debounce VBUS as needed | ||
331 | * to cope with device connect current spikes. This | ||
332 | * means it's not uncommon for bus-powered devices | ||
333 | * to get VBUS errors during enumeration. | ||
334 | * | ||
335 | * This is a workaround, but newer RTL from Mentor | ||
336 | * seems to allow a better one: "re"-starting sessions | ||
337 | * without waiting for VBUS to stop registering in | ||
338 | * devctl. | ||
339 | */ | ||
340 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; | ||
341 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | ||
342 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
343 | WARNING("VBUS error workaround (delay coming)\n"); | ||
344 | } else if (is_host_enabled(musb) && drvvbus) { | ||
345 | MUSB_HST_MODE(musb); | ||
346 | musb->xceiv->default_a = 1; | ||
347 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
348 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); | ||
349 | del_timer(&otg_workaround); | ||
350 | } else { | ||
351 | musb->is_active = 0; | ||
352 | MUSB_DEV_MODE(musb); | ||
353 | musb->xceiv->default_a = 0; | ||
354 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
355 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | ||
356 | } | ||
357 | |||
358 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | ||
359 | drvvbus ? "on" : "off", | ||
360 | otg_state_string(musb), | ||
361 | err ? " ERROR" : "", | ||
362 | devctl); | ||
363 | ret = IRQ_HANDLED; | ||
364 | } | ||
365 | |||
366 | if (musb->int_tx || musb->int_rx || musb->int_usb) | ||
367 | ret |= musb_interrupt(musb); | ||
368 | |||
369 | eoi: | ||
370 | /* EOI needs to be written for the IRQ to be re-asserted. */ | ||
371 | if (ret == IRQ_HANDLED || status) | ||
372 | musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); | ||
373 | |||
374 | /* Poll for ID change */ | ||
375 | if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE) | ||
376 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | ||
377 | |||
378 | spin_unlock_irqrestore(&musb->lock, flags); | ||
379 | |||
380 | return ret; | ||
381 | } | ||
382 | |||
383 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
384 | { | ||
385 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | ||
386 | |||
387 | cfgchip2 &= ~CFGCHIP2_OTGMODE; | ||
388 | switch (musb_mode) { | ||
389 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
390 | case MUSB_HOST: /* Force VBUS valid, ID = 0 */ | ||
391 | cfgchip2 |= CFGCHIP2_FORCE_HOST; | ||
392 | break; | ||
393 | #endif | ||
394 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
395 | case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ | ||
396 | cfgchip2 |= CFGCHIP2_FORCE_DEVICE; | ||
397 | break; | ||
398 | #endif | ||
399 | #ifdef CONFIG_USB_MUSB_OTG | ||
400 | case MUSB_OTG: /* Don't override the VBUS/ID comparators */ | ||
401 | cfgchip2 |= CFGCHIP2_NO_OVERRIDE; | ||
402 | break; | ||
403 | #endif | ||
404 | default: | ||
405 | DBG(2, "Trying to set unsupported mode %u\n", musb_mode); | ||
406 | } | ||
407 | |||
408 | __raw_writel(cfgchip2, CFGCHIP2); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | int __init musb_platform_init(struct musb *musb, void *board_data) | ||
413 | { | ||
414 | void __iomem *reg_base = musb->ctrl_base; | ||
415 | u32 rev; | ||
416 | |||
417 | musb->mregs += DA8XX_MENTOR_CORE_OFFSET; | ||
418 | |||
419 | clk_enable(musb->clock); | ||
420 | |||
421 | /* Returns zero if e.g. not clocked */ | ||
422 | rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG); | ||
423 | if (!rev) | ||
424 | goto fail; | ||
425 | |||
426 | usb_nop_xceiv_register(); | ||
427 | musb->xceiv = otg_get_transceiver(); | ||
428 | if (!musb->xceiv) | ||
429 | goto fail; | ||
430 | |||
431 | if (is_host_enabled(musb)) | ||
432 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); | ||
433 | |||
434 | musb->board_set_vbus = da8xx_set_vbus; | ||
435 | |||
436 | /* Reset the controller */ | ||
437 | musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); | ||
438 | |||
439 | /* Start the on-chip PHY and its PLL. */ | ||
440 | phy_on(); | ||
441 | |||
442 | msleep(5); | ||
443 | |||
444 | /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */ | ||
445 | pr_debug("DA8xx OTG revision %08x, PHY %03x, control %02x\n", | ||
446 | rev, __raw_readl(CFGCHIP2), | ||
447 | musb_readb(reg_base, DA8XX_USB_CTRL_REG)); | ||
448 | |||
449 | musb->isr = da8xx_interrupt; | ||
450 | return 0; | ||
451 | fail: | ||
452 | clk_disable(musb->clock); | ||
453 | return -ENODEV; | ||
454 | } | ||
455 | |||
456 | int musb_platform_exit(struct musb *musb) | ||
457 | { | ||
458 | if (is_host_enabled(musb)) | ||
459 | del_timer_sync(&otg_workaround); | ||
460 | |||
461 | phy_off(); | ||
462 | |||
463 | otg_put_transceiver(musb->xceiv); | ||
464 | usb_nop_xceiv_unregister(); | ||
465 | |||
466 | clk_disable(musb->clock); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 57624361c1de..6e67629f50cc 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -446,6 +446,7 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
446 | fail: | 446 | fail: |
447 | clk_disable(musb->clock); | 447 | clk_disable(musb->clock); |
448 | 448 | ||
449 | otg_put_transceiver(musb->xceiv); | ||
449 | usb_nop_xceiv_unregister(); | 450 | usb_nop_xceiv_unregister(); |
450 | return -ENODEV; | 451 | return -ENODEV; |
451 | } | 452 | } |
@@ -496,6 +497,7 @@ int musb_platform_exit(struct musb *musb) | |||
496 | 497 | ||
497 | clk_disable(musb->clock); | 498 | clk_disable(musb->clock); |
498 | 499 | ||
500 | otg_put_transceiver(musb->xceiv); | ||
499 | usb_nop_xceiv_unregister(); | 501 | usb_nop_xceiv_unregister(); |
500 | 502 | ||
501 | return 0; | 503 | return 0; |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 540c766c4f86..c9f9024c5515 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -272,6 +272,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
272 | } | 272 | } |
273 | } | 273 | } |
274 | 274 | ||
275 | #if !defined(CONFIG_USB_MUSB_AM35X) | ||
275 | /* | 276 | /* |
276 | * Unload an endpoint's FIFO | 277 | * Unload an endpoint's FIFO |
277 | */ | 278 | */ |
@@ -309,6 +310,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
309 | readsb(fifo, dst, len); | 310 | readsb(fifo, dst, len); |
310 | } | 311 | } |
311 | } | 312 | } |
313 | #endif | ||
312 | 314 | ||
313 | #endif /* normal PIO */ | 315 | #endif /* normal PIO */ |
314 | 316 | ||
@@ -550,6 +552,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
550 | if (int_usb & MUSB_INTR_SESSREQ) { | 552 | if (int_usb & MUSB_INTR_SESSREQ) { |
551 | void __iomem *mbase = musb->mregs; | 553 | void __iomem *mbase = musb->mregs; |
552 | 554 | ||
555 | if (devctl & MUSB_DEVCTL_BDEVICE) { | ||
556 | DBG(3, "SessReq while on B state\n"); | ||
557 | return IRQ_HANDLED; | ||
558 | } | ||
559 | |||
553 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); | 560 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); |
554 | 561 | ||
555 | /* IRQ arrives from ID pin sense or (later, if VBUS power | 562 | /* IRQ arrives from ID pin sense or (later, if VBUS power |
@@ -1921,10 +1928,6 @@ static void musb_free(struct musb *musb) | |||
1921 | dma_controller_destroy(c); | 1928 | dma_controller_destroy(c); |
1922 | } | 1929 | } |
1923 | 1930 | ||
1924 | #ifdef CONFIG_USB_MUSB_OTG | ||
1925 | put_device(musb->xceiv->dev); | ||
1926 | #endif | ||
1927 | |||
1928 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1931 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
1929 | usb_put_hcd(musb_to_hcd(musb)); | 1932 | usb_put_hcd(musb_to_hcd(musb)); |
1930 | #else | 1933 | #else |
@@ -2266,6 +2269,7 @@ void musb_save_context(struct musb *musb) | |||
2266 | { | 2269 | { |
2267 | int i; | 2270 | int i; |
2268 | void __iomem *musb_base = musb->mregs; | 2271 | void __iomem *musb_base = musb->mregs; |
2272 | void __iomem *epio; | ||
2269 | 2273 | ||
2270 | if (is_host_enabled(musb)) { | 2274 | if (is_host_enabled(musb)) { |
2271 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); | 2275 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); |
@@ -2279,16 +2283,16 @@ void musb_save_context(struct musb *musb) | |||
2279 | musb_context.index = musb_readb(musb_base, MUSB_INDEX); | 2283 | musb_context.index = musb_readb(musb_base, MUSB_INDEX); |
2280 | musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); | 2284 | musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); |
2281 | 2285 | ||
2282 | for (i = 0; i < MUSB_C_NUM_EPS; ++i) { | 2286 | for (i = 0; i < musb->config->num_eps; ++i) { |
2283 | musb_writeb(musb_base, MUSB_INDEX, i); | 2287 | epio = musb->endpoints[i].regs; |
2284 | musb_context.index_regs[i].txmaxp = | 2288 | musb_context.index_regs[i].txmaxp = |
2285 | musb_readw(musb_base, 0x10 + MUSB_TXMAXP); | 2289 | musb_readw(epio, MUSB_TXMAXP); |
2286 | musb_context.index_regs[i].txcsr = | 2290 | musb_context.index_regs[i].txcsr = |
2287 | musb_readw(musb_base, 0x10 + MUSB_TXCSR); | 2291 | musb_readw(epio, MUSB_TXCSR); |
2288 | musb_context.index_regs[i].rxmaxp = | 2292 | musb_context.index_regs[i].rxmaxp = |
2289 | musb_readw(musb_base, 0x10 + MUSB_RXMAXP); | 2293 | musb_readw(epio, MUSB_RXMAXP); |
2290 | musb_context.index_regs[i].rxcsr = | 2294 | musb_context.index_regs[i].rxcsr = |
2291 | musb_readw(musb_base, 0x10 + MUSB_RXCSR); | 2295 | musb_readw(epio, MUSB_RXCSR); |
2292 | 2296 | ||
2293 | if (musb->dyn_fifo) { | 2297 | if (musb->dyn_fifo) { |
2294 | musb_context.index_regs[i].txfifoadd = | 2298 | musb_context.index_regs[i].txfifoadd = |
@@ -2302,13 +2306,13 @@ void musb_save_context(struct musb *musb) | |||
2302 | } | 2306 | } |
2303 | if (is_host_enabled(musb)) { | 2307 | if (is_host_enabled(musb)) { |
2304 | musb_context.index_regs[i].txtype = | 2308 | musb_context.index_regs[i].txtype = |
2305 | musb_readb(musb_base, 0x10 + MUSB_TXTYPE); | 2309 | musb_readb(epio, MUSB_TXTYPE); |
2306 | musb_context.index_regs[i].txinterval = | 2310 | musb_context.index_regs[i].txinterval = |
2307 | musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL); | 2311 | musb_readb(epio, MUSB_TXINTERVAL); |
2308 | musb_context.index_regs[i].rxtype = | 2312 | musb_context.index_regs[i].rxtype = |
2309 | musb_readb(musb_base, 0x10 + MUSB_RXTYPE); | 2313 | musb_readb(epio, MUSB_RXTYPE); |
2310 | musb_context.index_regs[i].rxinterval = | 2314 | musb_context.index_regs[i].rxinterval = |
2311 | musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL); | 2315 | musb_readb(epio, MUSB_RXINTERVAL); |
2312 | 2316 | ||
2313 | musb_context.index_regs[i].txfunaddr = | 2317 | musb_context.index_regs[i].txfunaddr = |
2314 | musb_read_txfunaddr(musb_base, i); | 2318 | musb_read_txfunaddr(musb_base, i); |
@@ -2326,8 +2330,6 @@ void musb_save_context(struct musb *musb) | |||
2326 | } | 2330 | } |
2327 | } | 2331 | } |
2328 | 2332 | ||
2329 | musb_writeb(musb_base, MUSB_INDEX, musb_context.index); | ||
2330 | |||
2331 | musb_platform_save_context(musb, &musb_context); | 2333 | musb_platform_save_context(musb, &musb_context); |
2332 | } | 2334 | } |
2333 | 2335 | ||
@@ -2336,6 +2338,7 @@ void musb_restore_context(struct musb *musb) | |||
2336 | int i; | 2338 | int i; |
2337 | void __iomem *musb_base = musb->mregs; | 2339 | void __iomem *musb_base = musb->mregs; |
2338 | void __iomem *ep_target_regs; | 2340 | void __iomem *ep_target_regs; |
2341 | void __iomem *epio; | ||
2339 | 2342 | ||
2340 | musb_platform_restore_context(musb, &musb_context); | 2343 | musb_platform_restore_context(musb, &musb_context); |
2341 | 2344 | ||
@@ -2350,15 +2353,15 @@ void musb_restore_context(struct musb *musb) | |||
2350 | musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); | 2353 | musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); |
2351 | musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); | 2354 | musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); |
2352 | 2355 | ||
2353 | for (i = 0; i < MUSB_C_NUM_EPS; ++i) { | 2356 | for (i = 0; i < musb->config->num_eps; ++i) { |
2354 | musb_writeb(musb_base, MUSB_INDEX, i); | 2357 | epio = musb->endpoints[i].regs; |
2355 | musb_writew(musb_base, 0x10 + MUSB_TXMAXP, | 2358 | musb_writew(epio, MUSB_TXMAXP, |
2356 | musb_context.index_regs[i].txmaxp); | 2359 | musb_context.index_regs[i].txmaxp); |
2357 | musb_writew(musb_base, 0x10 + MUSB_TXCSR, | 2360 | musb_writew(epio, MUSB_TXCSR, |
2358 | musb_context.index_regs[i].txcsr); | 2361 | musb_context.index_regs[i].txcsr); |
2359 | musb_writew(musb_base, 0x10 + MUSB_RXMAXP, | 2362 | musb_writew(epio, MUSB_RXMAXP, |
2360 | musb_context.index_regs[i].rxmaxp); | 2363 | musb_context.index_regs[i].rxmaxp); |
2361 | musb_writew(musb_base, 0x10 + MUSB_RXCSR, | 2364 | musb_writew(epio, MUSB_RXCSR, |
2362 | musb_context.index_regs[i].rxcsr); | 2365 | musb_context.index_regs[i].rxcsr); |
2363 | 2366 | ||
2364 | if (musb->dyn_fifo) { | 2367 | if (musb->dyn_fifo) { |
@@ -2373,13 +2376,13 @@ void musb_restore_context(struct musb *musb) | |||
2373 | } | 2376 | } |
2374 | 2377 | ||
2375 | if (is_host_enabled(musb)) { | 2378 | if (is_host_enabled(musb)) { |
2376 | musb_writeb(musb_base, 0x10 + MUSB_TXTYPE, | 2379 | musb_writeb(epio, MUSB_TXTYPE, |
2377 | musb_context.index_regs[i].txtype); | 2380 | musb_context.index_regs[i].txtype); |
2378 | musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL, | 2381 | musb_writeb(epio, MUSB_TXINTERVAL, |
2379 | musb_context.index_regs[i].txinterval); | 2382 | musb_context.index_regs[i].txinterval); |
2380 | musb_writeb(musb_base, 0x10 + MUSB_RXTYPE, | 2383 | musb_writeb(epio, MUSB_RXTYPE, |
2381 | musb_context.index_regs[i].rxtype); | 2384 | musb_context.index_regs[i].rxtype); |
2382 | musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL, | 2385 | musb_writeb(epio, MUSB_RXINTERVAL, |
2383 | 2386 | ||
2384 | musb_context.index_regs[i].rxinterval); | 2387 | musb_context.index_regs[i].rxinterval); |
2385 | musb_write_txfunaddr(musb_base, i, | 2388 | musb_write_txfunaddr(musb_base, i, |
@@ -2400,8 +2403,6 @@ void musb_restore_context(struct musb *musb) | |||
2400 | musb_context.index_regs[i].rxhubport); | 2403 | musb_context.index_regs[i].rxhubport); |
2401 | } | 2404 | } |
2402 | } | 2405 | } |
2403 | |||
2404 | musb_writeb(musb_base, MUSB_INDEX, musb_context.index); | ||
2405 | } | 2406 | } |
2406 | 2407 | ||
2407 | static int musb_suspend(struct device *dev) | 2408 | static int musb_suspend(struct device *dev) |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 91d67794e350..69797e5b46a7 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -330,6 +330,7 @@ struct musb { | |||
330 | /* device lock */ | 330 | /* device lock */ |
331 | spinlock_t lock; | 331 | spinlock_t lock; |
332 | struct clk *clock; | 332 | struct clk *clock; |
333 | struct clk *phy_clock; | ||
333 | irqreturn_t (*isr)(int, void *); | 334 | irqreturn_t (*isr)(int, void *); |
334 | struct work_struct irq_work; | 335 | struct work_struct irq_work; |
335 | u16 hwvers; | 336 | u16 hwvers; |
@@ -599,6 +600,7 @@ extern void musb_hnp_stop(struct musb *musb); | |||
599 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); | 600 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); |
600 | 601 | ||
601 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ | 602 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ |
603 | defined(CONFIG_ARCH_DAVINCI_DA8XX) || \ | ||
602 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | 604 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ |
603 | defined(CONFIG_ARCH_OMAP4) | 605 | defined(CONFIG_ARCH_OMAP4) |
604 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); | 606 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); |
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index d73afdbde3ee..94f6973cf8f7 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h | |||
@@ -42,11 +42,10 @@ | |||
42 | #define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args) | 42 | #define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args) |
43 | #define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args) | 43 | #define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args) |
44 | 44 | ||
45 | #define xprintk(level, facility, format, args...) do { \ | 45 | #define DBG(level, format, args...) do { \ |
46 | if (_dbg_level(level)) { \ | 46 | if (_dbg_level(level)) \ |
47 | printk(facility "%s %d: " format , \ | 47 | pr_debug("%s %d: " format, __func__, __LINE__, ## args); \ |
48 | __func__, __LINE__ , ## args); \ | 48 | } while (0) |
49 | } } while (0) | ||
50 | 49 | ||
51 | extern unsigned musb_debug; | 50 | extern unsigned musb_debug; |
52 | 51 | ||
@@ -55,8 +54,6 @@ static inline int _dbg_level(unsigned l) | |||
55 | return musb_debug >= l; | 54 | return musb_debug >= l; |
56 | } | 55 | } |
57 | 56 | ||
58 | #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) | ||
59 | |||
60 | extern const char *otg_state_string(struct musb *); | 57 | extern const char *otg_state_string(struct musb *); |
61 | 58 | ||
62 | #ifdef CONFIG_DEBUG_FS | 59 | #ifdef CONFIG_DEBUG_FS |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d065e23f123e..5d815049cbaa 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -337,13 +337,15 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
337 | csr |= (MUSB_TXCSR_DMAENAB | | 337 | csr |= (MUSB_TXCSR_DMAENAB | |
338 | MUSB_TXCSR_MODE); | 338 | MUSB_TXCSR_MODE); |
339 | /* against programming guide */ | 339 | /* against programming guide */ |
340 | } else | 340 | } else { |
341 | csr |= (MUSB_TXCSR_AUTOSET | 341 | csr |= (MUSB_TXCSR_DMAENAB |
342 | | MUSB_TXCSR_DMAENAB | ||
343 | | MUSB_TXCSR_DMAMODE | 342 | | MUSB_TXCSR_DMAMODE |
344 | | MUSB_TXCSR_MODE); | 343 | | MUSB_TXCSR_MODE); |
345 | 344 | if (!musb_ep->hb_mult) | |
345 | csr |= MUSB_TXCSR_AUTOSET; | ||
346 | } | ||
346 | csr &= ~MUSB_TXCSR_P_UNDERRUN; | 347 | csr &= ~MUSB_TXCSR_P_UNDERRUN; |
348 | |||
347 | musb_writew(epio, MUSB_TXCSR, csr); | 349 | musb_writew(epio, MUSB_TXCSR, csr); |
348 | } | 350 | } |
349 | } | 351 | } |
@@ -475,40 +477,39 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
475 | epnum, csr, musb_ep->dma->actual_len, request); | 477 | epnum, csr, musb_ep->dma->actual_len, request); |
476 | } | 478 | } |
477 | 479 | ||
478 | if (is_dma || request->actual == request->length) { | 480 | /* |
479 | /* | 481 | * First, maybe a terminating short packet. Some DMA |
480 | * First, maybe a terminating short packet. Some DMA | 482 | * engines might handle this by themselves. |
481 | * engines might handle this by themselves. | 483 | */ |
482 | */ | 484 | if ((request->zero && request->length |
483 | if ((request->zero && request->length | 485 | && (request->length % musb_ep->packet_sz == 0) |
484 | && request->length % musb_ep->packet_sz == 0) | 486 | && (request->actual == request->length)) |
485 | #ifdef CONFIG_USB_INVENTRA_DMA | 487 | #ifdef CONFIG_USB_INVENTRA_DMA |
486 | || (is_dma && (!dma->desired_mode || | 488 | || (is_dma && (!dma->desired_mode || |
487 | (request->actual & | 489 | (request->actual & |
488 | (musb_ep->packet_sz - 1)))) | 490 | (musb_ep->packet_sz - 1)))) |
489 | #endif | 491 | #endif |
490 | ) { | 492 | ) { |
491 | /* | 493 | /* |
492 | * On DMA completion, FIFO may not be | 494 | * On DMA completion, FIFO may not be |
493 | * available yet... | 495 | * available yet... |
494 | */ | 496 | */ |
495 | if (csr & MUSB_TXCSR_TXPKTRDY) | 497 | if (csr & MUSB_TXCSR_TXPKTRDY) |
496 | return; | 498 | return; |
497 | 499 | ||
498 | DBG(4, "sending zero pkt\n"); | 500 | DBG(4, "sending zero pkt\n"); |
499 | musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE | 501 | musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE |
500 | | MUSB_TXCSR_TXPKTRDY); | 502 | | MUSB_TXCSR_TXPKTRDY); |
501 | request->zero = 0; | 503 | request->zero = 0; |
502 | } | 504 | } |
503 | 505 | ||
504 | if (request->actual == request->length) { | 506 | if (request->actual == request->length) { |
505 | musb_g_giveback(musb_ep, request, 0); | 507 | musb_g_giveback(musb_ep, request, 0); |
506 | request = musb_ep->desc ? next_request(musb_ep) : NULL; | 508 | request = musb_ep->desc ? next_request(musb_ep) : NULL; |
507 | if (!request) { | 509 | if (!request) { |
508 | DBG(4, "%s idle now\n", | 510 | DBG(4, "%s idle now\n", |
509 | musb_ep->end_point.name); | 511 | musb_ep->end_point.name); |
510 | return; | 512 | return; |
511 | } | ||
512 | } | 513 | } |
513 | } | 514 | } |
514 | 515 | ||
@@ -643,7 +644,9 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
643 | */ | 644 | */ |
644 | 645 | ||
645 | csr |= MUSB_RXCSR_DMAENAB; | 646 | csr |= MUSB_RXCSR_DMAENAB; |
646 | csr |= MUSB_RXCSR_AUTOCLEAR; | 647 | if (!musb_ep->hb_mult && |
648 | musb_ep->hw_ep->rx_double_buffered) | ||
649 | csr |= MUSB_RXCSR_AUTOCLEAR; | ||
647 | #ifdef USE_MODE1 | 650 | #ifdef USE_MODE1 |
648 | /* csr |= MUSB_RXCSR_DMAMODE; */ | 651 | /* csr |= MUSB_RXCSR_DMAMODE; */ |
649 | 652 | ||
@@ -772,7 +775,7 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
772 | musb_writew(epio, MUSB_RXCSR, csr); | 775 | musb_writew(epio, MUSB_RXCSR, csr); |
773 | 776 | ||
774 | DBG(3, "%s iso overrun on %p\n", musb_ep->name, request); | 777 | DBG(3, "%s iso overrun on %p\n", musb_ep->name, request); |
775 | if (request && request->status == -EINPROGRESS) | 778 | if (request->status == -EINPROGRESS) |
776 | request->status = -EOVERFLOW; | 779 | request->status = -EOVERFLOW; |
777 | } | 780 | } |
778 | if (csr & MUSB_RXCSR_INCOMPRX) { | 781 | if (csr & MUSB_RXCSR_INCOMPRX) { |
@@ -825,14 +828,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
825 | return; | 828 | return; |
826 | } | 829 | } |
827 | 830 | ||
828 | /* analyze request if the ep is hot */ | 831 | /* Analyze request */ |
829 | if (request) | 832 | rxstate(musb, to_musb_request(request)); |
830 | rxstate(musb, to_musb_request(request)); | ||
831 | else | ||
832 | DBG(3, "packet waiting for %s%s request\n", | ||
833 | musb_ep->desc ? "" : "inactive ", | ||
834 | musb_ep->end_point.name); | ||
835 | return; | ||
836 | } | 833 | } |
837 | 834 | ||
838 | /* ------------------------------------------------------------ */ | 835 | /* ------------------------------------------------------------ */ |
@@ -875,9 +872,25 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
875 | 872 | ||
876 | /* REVISIT this rules out high bandwidth periodic transfers */ | 873 | /* REVISIT this rules out high bandwidth periodic transfers */ |
877 | tmp = le16_to_cpu(desc->wMaxPacketSize); | 874 | tmp = le16_to_cpu(desc->wMaxPacketSize); |
878 | if (tmp & ~0x07ff) | 875 | if (tmp & ~0x07ff) { |
879 | goto fail; | 876 | int ok; |
880 | musb_ep->packet_sz = tmp; | 877 | |
878 | if (usb_endpoint_dir_in(desc)) | ||
879 | ok = musb->hb_iso_tx; | ||
880 | else | ||
881 | ok = musb->hb_iso_rx; | ||
882 | |||
883 | if (!ok) { | ||
884 | DBG(4, "%s: not support ISO high bandwidth\n", __func__); | ||
885 | goto fail; | ||
886 | } | ||
887 | musb_ep->hb_mult = (tmp >> 11) & 3; | ||
888 | } else { | ||
889 | musb_ep->hb_mult = 0; | ||
890 | } | ||
891 | |||
892 | musb_ep->packet_sz = tmp & 0x7ff; | ||
893 | tmp = musb_ep->packet_sz * (musb_ep->hb_mult + 1); | ||
881 | 894 | ||
882 | /* enable the interrupts for the endpoint, set the endpoint | 895 | /* enable the interrupts for the endpoint, set the endpoint |
883 | * packet size (or fail), set the mode, clear the fifo | 896 | * packet size (or fail), set the mode, clear the fifo |
@@ -890,8 +903,11 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
890 | musb_ep->is_in = 1; | 903 | musb_ep->is_in = 1; |
891 | if (!musb_ep->is_in) | 904 | if (!musb_ep->is_in) |
892 | goto fail; | 905 | goto fail; |
893 | if (tmp > hw_ep->max_packet_sz_tx) | 906 | |
907 | if (tmp > hw_ep->max_packet_sz_tx) { | ||
908 | DBG(4, "%s: packet size beyond hw fifo size\n", __func__); | ||
894 | goto fail; | 909 | goto fail; |
910 | } | ||
895 | 911 | ||
896 | int_txe |= (1 << epnum); | 912 | int_txe |= (1 << epnum); |
897 | musb_writew(mbase, MUSB_INTRTXE, int_txe); | 913 | musb_writew(mbase, MUSB_INTRTXE, int_txe); |
@@ -906,7 +922,7 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
906 | if (musb->hwvers < MUSB_HWVERS_2000) | 922 | if (musb->hwvers < MUSB_HWVERS_2000) |
907 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); | 923 | musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); |
908 | else | 924 | else |
909 | musb_writew(regs, MUSB_TXMAXP, tmp); | 925 | musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); |
910 | 926 | ||
911 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; | 927 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; |
912 | if (musb_readw(regs, MUSB_TXCSR) | 928 | if (musb_readw(regs, MUSB_TXCSR) |
@@ -927,8 +943,11 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
927 | musb_ep->is_in = 0; | 943 | musb_ep->is_in = 0; |
928 | if (musb_ep->is_in) | 944 | if (musb_ep->is_in) |
929 | goto fail; | 945 | goto fail; |
930 | if (tmp > hw_ep->max_packet_sz_rx) | 946 | |
947 | if (tmp > hw_ep->max_packet_sz_rx) { | ||
948 | DBG(4, "%s: packet size beyond hw fifo size\n", __func__); | ||
931 | goto fail; | 949 | goto fail; |
950 | } | ||
932 | 951 | ||
933 | int_rxe |= (1 << epnum); | 952 | int_rxe |= (1 << epnum); |
934 | musb_writew(mbase, MUSB_INTRRXE, int_rxe); | 953 | musb_writew(mbase, MUSB_INTRRXE, int_rxe); |
@@ -942,7 +961,7 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
942 | if (musb->hwvers < MUSB_HWVERS_2000) | 961 | if (musb->hwvers < MUSB_HWVERS_2000) |
943 | musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); | 962 | musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); |
944 | else | 963 | else |
945 | musb_writew(regs, MUSB_RXMAXP, tmp); | 964 | musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); |
946 | 965 | ||
947 | /* force shared fifo to OUT-only mode */ | 966 | /* force shared fifo to OUT-only mode */ |
948 | if (hw_ep->is_shared_fifo) { | 967 | if (hw_ep->is_shared_fifo) { |
@@ -1699,9 +1718,11 @@ void musb_gadget_cleanup(struct musb *musb) | |||
1699 | * -ENOMEM no memeory to perform the operation | 1718 | * -ENOMEM no memeory to perform the operation |
1700 | * | 1719 | * |
1701 | * @param driver the gadget driver | 1720 | * @param driver the gadget driver |
1721 | * @param bind the driver's bind function | ||
1702 | * @return <0 if error, 0 if everything is fine | 1722 | * @return <0 if error, 0 if everything is fine |
1703 | */ | 1723 | */ |
1704 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | 1724 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, |
1725 | int (*bind)(struct usb_gadget *)) | ||
1705 | { | 1726 | { |
1706 | int retval; | 1727 | int retval; |
1707 | unsigned long flags; | 1728 | unsigned long flags; |
@@ -1709,8 +1730,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1709 | 1730 | ||
1710 | if (!driver | 1731 | if (!driver |
1711 | || driver->speed != USB_SPEED_HIGH | 1732 | || driver->speed != USB_SPEED_HIGH |
1712 | || !driver->bind | 1733 | || !bind || !driver->setup) |
1713 | || !driver->setup) | ||
1714 | return -EINVAL; | 1734 | return -EINVAL; |
1715 | 1735 | ||
1716 | /* driver must be initialized to support peripheral mode */ | 1736 | /* driver must be initialized to support peripheral mode */ |
@@ -1738,7 +1758,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1738 | spin_unlock_irqrestore(&musb->lock, flags); | 1758 | spin_unlock_irqrestore(&musb->lock, flags); |
1739 | 1759 | ||
1740 | if (retval == 0) { | 1760 | if (retval == 0) { |
1741 | retval = driver->bind(&musb->g); | 1761 | retval = bind(&musb->g); |
1742 | if (retval != 0) { | 1762 | if (retval != 0) { |
1743 | DBG(3, "bind to driver %s failed --> %d\n", | 1763 | DBG(3, "bind to driver %s failed --> %d\n", |
1744 | driver->driver.name, retval); | 1764 | driver->driver.name, retval); |
@@ -1786,7 +1806,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1786 | 1806 | ||
1787 | return retval; | 1807 | return retval; |
1788 | } | 1808 | } |
1789 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1809 | EXPORT_SYMBOL(usb_gadget_probe_driver); |
1790 | 1810 | ||
1791 | static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | 1811 | static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) |
1792 | { | 1812 | { |
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index 572b1da7f2dc..dec8dc008191 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h | |||
@@ -79,6 +79,8 @@ struct musb_ep { | |||
79 | 79 | ||
80 | /* true if lock must be dropped but req_list may not be advanced */ | 80 | /* true if lock must be dropped but req_list may not be advanced */ |
81 | u8 busy; | 81 | u8 busy; |
82 | |||
83 | u8 hb_mult; | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | static inline struct musb_ep *to_musb_ep(struct usb_ep *ep) | 86 | static inline struct musb_ep *to_musb_ep(struct usb_ep *ep) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 9e65c47cc98b..4d5bcb4e14d2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/list.h> | 43 | #include <linux/list.h> |
44 | #include <linux/dma-mapping.h> | ||
44 | 45 | ||
45 | #include "musb_core.h" | 46 | #include "musb_core.h" |
46 | #include "musb_host.h" | 47 | #include "musb_host.h" |
@@ -1119,6 +1120,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1119 | u32 status = 0; | 1120 | u32 status = 0; |
1120 | void __iomem *mbase = musb->mregs; | 1121 | void __iomem *mbase = musb->mregs; |
1121 | struct dma_channel *dma; | 1122 | struct dma_channel *dma; |
1123 | bool transfer_pending = false; | ||
1122 | 1124 | ||
1123 | musb_ep_select(mbase, epnum); | 1125 | musb_ep_select(mbase, epnum); |
1124 | tx_csr = musb_readw(epio, MUSB_TXCSR); | 1126 | tx_csr = musb_readw(epio, MUSB_TXCSR); |
@@ -1279,7 +1281,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1279 | offset = d->offset; | 1281 | offset = d->offset; |
1280 | length = d->length; | 1282 | length = d->length; |
1281 | } | 1283 | } |
1282 | } else if (dma) { | 1284 | } else if (dma && urb->transfer_buffer_length == qh->offset) { |
1283 | done = true; | 1285 | done = true; |
1284 | } else { | 1286 | } else { |
1285 | /* see if we need to send more data, or ZLP */ | 1287 | /* see if we need to send more data, or ZLP */ |
@@ -1292,6 +1294,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1292 | if (!done) { | 1294 | if (!done) { |
1293 | offset = qh->offset; | 1295 | offset = qh->offset; |
1294 | length = urb->transfer_buffer_length - offset; | 1296 | length = urb->transfer_buffer_length - offset; |
1297 | transfer_pending = true; | ||
1295 | } | 1298 | } |
1296 | } | 1299 | } |
1297 | } | 1300 | } |
@@ -1311,7 +1314,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1311 | urb->actual_length = qh->offset; | 1314 | urb->actual_length = qh->offset; |
1312 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); | 1315 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); |
1313 | return; | 1316 | return; |
1314 | } else if (usb_pipeisoc(pipe) && dma) { | 1317 | } else if ((usb_pipeisoc(pipe) || transfer_pending) && dma) { |
1315 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, | 1318 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, |
1316 | offset, length)) { | 1319 | offset, length)) { |
1317 | if (is_cppi_enabled() || tusb_dma_omap()) | 1320 | if (is_cppi_enabled() || tusb_dma_omap()) |
@@ -1332,6 +1335,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1332 | */ | 1335 | */ |
1333 | if (length > qh->maxpacket) | 1336 | if (length > qh->maxpacket) |
1334 | length = qh->maxpacket; | 1337 | length = qh->maxpacket; |
1338 | /* Unmap the buffer so that CPU can use it */ | ||
1339 | unmap_urb_for_dma(musb_to_hcd(musb), urb); | ||
1335 | musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); | 1340 | musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); |
1336 | qh->segsize = length; | 1341 | qh->segsize = length; |
1337 | 1342 | ||
@@ -1752,6 +1757,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1752 | #endif /* Mentor DMA */ | 1757 | #endif /* Mentor DMA */ |
1753 | 1758 | ||
1754 | if (!dma) { | 1759 | if (!dma) { |
1760 | /* Unmap the buffer so that CPU can use it */ | ||
1761 | unmap_urb_for_dma(musb_to_hcd(musb), urb); | ||
1755 | done = musb_host_packet_rx(musb, urb, | 1762 | done = musb_host_packet_rx(musb, urb, |
1756 | epnum, iso_err); | 1763 | epnum, iso_err); |
1757 | DBG(6, "read %spacket\n", done ? "last " : ""); | 1764 | DBG(6, "read %spacket\n", done ? "last " : ""); |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 6dc107f25245..6f771af5cbdb 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -91,7 +91,7 @@ static struct dma_channel *dma_channel_allocate(struct dma_controller *c, | |||
91 | channel = &(musb_channel->channel); | 91 | channel = &(musb_channel->channel); |
92 | channel->private_data = musb_channel; | 92 | channel->private_data = musb_channel; |
93 | channel->status = MUSB_DMA_STATUS_FREE; | 93 | channel->status = MUSB_DMA_STATUS_FREE; |
94 | channel->max_len = 0x10000; | 94 | channel->max_len = 0x100000; |
95 | /* Tx => mode 1; Rx => mode 0 */ | 95 | /* Tx => mode 1; Rx => mode 0 */ |
96 | channel->desired_mode = transmit; | 96 | channel->desired_mode = transmit; |
97 | channel->actual_len = 0; | 97 | channel->actual_len = 0; |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2111a241dd03..ed618bde1eec 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -320,5 +320,6 @@ int musb_platform_exit(struct musb *musb) | |||
320 | 320 | ||
321 | musb_platform_suspend(musb); | 321 | musb_platform_suspend(musb); |
322 | 322 | ||
323 | otg_put_transceiver(musb->xceiv); | ||
323 | return 0; | 324 | return 0; |
324 | } | 325 | } |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 3c48e77a0aa2..bde40efc7046 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1152,6 +1152,8 @@ done: | |||
1152 | if (ret < 0) { | 1152 | if (ret < 0) { |
1153 | if (sync) | 1153 | if (sync) |
1154 | iounmap(sync); | 1154 | iounmap(sync); |
1155 | |||
1156 | otg_put_transceiver(musb->xceiv); | ||
1155 | usb_nop_xceiv_unregister(); | 1157 | usb_nop_xceiv_unregister(); |
1156 | } | 1158 | } |
1157 | return ret; | 1159 | return ret; |
@@ -1166,6 +1168,8 @@ int musb_platform_exit(struct musb *musb) | |||
1166 | musb->board_set_power(0); | 1168 | musb->board_set_power(0); |
1167 | 1169 | ||
1168 | iounmap(musb->sync_va); | 1170 | iounmap(musb->sync_va); |
1171 | |||
1172 | otg_put_transceiver(musb->xceiv); | ||
1169 | usb_nop_xceiv_unregister(); | 1173 | usb_nop_xceiv_unregister(); |
1170 | return 0; | 1174 | return 0; |
1171 | } | 1175 | } |