aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-04-04 00:44:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-04-13 19:07:07 -0400
commitf1407d5c66240b33d11a7f1a41d55ccf6a9d7647 (patch)
tree90d08090ac44e19e1e3fc0fe0073a34884b5f4c5 /drivers
parenta6360dd37e1a144ed11e6548371bade559a1e4df (diff)
usb: renesas_usbhs: Add Renesas USBHS common code
Renesas SuperH has USBHS IP which can switch Host / Function. This driver is designed so that Host / Function may dynamically change. This patch add usb/renesas_usbhs and common code for SuperH USBHS. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/renesas_usbhs/Kconfig15
-rw-r--r--drivers/usb/renesas_usbhs/Makefile7
-rw-r--r--drivers/usb/renesas_usbhs/common.c394
-rw-r--r--drivers/usb/renesas_usbhs/common.h225
-rw-r--r--drivers/usb/renesas_usbhs/mod.c261
-rw-r--r--drivers/usb/renesas_usbhs/mod.h106
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c880
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h105
10 files changed, 1996 insertions, 0 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index 3f135b6fb014..ad67b7d4c271 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_UWB) += uwb/
67obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/ 67obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/
68obj-$(CONFIG_USB) += usb/ 68obj-$(CONFIG_USB) += usb/
69obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/ 69obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
70obj-$(CONFIG_USB_RENESAS_USBHS) += usb/renesas_usbhs/
70obj-$(CONFIG_PCI) += usb/ 71obj-$(CONFIG_PCI) += usb/
71obj-$(CONFIG_USB_GADGET) += usb/gadget/ 72obj-$(CONFIG_USB_GADGET) += usb/gadget/
72obj-$(CONFIG_SERIO) += input/serio/ 73obj-$(CONFIG_SERIO) += input/serio/
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 41b6e51188e4..d299906e4f00 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -115,6 +115,8 @@ source "drivers/usb/host/Kconfig"
115 115
116source "drivers/usb/musb/Kconfig" 116source "drivers/usb/musb/Kconfig"
117 117
118source "drivers/usb/renesas_usbhs/Kconfig"
119
118source "drivers/usb/class/Kconfig" 120source "drivers/usb/class/Kconfig"
119 121
120source "drivers/usb/storage/Kconfig" 122source "drivers/usb/storage/Kconfig"
diff --git a/drivers/usb/renesas_usbhs/Kconfig b/drivers/usb/renesas_usbhs/Kconfig
new file mode 100644
index 000000000000..481490e5500a
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/Kconfig
@@ -0,0 +1,15 @@
1#
2# Renesas USB Controller Drivers
3#
4
5config USB_RENESAS_USBHS
6 tristate 'Renesas USBHS controller'
7 default n
8 help
9 Renesas USBHS is a discrete USB host and peripheral controller chip
10 that supports both full and high speed USB 2.0 data transfers.
11 It has nine or more configurable endpoints, and endpoint zero.
12
13 Say "y" to link the driver statically, or "m" to build a
14 dynamically linked module called "renesas_usbhs" and force all
15 gadget drivers to also be dynamically linked.
diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile
new file mode 100644
index 000000000000..d76f3dd3b9d1
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/Makefile
@@ -0,0 +1,7 @@
1#
2# for Renesas USB
3#
4
5obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o
6
7renesas_usbhs-y := common.o mod.o pipe.o
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
new file mode 100644
index 000000000000..d9ad60d1c156
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -0,0 +1,394 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/pm_runtime.h>
20#include <linux/slab.h>
21#include <linux/sysfs.h>
22#include "./common.h"
23
24/*
25 * platform call back
26 *
27 * renesas usb support platform callback function.
28 * Below macro call it.
29 * if platform doesn't have callback, it return 0 (no error)
30 */
31#define usbhs_platform_call(priv, func, args...)\
32 (!(priv) ? -ENODEV : \
33 !((priv)->pfunc->func) ? 0 : \
34 (priv)->pfunc->func(args))
35
36/*
37 * common functions
38 */
39u16 usbhs_read(struct usbhs_priv *priv, u32 reg)
40{
41 return ioread16(priv->base + reg);
42}
43
44void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data)
45{
46 iowrite16(data, priv->base + reg);
47}
48
49void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data)
50{
51 u16 val = usbhs_read(priv, reg);
52
53 val &= ~mask;
54 val |= data & mask;
55
56 usbhs_write(priv, reg, val);
57}
58
59/*
60 * syscfg functions
61 */
62void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
63{
64 usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
65}
66
67void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable)
68{
69 usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0);
70}
71
72void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable)
73{
74 usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0);
75}
76
77void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
78{
79 u16 mask = DCFM | DRPD | DPRPU;
80 u16 val = DCFM | DRPD;
81
82 /*
83 * if enable
84 *
85 * - select Host mode
86 * - D+ Line/D- Line Pull-down
87 */
88 usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
89}
90
91void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
92{
93 u16 mask = DCFM | DRPD | DPRPU;
94 u16 val = DPRPU;
95
96 /*
97 * if enable
98 *
99 * - select Function mode
100 * - D+ Line Pull-up
101 */
102 usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
103}
104
105/*
106 * frame functions
107 */
108int usbhs_frame_get_num(struct usbhs_priv *priv)
109{
110 return usbhs_read(priv, FRMNUM) & FRNM_MASK;
111}
112
113/*
114 * local functions
115 */
116static struct usbhs_priv *usbhsc_pdev_to_priv(struct platform_device *pdev)
117{
118 return dev_get_drvdata(&pdev->dev);
119}
120
121static void usbhsc_bus_ctrl(struct usbhs_priv *priv, int enable)
122{
123 int wait = usbhs_get_dparam(priv, buswait_bwait);
124 u16 data = 0;
125
126 if (enable) {
127 /* set bus wait if platform have */
128 if (wait)
129 usbhs_bset(priv, BUSWAIT, 0x000F, wait);
130 }
131 usbhs_write(priv, DVSTCTR, data);
132}
133
134/*
135 * platform default param
136 */
137static u32 usbhsc_default_pipe_type[] = {
138 USB_ENDPOINT_XFER_CONTROL,
139 USB_ENDPOINT_XFER_ISOC,
140 USB_ENDPOINT_XFER_ISOC,
141 USB_ENDPOINT_XFER_BULK,
142 USB_ENDPOINT_XFER_BULK,
143 USB_ENDPOINT_XFER_BULK,
144 USB_ENDPOINT_XFER_INT,
145 USB_ENDPOINT_XFER_INT,
146 USB_ENDPOINT_XFER_INT,
147 USB_ENDPOINT_XFER_INT,
148};
149
150/*
151 * driver callback functions
152 */
153static void usbhsc_notify_hotplug(struct work_struct *work)
154{
155 struct usbhs_priv *priv = container_of(work,
156 struct usbhs_priv,
157 notify_hotplug_work);
158 struct platform_device *pdev = usbhs_priv_to_pdev(priv);
159 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
160 int id;
161 int enable;
162 int ret;
163
164 /*
165 * get vbus status from platform
166 */
167 enable = usbhs_platform_call(priv, get_vbus, pdev);
168
169 /*
170 * get id from platform
171 */
172 id = usbhs_platform_call(priv, get_id, pdev);
173
174 if (enable && !mod) {
175 ret = usbhs_mod_change(priv, id);
176 if (ret < 0)
177 return;
178
179 dev_dbg(&pdev->dev, "%s enable\n", __func__);
180
181 /* enable PM */
182 pm_runtime_get_sync(&pdev->dev);
183
184 /* USB on */
185 usbhs_sys_clock_ctrl(priv, enable);
186 usbhsc_bus_ctrl(priv, enable);
187
188 /* module start */
189 usbhs_mod_call(priv, start, priv);
190
191 } else if (!enable && mod) {
192 dev_dbg(&pdev->dev, "%s disable\n", __func__);
193
194 /* module stop */
195 usbhs_mod_call(priv, stop, priv);
196
197 /* USB off */
198 usbhsc_bus_ctrl(priv, enable);
199 usbhs_sys_clock_ctrl(priv, enable);
200
201 /* disable PM */
202 pm_runtime_put_sync(&pdev->dev);
203
204 usbhs_mod_change(priv, -1);
205
206 /* reset phy for next connection */
207 usbhs_platform_call(priv, phy_reset, pdev);
208 }
209}
210
211static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
212{
213 struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev);
214
215 /*
216 * This functions will be called in interrupt.
217 * To make sure safety context,
218 * use workqueue for usbhs_notify_hotplug
219 */
220 schedule_work(&priv->notify_hotplug_work);
221 return 0;
222}
223
224/*
225 * platform functions
226 */
227static int __devinit usbhs_probe(struct platform_device *pdev)
228{
229 struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;
230 struct renesas_usbhs_driver_callback *dfunc;
231 struct usbhs_priv *priv;
232 struct resource *res;
233 unsigned int irq;
234 int ret;
235
236 /* check platform information */
237 if (!info ||
238 !info->platform_callback.get_id ||
239 !info->platform_callback.get_vbus) {
240 dev_err(&pdev->dev, "no platform information\n");
241 return -EINVAL;
242 }
243
244 /* platform data */
245 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
246 irq = platform_get_irq(pdev, 0);
247 if (!res || (int)irq <= 0) {
248 dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n");
249 return -ENODEV;
250 }
251
252 /* usb private data */
253 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
254 if (!priv) {
255 dev_err(&pdev->dev, "Could not allocate priv\n");
256 return -ENOMEM;
257 }
258
259 priv->base = ioremap_nocache(res->start, resource_size(res));
260 if (!priv->base) {
261 dev_err(&pdev->dev, "ioremap error.\n");
262 ret = -ENOMEM;
263 goto probe_end_kfree;
264 }
265
266 /*
267 * care platform info
268 */
269 priv->pfunc = &info->platform_callback;
270 priv->dparam = &info->driver_param;
271
272 /* set driver callback functions for platform */
273 dfunc = &info->driver_callback;
274 dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug;
275
276 /* set default param if platform doesn't have */
277 if (!priv->dparam->pipe_type) {
278 priv->dparam->pipe_type = usbhsc_default_pipe_type;
279 priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type);
280 }
281
282 /*
283 * priv settings
284 */
285 priv->irq = irq;
286 priv->pdev = pdev;
287 INIT_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
288 spin_lock_init(usbhs_priv_to_lock(priv));
289
290 /* call pipe and module init */
291 ret = usbhs_pipe_probe(priv);
292 if (ret < 0)
293 goto probe_end_mod_exit;
294
295 ret = usbhs_mod_probe(priv);
296 if (ret < 0)
297 goto probe_end_iounmap;
298
299 /* dev_set_drvdata should be called after usbhs_mod_init */
300 dev_set_drvdata(&pdev->dev, priv);
301
302 /*
303 * deviece reset here because
304 * USB device might be used in boot loader.
305 */
306 usbhs_sys_clock_ctrl(priv, 0);
307
308 /*
309 * platform call
310 *
311 * USB phy setup might depend on CPU/Board.
312 * If platform has its callback functions,
313 * call it here.
314 */
315 ret = usbhs_platform_call(priv, hardware_init, pdev);
316 if (ret < 0) {
317 dev_err(&pdev->dev, "platform prove failed.\n");
318 goto probe_end_pipe_exit;
319 }
320
321 /* reset phy for connection */
322 usbhs_platform_call(priv, phy_reset, pdev);
323
324 /*
325 * manual call notify_hotplug for cold plug
326 */
327 pm_runtime_enable(&pdev->dev);
328 ret = usbhsc_drvcllbck_notify_hotplug(pdev);
329 if (ret < 0)
330 goto probe_end_call_remove;
331
332 dev_info(&pdev->dev, "probed\n");
333
334 return ret;
335
336probe_end_call_remove:
337 usbhs_platform_call(priv, hardware_exit, pdev);
338probe_end_pipe_exit:
339 usbhs_pipe_remove(priv);
340probe_end_mod_exit:
341 usbhs_mod_remove(priv);
342probe_end_iounmap:
343 iounmap(priv->base);
344probe_end_kfree:
345 kfree(priv);
346
347 dev_info(&pdev->dev, "probe failed\n");
348
349 return ret;
350}
351
352static int __devexit usbhs_remove(struct platform_device *pdev)
353{
354 struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev);
355
356 dev_dbg(&pdev->dev, "usb remove\n");
357
358 pm_runtime_disable(&pdev->dev);
359
360 usbhsc_bus_ctrl(priv, 0);
361
362 usbhs_platform_call(priv, hardware_exit, pdev);
363 usbhs_pipe_remove(priv);
364 usbhs_mod_remove(priv);
365 iounmap(priv->base);
366 kfree(priv);
367
368 return 0;
369}
370
371static struct platform_driver renesas_usbhs_driver = {
372 .driver = {
373 .name = "renesas_usbhs",
374 },
375 .probe = usbhs_probe,
376 .remove = __devexit_p(usbhs_remove),
377};
378
379static int __init usbhs_init(void)
380{
381 return platform_driver_register(&renesas_usbhs_driver);
382}
383
384static void __exit usbhs_exit(void)
385{
386 platform_driver_unregister(&renesas_usbhs_driver);
387}
388
389module_init(usbhs_init);
390module_exit(usbhs_exit);
391
392MODULE_LICENSE("GPL");
393MODULE_DESCRIPTION("Renesas USB driver");
394MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
new file mode 100644
index 000000000000..f1a2b62f93f9
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -0,0 +1,225 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#ifndef RENESAS_USB_DRIVER_H
18#define RENESAS_USB_DRIVER_H
19
20#include <linux/platform_device.h>
21#include <linux/usb/renesas_usbhs.h>
22
23struct usbhs_priv;
24
25#include "./mod.h"
26#include "./pipe.h"
27
28/*
29 *
30 * register define
31 *
32 */
33#define SYSCFG 0x0000
34#define BUSWAIT 0x0002
35#define DVSTCTR 0x0008
36#define CFIFO 0x0014
37#define CFIFOSEL 0x0020
38#define CFIFOCTR 0x0022
39#define INTENB0 0x0030
40#define INTENB1 0x0032
41#define BRDYENB 0x0036
42#define NRDYENB 0x0038
43#define BEMPENB 0x003A
44#define INTSTS0 0x0040
45#define INTSTS1 0x0042
46#define BRDYSTS 0x0046
47#define NRDYSTS 0x0048
48#define BEMPSTS 0x004A
49#define FRMNUM 0x004C
50#define USBREQ 0x0054 /* USB request type register */
51#define USBVAL 0x0056 /* USB request value register */
52#define USBINDX 0x0058 /* USB request index register */
53#define USBLENG 0x005A /* USB request length register */
54#define DCPCFG 0x005C
55#define DCPMAXP 0x005E
56#define DCPCTR 0x0060
57#define PIPESEL 0x0064
58#define PIPECFG 0x0068
59#define PIPEBUF 0x006A
60#define PIPEMAXP 0x006C
61#define PIPEPERI 0x006E
62#define PIPEnCTR 0x0070
63
64/* SYSCFG */
65#define SCKE (1 << 10) /* USB Module Clock Enable */
66#define HSE (1 << 7) /* High-Speed Operation Enable */
67#define DCFM (1 << 6) /* Controller Function Select */
68#define DRPD (1 << 5) /* D+ Line/D- Line Resistance Control */
69#define DPRPU (1 << 4) /* D+ Line Resistance Control */
70#define USBE (1 << 0) /* USB Module Operation Enable */
71
72/* DVSTCTR */
73#define EXTLP (1 << 10) /* Controls the EXTLP pin output state */
74#define PWEN (1 << 9) /* Controls the PWEN pin output state */
75#define RHST (0x7) /* Reset Handshake */
76#define RHST_LOW_SPEED 1 /* Low-speed connection */
77#define RHST_FULL_SPEED 2 /* Full-speed connection */
78#define RHST_HIGH_SPEED 3 /* High-speed connection */
79
80/* CFIFOSEL */
81#define MBW_32 (0x2 << 10) /* CFIFO Port Access Bit Width */
82
83/* CFIFOCTR */
84#define BVAL (1 << 15) /* Buffer Memory Enable Flag */
85#define BCLR (1 << 14) /* CPU buffer clear */
86#define FRDY (1 << 13) /* FIFO Port Ready */
87#define DTLN_MASK (0x0FFF) /* Receive Data Length */
88
89/* INTENB0 */
90#define VBSE (1 << 15) /* Enable IRQ VBUS_0 and VBUSIN_0 */
91#define RSME (1 << 14) /* Enable IRQ Resume */
92#define SOFE (1 << 13) /* Enable IRQ Frame Number Update */
93#define DVSE (1 << 12) /* Enable IRQ Device State Transition */
94#define CTRE (1 << 11) /* Enable IRQ Control Stage Transition */
95#define BEMPE (1 << 10) /* Enable IRQ Buffer Empty */
96#define NRDYE (1 << 9) /* Enable IRQ Buffer Not Ready Response */
97#define BRDYE (1 << 8) /* Enable IRQ Buffer Ready */
98
99/* INTENB1 */
100#define BCHGE (1 << 14) /* USB Bus Change Interrupt Enable */
101#define DTCHE (1 << 12) /* Disconnection Detect Interrupt Enable */
102#define ATTCHE (1 << 11) /* Connection Detect Interrupt Enable */
103#define EOFERRE (1 << 6) /* EOF Error Detect Interrupt Enable */
104#define SIGNE (1 << 5) /* Setup Transaction Error Interrupt Enable */
105#define SACKE (1 << 4) /* Setup Transaction ACK Interrupt Enable */
106
107/* INTSTS0 */
108#define DVST (1 << 12) /* Device State Transition Interrupt Status */
109#define CTRT (1 << 11) /* Control Stage Interrupt Status */
110#define BEMP (1 << 10) /* Buffer Empty Interrupt Status */
111#define BRDY (1 << 8) /* Buffer Ready Interrupt Status */
112#define VBSTS (1 << 7) /* VBUS_0 and VBUSIN_0 Input Status */
113#define VALID (1 << 3) /* USB Request Receive */
114
115#define DVSQ_MASK (0x3 << 4) /* Device State */
116#define POWER_STATE (0 << 4)
117#define DEFAULT_STATE (1 << 4)
118#define ADDRESS_STATE (2 << 4)
119#define CONFIGURATION_STATE (3 << 4)
120
121#define CTSQ_MASK (0x7) /* Control Transfer Stage */
122#define IDLE_SETUP_STAGE 0 /* Idle stage or setup stage */
123#define READ_DATA_STAGE 1 /* Control read data stage */
124#define READ_STATUS_STAGE 2 /* Control read status stage */
125#define WRITE_DATA_STAGE 3 /* Control write data stage */
126#define WRITE_STATUS_STAGE 4 /* Control write status stage */
127#define NODATA_STATUS_STAGE 5 /* Control write NoData status stage */
128#define SEQUENCE_ERROR 6 /* Control transfer sequence error */
129
130/* PIPECFG */
131/* DCPCFG */
132#define TYPE_NONE (0 << 14) /* Transfer Type */
133#define TYPE_BULK (1 << 14)
134#define TYPE_INT (2 << 14)
135#define TYPE_ISO (3 << 14)
136#define DBLB (1 << 9) /* Double Buffer Mode */
137#define SHTNAK (1 << 7) /* Pipe Disable in Transfer End */
138#define DIR_OUT (1 << 4) /* Transfer Direction */
139
140/* PIPEMAXP */
141/* DCPMAXP */
142#define DEVSEL_MASK (0xF << 12) /* Device Select */
143#define DCP_MAXP_MASK (0x7F)
144#define PIPE_MAXP_MASK (0x7FF)
145
146/* PIPEBUF */
147#define BUFSIZE_SHIFT 10
148#define BUFSIZE_MASK (0x1F << BUFSIZE_SHIFT)
149#define BUFNMB_MASK (0xFF)
150
151/* PIPEnCTR */
152/* DCPCTR */
153#define BSTS (1 << 15) /* Buffer Status */
154#define CSSTS (1 << 12) /* CSSTS Status */
155#define SQCLR (1 << 8) /* Toggle Bit Clear */
156#define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */
157#define PBUSY (1 << 5) /* Pipe Busy */
158#define PID_MASK (0x3) /* Response PID */
159#define PID_NAK 0
160#define PID_BUF 1
161#define PID_STALL10 2
162#define PID_STALL11 3
163
164#define CCPL (1 << 2) /* Control Transfer End Enable */
165
166/* FRMNUM */
167#define FRNM_MASK (0x7FF)
168
169/*
170 * struct
171 */
172struct usbhs_priv {
173
174 void __iomem *base;
175 unsigned int irq;
176
177 struct renesas_usbhs_platform_callback *pfunc;
178 struct renesas_usbhs_driver_param *dparam;
179
180 struct work_struct notify_hotplug_work;
181 struct platform_device *pdev;
182
183 spinlock_t lock;
184
185 /*
186 * module control
187 */
188 struct usbhs_mod_info mod_info;
189
190 /*
191 * pipe control
192 */
193 struct usbhs_pipe_info pipe_info;
194};
195
196/*
197 * common
198 */
199u16 usbhs_read(struct usbhs_priv *priv, u32 reg);
200void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data);
201void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data);
202
203/*
204 * sysconfig
205 */
206void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable);
207void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable);
208void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable);
209void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable);
210void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable);
211
212/*
213 * frame
214 */
215int usbhs_frame_get_num(struct usbhs_priv *priv);
216
217/*
218 * data
219 */
220#define usbhs_get_dparam(priv, param) (priv->dparam->param)
221#define usbhs_priv_to_pdev(priv) (priv->pdev)
222#define usbhs_priv_to_dev(priv) (&priv->pdev->dev)
223#define usbhs_priv_to_lock(priv) (&priv->lock)
224
225#endif /* RENESAS_USB_DRIVER_H */
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c
new file mode 100644
index 000000000000..4a3398484cd7
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/mod.c
@@ -0,0 +1,261 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#include <linux/interrupt.h>
18
19#include "./common.h"
20#include "./mod.h"
21
22#define usbhs_priv_to_modinfo(priv) (&priv->mod_info)
23
24/*
25 * host / gadget functions
26 *
27 * renesas_usbhs host/gadget can register itself by below functions.
28 * these functions are called when probe
29 *
30 */
31void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *mod, int id)
32{
33 struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
34
35 info->mod[id] = mod;
36 mod->priv = priv;
37}
38
39struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id)
40{
41 struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
42 struct usbhs_mod *ret = NULL;
43
44 switch (id) {
45 case USBHS_HOST:
46 case USBHS_GADGET:
47 ret = info->mod[id];
48 break;
49 }
50
51 return ret;
52}
53
54int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod)
55{
56 struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
57
58 if (!mod)
59 return -EINVAL;
60
61 return info->mod[USBHS_HOST] == mod;
62}
63
64struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv)
65{
66 struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
67
68 return info->curt;
69}
70
71int usbhs_mod_change(struct usbhs_priv *priv, int id)
72{
73 struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv);
74 struct usbhs_mod *mod = NULL;
75 int ret = 0;
76
77 /* id < 0 mean no current */
78 switch (id) {
79 case USBHS_HOST:
80 case USBHS_GADGET:
81 mod = info->mod[id];
82 break;
83 default:
84 ret = -EINVAL;
85 }
86 info->curt = mod;
87
88 return ret;
89}
90
91static irqreturn_t usbhs_interrupt(int irq, void *data);
92int usbhs_mod_probe(struct usbhs_priv *priv)
93{
94 struct device *dev = usbhs_priv_to_dev(priv);
95 int ret;
96
97 /* irq settings */
98 ret = request_irq(priv->irq, usbhs_interrupt,
99 IRQF_DISABLED, dev_name(dev), priv);
100 if (ret)
101 dev_err(dev, "irq request err\n");
102
103 return ret;
104}
105
106void usbhs_mod_remove(struct usbhs_priv *priv)
107{
108 free_irq(priv->irq, priv);
109}
110
111/*
112 * status functions
113 */
114int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state)
115{
116 switch (irq_state->dvstctr & RHST) {
117 case RHST_LOW_SPEED:
118 return USB_SPEED_LOW;
119 case RHST_FULL_SPEED:
120 return USB_SPEED_FULL;
121 case RHST_HIGH_SPEED:
122 return USB_SPEED_HIGH;
123 }
124
125 return USB_SPEED_UNKNOWN;
126}
127
128int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state)
129{
130 int state = irq_state->intsts0 & DVSQ_MASK;
131
132 switch (state) {
133 case POWER_STATE:
134 case DEFAULT_STATE:
135 case ADDRESS_STATE:
136 case CONFIGURATION_STATE:
137 return state;
138 }
139
140 return -EIO;
141}
142
143int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state)
144{
145 /*
146 * return value
147 *
148 * IDLE_SETUP_STAGE
149 * READ_DATA_STAGE
150 * READ_STATUS_STAGE
151 * WRITE_DATA_STAGE
152 * WRITE_STATUS_STAGE
153 * NODATA_STATUS_STAGE
154 * SEQUENCE_ERROR
155 */
156 return (int)irq_state->intsts0 & CTSQ_MASK;
157}
158
159static void usbhs_status_get_each_irq(struct usbhs_priv *priv,
160 struct usbhs_irq_state *state)
161{
162 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
163
164 state->intsts0 = usbhs_read(priv, INTSTS0);
165 state->intsts1 = usbhs_read(priv, INTSTS1);
166
167 state->brdysts = usbhs_read(priv, BRDYSTS);
168 state->nrdysts = usbhs_read(priv, NRDYSTS);
169 state->bempsts = usbhs_read(priv, BEMPSTS);
170
171 state->dvstctr = usbhs_read(priv, DVSTCTR);
172
173 /* mask */
174 state->bempsts &= mod->irq_bempsts;
175 state->brdysts &= mod->irq_brdysts;
176}
177
178/*
179 * interrupt
180 */
181#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */
182#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */
183static irqreturn_t usbhs_interrupt(int irq, void *data)
184{
185 struct usbhs_priv *priv = data;
186 struct usbhs_irq_state irq_state;
187
188 usbhs_status_get_each_irq(priv, &irq_state);
189
190 /*
191 * clear interrupt
192 *
193 * The hardware is _very_ picky to clear interrupt bit.
194 * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value.
195 *
196 * see
197 * "Operation"
198 * - "Control Transfer (DCP)"
199 * - Function :: VALID bit should 0
200 */
201 usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
202 usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
203
204 usbhs_write(priv, BRDYSTS, 0);
205 usbhs_write(priv, NRDYSTS, 0);
206 usbhs_write(priv, BEMPSTS, 0);
207
208 /*
209 * call irq callback functions
210 * see also
211 * usbhs_irq_setting_update
212 */
213 if (irq_state.intsts0 & DVST)
214 usbhs_mod_call(priv, irq_dev_state, priv, &irq_state);
215
216 if (irq_state.intsts0 & CTRT)
217 usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state);
218
219 if (irq_state.intsts0 & BEMP)
220 usbhs_mod_call(priv, irq_empty, priv, &irq_state);
221
222 if (irq_state.intsts0 & BRDY)
223 usbhs_mod_call(priv, irq_ready, priv, &irq_state);
224
225 return IRQ_HANDLED;
226}
227
228void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod)
229{
230 u16 intenb0 = 0;
231
232 usbhs_write(priv, INTENB0, 0);
233
234 usbhs_write(priv, BEMPENB, 0);
235 usbhs_write(priv, BRDYENB, 0);
236
237 /*
238 * see also
239 * usbhs_interrupt
240 */
241
242 /*
243 * it don't enable DVSE (intenb0) here
244 * but "mod->irq_dev_state" will be called.
245 */
246
247 if (mod->irq_ctrl_stage)
248 intenb0 |= CTRE;
249
250 if (mod->irq_empty && mod->irq_bempsts) {
251 usbhs_write(priv, BEMPENB, mod->irq_bempsts);
252 intenb0 |= BEMPE;
253 }
254
255 if (mod->irq_ready && mod->irq_brdysts) {
256 usbhs_write(priv, BRDYENB, mod->irq_brdysts);
257 intenb0 |= BRDYE;
258 }
259
260 usbhs_write(priv, INTENB0, intenb0);
261}
diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h
new file mode 100644
index 000000000000..bd873d5b432a
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/mod.h
@@ -0,0 +1,106 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#ifndef RENESAS_USB_MOD_H
18#define RENESAS_USB_MOD_H
19
20#include <linux/spinlock.h>
21#include <linux/usb/renesas_usbhs.h>
22#include "./common.h"
23
24/*
25 * struct
26 */
27struct usbhs_irq_state {
28 u16 intsts0;
29 u16 intsts1;
30 u16 brdysts;
31 u16 nrdysts;
32 u16 bempsts;
33 u16 dvstctr;
34};
35
36struct usbhs_mod {
37 char *name;
38
39 /*
40 * entry point from common.c
41 */
42 int (*start)(struct usbhs_priv *priv);
43 int (*stop)(struct usbhs_priv *priv);
44
45 /* INTSTS0 :: DVST (DVSQ) */
46 int (*irq_dev_state)(struct usbhs_priv *priv,
47 struct usbhs_irq_state *irq_state);
48
49 /* INTSTS0 :: CTRT (CTSQ) */
50 int (*irq_ctrl_stage)(struct usbhs_priv *priv,
51 struct usbhs_irq_state *irq_state);
52
53 /* INTSTS0 :: BEMP */
54 /* BEMPSTS */
55 int (*irq_empty)(struct usbhs_priv *priv,
56 struct usbhs_irq_state *irq_state);
57 u16 irq_bempsts;
58
59 /* INTSTS0 :: BRDY */
60 /* BRDYSTS */
61 int (*irq_ready)(struct usbhs_priv *priv,
62 struct usbhs_irq_state *irq_state);
63 u16 irq_brdysts;
64
65 struct usbhs_priv *priv;
66};
67
68struct usbhs_mod_info {
69 struct usbhs_mod *mod[USBHS_MAX];
70 struct usbhs_mod *curt; /* current mod */
71};
72
73/*
74 * for host/gadget module
75 */
76struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id);
77struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv);
78void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id);
79int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod);
80int usbhs_mod_change(struct usbhs_priv *priv, int id);
81int usbhs_mod_probe(struct usbhs_priv *priv);
82void usbhs_mod_remove(struct usbhs_priv *priv);
83
84/*
85 * status functions
86 */
87int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state);
88int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state);
89int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state);
90
91/*
92 * callback functions
93 */
94void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod);
95
96
97#define usbhs_mod_call(priv, func, param...) \
98 ({ \
99 struct usbhs_mod *mod; \
100 mod = usbhs_mod_get_current(priv); \
101 !mod ? -ENODEV : \
102 !mod->func ? 0 : \
103 mod->func(param); \
104 })
105
106#endif /* RENESAS_USB_MOD_H */
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
new file mode 100644
index 000000000000..b7a9137f599b
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -0,0 +1,880 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/slab.h>
20#include "./common.h"
21#include "./pipe.h"
22
23/*
24 * macros
25 */
26#define usbhsp_priv_to_pipeinfo(pr) (&(pr)->pipe_info)
27#define usbhsp_pipe_to_priv(p) ((p)->priv)
28
29#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
30
31#define usbhsp_is_dcp(p) ((p)->priv->pipe_info.pipe == (p))
32
33#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
34#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
35#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
36#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0)
37
38#define usbhsp_type(p) ((p)->pipe_type)
39#define usbhsp_type_is(p, t) ((p)->pipe_type == t)
40
41/*
42 * for debug
43 */
44static char *usbhsp_pipe_name[] = {
45 [USB_ENDPOINT_XFER_CONTROL] = "DCP",
46 [USB_ENDPOINT_XFER_BULK] = "BULK",
47 [USB_ENDPOINT_XFER_INT] = "INT",
48 [USB_ENDPOINT_XFER_ISOC] = "ISO",
49};
50
51/*
52 * usb request functions
53 */
54void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
55{
56 u16 val;
57
58 val = usbhs_read(priv, USBREQ);
59 req->bRequest = (val >> 8) & 0xFF;
60 req->bRequestType = (val >> 0) & 0xFF;
61
62 req->wValue = usbhs_read(priv, USBVAL);
63 req->wIndex = usbhs_read(priv, USBINDX);
64 req->wLength = usbhs_read(priv, USBLENG);
65}
66
67void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
68{
69 usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType);
70 usbhs_write(priv, USBVAL, req->wValue);
71 usbhs_write(priv, USBINDX, req->wIndex);
72 usbhs_write(priv, USBLENG, req->wLength);
73}
74
75/*
76 * DCPCTR/PIPEnCTR functions
77 */
78static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
79{
80 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
81 int offset = usbhsp_addr_offset(pipe);
82
83 if (usbhsp_is_dcp(pipe))
84 usbhs_bset(priv, DCPCTR, mask, val);
85 else
86 usbhs_bset(priv, PIPEnCTR + offset, mask, val);
87}
88
89static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
90{
91 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
92 int offset = usbhsp_addr_offset(pipe);
93
94 if (usbhsp_is_dcp(pipe))
95 return usbhs_read(priv, DCPCTR);
96 else
97 return usbhs_read(priv, PIPEnCTR + offset);
98}
99
100/*
101 * DCP/PIPE functions
102 */
103static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
104 u16 dcp_reg, u16 pipe_reg,
105 u16 mask, u16 val)
106{
107 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
108
109 if (usbhsp_is_dcp(pipe))
110 usbhs_bset(priv, dcp_reg, mask, val);
111 else
112 usbhs_bset(priv, pipe_reg, mask, val);
113}
114
115static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
116 u16 dcp_reg, u16 pipe_reg)
117{
118 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
119
120 if (usbhsp_is_dcp(pipe))
121 return usbhs_read(priv, dcp_reg);
122 else
123 return usbhs_read(priv, pipe_reg);
124}
125
126/*
127 * DCPCFG/PIPECFG functions
128 */
129static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
130{
131 __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
132}
133
134/*
135 * PIPEBUF
136 */
137static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
138{
139 if (usbhsp_is_dcp(pipe))
140 return;
141
142 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
143}
144
145/*
146 * DCPMAXP/PIPEMAXP
147 */
148static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
149{
150 __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
151}
152
153static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe)
154{
155 return __usbhsp_pipe_xxx_get(pipe, DCPMAXP, PIPEMAXP);
156}
157
158/*
159 * pipe control functions
160 */
161static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
162{
163 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
164
165 /*
166 * On pipe, this is necessary before
167 * accesses to below registers.
168 *
169 * PIPESEL : usbhsp_pipe_select
170 * PIPECFG : usbhsp_pipe_cfg_xxx
171 * PIPEBUF : usbhsp_pipe_buf_xxx
172 * PIPEMAXP : usbhsp_pipe_maxp_xxx
173 * PIPEPERI
174 */
175
176 /*
177 * if pipe is dcp, no pipe is selected.
178 * it is no problem, because dcp have its register
179 */
180 usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
181}
182
183static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
184{
185 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
186 struct device *dev = usbhs_priv_to_dev(priv);
187 int timeout = 1024;
188 u16 val;
189
190 /*
191 * make sure....
192 *
193 * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
194 * specified by the CURPIPE bits.
195 * When changing the setting of this bit after changing
196 * the PID bits for the selected pipe from BUF to NAK,
197 * check that CSSTS = 0 and PBUSY = 0.
198 */
199
200 /*
201 * CURPIPE bit = 0
202 *
203 * see also
204 * "Operation"
205 * - "Pipe Control"
206 * - "Pipe Control Registers Switching Procedure"
207 */
208 usbhs_write(priv, CFIFOSEL, 0);
209
210 do {
211 val = usbhsp_pipectrl_get(pipe);
212 val &= CSSTS | PID_MASK;
213 if (!val)
214 return 0;
215
216 udelay(10);
217
218 } while (timeout--);
219
220 /*
221 * force NAK
222 */
223 timeout = 1024;
224 usbhs_fifo_disable(pipe);
225 do {
226 val = usbhsp_pipectrl_get(pipe);
227 val &= PBUSY;
228 if (!val)
229 return 0;
230
231 } while (timeout--);
232
233 dev_err(dev, "pipe barrier failed\n");
234
235 return -EBUSY;
236}
237
238static int usbhsp_pipe_is_accessible(struct usbhs_pipe *pipe)
239{
240 u16 val;
241
242 val = usbhsp_pipectrl_get(pipe);
243 if (val & BSTS)
244 return 0;
245
246 return -EBUSY;
247}
248
249/*
250 * PID ctrl
251 */
252static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
253{
254 u16 pid = usbhsp_pipectrl_get(pipe);
255
256 pid &= PID_MASK;
257
258 /*
259 * see
260 * "Pipe n Control Register" - "PID"
261 */
262 switch (pid) {
263 case PID_STALL11:
264 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
265 /* fall-through */
266 case PID_STALL10:
267 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
268 }
269}
270
271void usbhs_fifo_disable(struct usbhs_pipe *pipe)
272{
273 /* see "Pipe n Control Register" - "PID" */
274 __usbhsp_pid_try_nak_if_stall(pipe);
275
276 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
277}
278
279void usbhs_fifo_enable(struct usbhs_pipe *pipe)
280{
281 /* see "Pipe n Control Register" - "PID" */
282 __usbhsp_pid_try_nak_if_stall(pipe);
283
284 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
285}
286
287void usbhs_fifo_stall(struct usbhs_pipe *pipe)
288{
289 u16 pid = usbhsp_pipectrl_get(pipe);
290
291 pid &= PID_MASK;
292
293 /*
294 * see
295 * "Pipe n Control Register" - "PID"
296 */
297 switch (pid) {
298 case PID_NAK:
299 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
300 break;
301 case PID_BUF:
302 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
303 break;
304 }
305}
306
307/*
308 * CFIFO ctrl
309 */
310void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe)
311{
312 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
313
314 usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
315}
316
317static void usbhsp_fifo_clear(struct usbhs_pipe *pipe)
318{
319 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
320
321 usbhs_write(priv, CFIFOCTR, BCLR);
322}
323
324static int usbhsp_fifo_barrier(struct usbhs_priv *priv)
325{
326 int timeout = 1024;
327
328 do {
329 /* The FIFO port is accessible */
330 if (usbhs_read(priv, CFIFOCTR) & FRDY)
331 return 0;
332
333 udelay(10);
334 } while (timeout--);
335
336 return -EBUSY;
337}
338
339static int usbhsp_fifo_rcv_len(struct usbhs_priv *priv)
340{
341 return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
342}
343
344static int usbhsp_fifo_select(struct usbhs_pipe *pipe, int write)
345{
346 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
347 struct device *dev = usbhs_priv_to_dev(priv);
348 int timeout = 1024;
349 u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */
350 u16 base = usbhs_pipe_number(pipe); /* CURPIPE */
351
352 if (usbhsp_is_dcp(pipe))
353 base |= (1 == write) << 5; /* ISEL */
354
355 /* "base" will be used below */
356 usbhs_write(priv, CFIFOSEL, base | MBW_32);
357
358 /* check ISEL and CURPIPE value */
359 while (timeout--) {
360 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
361 return 0;
362 udelay(10);
363 }
364
365 dev_err(dev, "fifo select error\n");
366
367 return -EIO;
368}
369
370int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
371{
372 int ret;
373
374 ret = usbhsp_fifo_select(pipe, 1);
375 if (ret < 0)
376 return ret;
377
378 usbhsp_fifo_clear(pipe);
379
380 return ret;
381}
382
383int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
384{
385 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
386 void __iomem *addr = priv->base + CFIFO;
387 int maxp = usbhs_pipe_get_maxpacket(pipe);
388 int total_len;
389 int i, ret;
390
391 ret = usbhsp_pipe_is_accessible(pipe);
392 if (ret < 0)
393 return ret;
394
395 ret = usbhs_fifo_prepare_write(pipe);
396 if (ret < 0)
397 return ret;
398
399 ret = usbhsp_fifo_barrier(priv);
400 if (ret < 0)
401 return ret;
402
403 len = min(len, maxp);
404 total_len = len;
405
406 /*
407 * FIXME
408 *
409 * 32-bit access only
410 */
411 if (len >= 4 &&
412 !((unsigned long)buf & 0x03)) {
413 iowrite32_rep(addr, buf, len / 4);
414 len %= 4;
415 buf += total_len - len;
416 }
417
418 /* the rest operation */
419 for (i = 0; i < len; i++)
420 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
421
422 if (total_len < maxp)
423 usbhs_fifo_send_terminator(pipe);
424
425 return total_len;
426}
427
428int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
429{
430 int ret;
431
432 /*
433 * select pipe and enable it to prepare packet receive
434 */
435 ret = usbhsp_fifo_select(pipe, 0);
436 if (ret < 0)
437 return ret;
438
439 usbhs_fifo_enable(pipe);
440
441 return ret;
442}
443
444int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
445{
446 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
447 void __iomem *addr = priv->base + CFIFO;
448 int rcv_len;
449 int i, ret;
450 int total_len;
451 u32 data = 0;
452
453 ret = usbhsp_fifo_select(pipe, 0);
454 if (ret < 0)
455 return ret;
456
457 ret = usbhsp_fifo_barrier(priv);
458 if (ret < 0)
459 return ret;
460
461 rcv_len = usbhsp_fifo_rcv_len(priv);
462
463 /*
464 * Buffer clear if Zero-Length packet
465 *
466 * see
467 * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
468 */
469 if (0 == rcv_len) {
470 usbhsp_fifo_clear(pipe);
471 return 0;
472 }
473
474 len = min(rcv_len, len);
475 total_len = len;
476
477 /*
478 * FIXME
479 *
480 * 32-bit access only
481 */
482 if (len >= 4 &&
483 !((unsigned long)buf & 0x03)) {
484 ioread32_rep(addr, buf, len / 4);
485 len %= 4;
486 buf += rcv_len - len;
487 }
488
489 /* the rest operation */
490 for (i = 0; i < len; i++) {
491 if (!(i & 0x03))
492 data = ioread32(addr);
493
494 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
495 }
496
497 return total_len;
498}
499
500/*
501 * pipe setup
502 */
503static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
504{
505 /*
506 * only ISO / BULK pipe can use double buffer
507 */
508 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) ||
509 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
510 return 1;
511
512 return 0;
513}
514
515static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
516 const struct usb_endpoint_descriptor *desc,
517 int is_host)
518{
519 u16 type = 0;
520 u16 bfre = 0;
521 u16 dblb = 0;
522 u16 cntmd = 0;
523 u16 dir = 0;
524 u16 epnum = 0;
525 u16 shtnak = 0;
526 u16 type_array[] = {
527 [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
528 [USB_ENDPOINT_XFER_INT] = TYPE_INT,
529 [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
530 };
531 int is_double = usbhsp_possible_double_buffer(pipe);
532
533 if (usbhsp_is_dcp(pipe))
534 return -EINVAL;
535
536 /*
537 * PIPECFG
538 *
539 * see
540 * - "Register Descriptions" - "PIPECFG" register
541 * - "Features" - "Pipe configuration"
542 * - "Operation" - "Pipe Control"
543 */
544
545 /* TYPE */
546 type = type_array[usbhsp_type(pipe)];
547
548 /* BFRE */
549 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
550 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK))
551 bfre = 0; /* FIXME */
552
553 /* DBLB */
554 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
555 usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK))
556 dblb = (is_double) ? DBLB : 0;
557
558 /* CNTMD */
559 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK))
560 cntmd = 0; /* FIXME */
561
562 /* DIR */
563 if (usb_endpoint_dir_in(desc))
564 usbhsp_flags_set(pipe, IS_DIR_IN);
565
566 if ((is_host && usb_endpoint_dir_out(desc)) ||
567 (!is_host && usb_endpoint_dir_in(desc)))
568 dir |= DIR_OUT;
569
570 /* SHTNAK */
571 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
572 !dir)
573 shtnak = SHTNAK;
574
575 /* EPNUM */
576 epnum = 0xF & usb_endpoint_num(desc);
577
578 return type |
579 bfre |
580 dblb |
581 cntmd |
582 dir |
583 shtnak |
584 epnum;
585}
586
587static u16 usbhsp_setup_pipemaxp(struct usbhs_pipe *pipe,
588 const struct usb_endpoint_descriptor *desc,
589 int is_host)
590{
591 /* host should set DEVSEL */
592
593 /* reutn MXPS */
594 return PIPE_MAXP_MASK & le16_to_cpu(desc->wMaxPacketSize);
595}
596
597static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
598 const struct usb_endpoint_descriptor *desc,
599 int is_host)
600{
601 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
602 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv);
603 struct device *dev = usbhs_priv_to_dev(priv);
604 int pipe_num = usbhs_pipe_number(pipe);
605 int is_double = usbhsp_possible_double_buffer(pipe);
606 u16 buff_size;
607 u16 bufnmb;
608 u16 bufnmb_cnt;
609
610 /*
611 * PIPEBUF
612 *
613 * see
614 * - "Register Descriptions" - "PIPEBUF" register
615 * - "Features" - "Pipe configuration"
616 * - "Operation" - "FIFO Buffer Memory"
617 * - "Operation" - "Pipe Control"
618 *
619 * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724)
620 *
621 * BUFNMB: PIPE
622 * 0: pipe0 (DCP 256byte)
623 * 1: -
624 * 2: -
625 * 3: -
626 * 4: pipe6 (INT 64byte)
627 * 5: pipe7 (INT 64byte)
628 * 6: pipe8 (INT 64byte)
629 * 7: pipe9 (INT 64byte)
630 * 8 - xx: free (for BULK, ISOC)
631 */
632
633 /*
634 * FIXME
635 *
636 * it doesn't have good buffer allocator
637 *
638 * DCP : 256 byte
639 * BULK: 512 byte
640 * INT : 64 byte
641 * ISOC: 512 byte
642 */
643 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_CONTROL))
644 buff_size = 256;
645 else if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT))
646 buff_size = 64;
647 else
648 buff_size = 512;
649
650 /* change buff_size to register value */
651 bufnmb_cnt = (buff_size / 64) - 1;
652
653 /* BUFNMB has been reserved for INT pipe
654 * see above */
655 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) {
656 bufnmb = pipe_num - 2;
657 } else {
658 bufnmb = info->bufnmb_last;
659 info->bufnmb_last += bufnmb_cnt + 1;
660
661 /*
662 * double buffer
663 */
664 if (is_double)
665 info->bufnmb_last += bufnmb_cnt + 1;
666 }
667
668 dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
669 pipe_num, buff_size, bufnmb);
670
671 return (0x1f & bufnmb_cnt) << 10 |
672 (0xff & bufnmb) << 0;
673}
674
675/*
676 * pipe control
677 */
678int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
679{
680 u16 mask = usbhsp_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK;
681
682 usbhsp_pipe_select(pipe);
683
684 return (int)(usbhsp_pipe_maxp_get(pipe) & mask);
685}
686
687int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
688{
689 return usbhsp_flags_has(pipe, IS_DIR_IN);
690}
691
692void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe)
693{
694 usbhsp_pipectrl_set(pipe, SQCLR, SQCLR);
695}
696
697static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
698{
699 struct usbhs_pipe *pos, *pipe;
700 int i;
701
702 /*
703 * find target pipe
704 */
705 pipe = NULL;
706 usbhs_for_each_pipe_with_dcp(pos, priv, i) {
707 if (!usbhsp_type_is(pos, type))
708 continue;
709 if (usbhsp_flags_has(pos, IS_USED))
710 continue;
711
712 pipe = pos;
713 break;
714 }
715
716 if (!pipe)
717 return NULL;
718
719 /*
720 * initialize pipe flags
721 */
722 usbhsp_flags_init(pipe);
723 usbhsp_flags_set(pipe, IS_USED);
724
725 return pipe;
726}
727
728void usbhs_pipe_init(struct usbhs_priv *priv)
729{
730 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv);
731 struct usbhs_pipe *pipe;
732 int i;
733
734 /*
735 * FIXME
736 *
737 * driver needs good allocator.
738 *
739 * find first free buffer area (BULK, ISOC)
740 * (DCP, INT area is fixed)
741 *
742 * buffer number 0 - 3 have been reserved for DCP
743 * see
744 * usbhsp_to_bufnmb
745 */
746 info->bufnmb_last = 4;
747 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
748 if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT))
749 info->bufnmb_last++;
750
751 usbhsp_flags_init(pipe);
752 pipe->mod_private = NULL;
753 }
754}
755
756struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
757 const struct usb_endpoint_descriptor *desc)
758{
759 struct device *dev = usbhs_priv_to_dev(priv);
760 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
761 struct usbhs_pipe *pipe;
762 int is_host = usbhs_mod_is_host(priv, mod);
763 int ret;
764 u16 pipecfg, pipebuf, pipemaxp;
765
766 pipe = usbhsp_get_pipe(priv, usb_endpoint_type(desc));
767 if (!pipe)
768 return NULL;
769
770 usbhs_fifo_disable(pipe);
771
772 /* make sure pipe is not busy */
773 ret = usbhsp_pipe_barrier(pipe);
774 if (ret < 0) {
775 dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
776 return NULL;
777 }
778
779 pipecfg = usbhsp_setup_pipecfg(pipe, desc, is_host);
780 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host);
781 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host);
782
783 /* buffer clear
784 * see PIPECFG :: BFRE */
785 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
786 usbhsp_pipectrl_set(pipe, ACLRM, 0);
787
788 usbhsp_pipe_select(pipe);
789 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
790 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
791 usbhsp_pipe_maxp_set(pipe, 0xFFFF, pipemaxp);
792
793 usbhs_pipe_clear_sequence(pipe);
794
795 dev_dbg(dev, "enable pipe %d : %s (%s)\n",
796 usbhs_pipe_number(pipe),
797 usbhsp_pipe_name[usb_endpoint_type(desc)],
798 usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
799
800 return pipe;
801}
802
803/*
804 * dcp control
805 */
806struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
807{
808 struct usbhs_pipe *pipe;
809
810 pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
811 if (!pipe)
812 return NULL;
813
814 /*
815 * dcpcfg : default
816 * dcpmaxp : default
817 * pipebuf : nothing to do
818 */
819
820 usbhsp_pipe_select(pipe);
821 usbhs_pipe_clear_sequence(pipe);
822
823 return pipe;
824}
825
826void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
827{
828 WARN_ON(!usbhsp_is_dcp(pipe));
829
830 usbhs_fifo_enable(pipe);
831 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
832}
833
834
835/*
836 * pipe module function
837 */
838int usbhs_pipe_probe(struct usbhs_priv *priv)
839{
840 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv);
841 struct usbhs_pipe *pipe;
842 struct device *dev = usbhs_priv_to_dev(priv);
843 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
844 int pipe_size = usbhs_get_dparam(priv, pipe_size);
845 int i;
846
847 /* This driver expects 1st pipe is DCP */
848 if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) {
849 dev_err(dev, "1st PIPE is not DCP\n");
850 return -EINVAL;
851 }
852
853 info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL);
854 if (!info->pipe) {
855 dev_err(dev, "Could not allocate pipe\n");
856 return -ENOMEM;
857 }
858
859 info->size = pipe_size;
860
861 /*
862 * init pipe
863 */
864 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
865 pipe->priv = priv;
866 usbhsp_type(pipe) = pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK;
867
868 dev_dbg(dev, "pipe %x\t: %s\n",
869 i, usbhsp_pipe_name[pipe_type[i]]);
870 }
871
872 return 0;
873}
874
875void usbhs_pipe_remove(struct usbhs_priv *priv)
876{
877 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv);
878
879 kfree(info->pipe);
880}
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
new file mode 100644
index 000000000000..4a60dcef9676
--- /dev/null
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -0,0 +1,105 @@
1/*
2 * Renesas USB driver
3 *
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 */
17#ifndef RENESAS_USB_PIPE_H
18#define RENESAS_USB_PIPE_H
19
20#include "./common.h"
21
22/*
23 * struct
24 */
25struct usbhs_pipe {
26 u32 pipe_type; /* USB_ENDPOINT_XFER_xxx */
27
28 struct usbhs_priv *priv;
29
30 u32 flags;
31#define USBHS_PIPE_FLAGS_IS_USED (1 << 0)
32#define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1)
33
34 void *mod_private;
35};
36
37struct usbhs_pipe_info {
38 struct usbhs_pipe *pipe;
39 int size; /* array size of "pipe" */
40 int bufnmb_last; /* FIXME : driver needs good allocator */
41};
42
43/*
44 * pipe list
45 */
46#define __usbhs_for_each_pipe(start, pos, info, i) \
47 for (i = start, pos = (info)->pipe; \
48 i < (info)->size; \
49 i++, pos = (info)->pipe + i)
50
51#define usbhs_for_each_pipe(pos, priv, i) \
52 __usbhs_for_each_pipe(1, pos, &((priv)->pipe_info), i)
53
54#define usbhs_for_each_pipe_with_dcp(pos, priv, i) \
55 __usbhs_for_each_pipe(0, pos, &((priv)->pipe_info), i)
56
57/*
58 * pipe module probe / remove
59 */
60int usbhs_pipe_probe(struct usbhs_priv *priv);
61void usbhs_pipe_remove(struct usbhs_priv *priv);
62
63/*
64 * cfifo
65 */
66int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len);
67int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len);
68int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe);
69int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe);
70
71void usbhs_fifo_enable(struct usbhs_pipe *pipe);
72void usbhs_fifo_disable(struct usbhs_pipe *pipe);
73void usbhs_fifo_stall(struct usbhs_pipe *pipe);
74
75void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe);
76
77
78/*
79 * usb request
80 */
81void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req);
82void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req);
83
84/*
85 * pipe control
86 */
87struct usbhs_pipe
88*usbhs_pipe_malloc(struct usbhs_priv *priv,
89 const struct usb_endpoint_descriptor *desc);
90
91int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
92void usbhs_pipe_init(struct usbhs_priv *priv);
93int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
94void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe);
95
96#define usbhs_pipe_number(p) (((u32)(p) - (u32)(p)->priv->pipe_info.pipe) / \
97 sizeof(struct usbhs_pipe))
98
99/*
100 * dcp control
101 */
102struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv);
103void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe);
104
105#endif /* RENESAS_USB_PIPE_H */