blob: 2e0450be436fe43b70cecef3ad07620bfbf27547 [file] [log] [blame]
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
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 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <linux/ioport.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/types.h>
Ido Shayevitzef72ddd2012-03-28 18:55:55 +020023#include <linux/delay.h>
24#include <linux/of.h>
Ido Shayevitz9fb83452012-04-01 17:45:58 +030025#include <linux/list.h>
26#include <linux/usb/ch9.h>
27#include <linux/usb/gadget.h>
28#include <linux/usb/msm_hsusb.h>
Manu Gautam60e01352012-05-29 09:00:34 +053029#include <linux/regulator/consumer.h>
30
31#include <mach/rpm-regulator.h>
Ido Shayevitz9fb83452012-04-01 17:45:58 +030032
33#include "core.h"
34#include "gadget.h"
35
36/**
37 * USB DBM Hardware registers.
38 *
39 */
40#define DBM_EP_CFG(n) (0x00 + 4 * (n))
41#define DBM_DATA_FIFO(n) (0x10 + 4 * (n))
42#define DBM_DATA_FIFO_SIZE(n) (0x20 + 4 * (n))
43#define DBM_DATA_FIFO_EN (0x30)
44#define DBM_GEVNTADR (0x34)
45#define DBM_GEVNTSIZ (0x38)
46#define DBM_DBG_CNFG (0x3C)
47#define DBM_HW_TRB0_EP(n) (0x40 + 4 * (n))
48#define DBM_HW_TRB1_EP(n) (0x50 + 4 * (n))
49#define DBM_HW_TRB2_EP(n) (0x60 + 4 * (n))
50#define DBM_HW_TRB3_EP(n) (0x70 + 4 * (n))
51#define DBM_PIPE_CFG (0x80)
52#define DBM_SOFT_RESET (0x84)
53
54/**
55 * USB DBM Hardware registers bitmask.
56 *
57 */
58/* DBM_EP_CFG */
59#define DBM_EN_EP 0x00000000
60#define DBM_USB3_EP_NUM 0x0000003E
61#define DBM_BAM_PIPE_NUM 0x000000C0
62#define DBM_PRODUCER 0x00000100
63#define DBM_DISABLE_WB 0x00000200
64#define DBM_INT_RAM_ACC 0x00000400
65
66/* DBM_DATA_FIFO_SIZE */
67#define DBM_DATA_FIFO_SIZE_MASK 0x0000ffff
68
69/* DBM_GEVNTSIZ */
70#define DBM_GEVNTSIZ_MASK 0x0000ffff
71
72/* DBM_DBG_CNFG */
73#define DBM_ENABLE_IOC_MASK 0x0000000f
74
75/* DBM_SOFT_RESET */
76#define DBM_SFT_RST_EP0 0x00000001
77#define DBM_SFT_RST_EP1 0x00000002
78#define DBM_SFT_RST_EP2 0x00000004
79#define DBM_SFT_RST_EP3 0x00000008
80#define DBM_SFT_RST_EPS 0x0000000F
81#define DBM_SFT_RST 0x80000000
Ido Shayevitzef72ddd2012-03-28 18:55:55 +020082
83#define DBM_MAX_EPS 4
84
Ido Shayevitzfa65a582012-06-06 14:39:54 +030085/* DBM TRB configurations */
86#define DBM_TRB_BIT 0x80000000
87#define DBM_TRB_DATA_SRC 0x40000000
88#define DBM_TRB_DMA 0x20000000
89#define DBM_TRB_EP_NUM(ep) (ep<<24)
90
Ido Shayevitz9fb83452012-04-01 17:45:58 +030091struct dwc3_msm_req_complete {
92 struct list_head list_item;
93 struct usb_request *req;
94 void (*orig_complete)(struct usb_ep *ep,
95 struct usb_request *req);
96};
97
Ido Shayevitzef72ddd2012-03-28 18:55:55 +020098struct dwc3_msm {
99 struct platform_device *dwc3;
100 struct device *dev;
101 void __iomem *base;
102 u32 resource_size;
103 int dbm_num_eps;
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300104 u8 ep_num_mapping[DBM_MAX_EPS];
105 const struct usb_ep_ops *original_ep_ops[DWC3_ENDPOINTS_NUM];
106 struct list_head req_complete_list;
Manu Gautam60e01352012-05-29 09:00:34 +0530107 struct regulator *hsusb_3p3;
108 struct regulator *hsusb_1p8;
109 struct regulator *hsusb_vddcx;
110 struct regulator *ssusb_1p8;
111 struct regulator *ssusb_vddcx;
112 enum usb_vdd_type ss_vdd_type;
113 enum usb_vdd_type hs_vdd_type;
114};
115
116#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
117#define USB_HSPHY_3P3_VOL_MAX 3300000 /* uV */
118#define USB_HSPHY_3P3_HPM_LOAD 16000 /* uA */
119
120#define USB_HSPHY_1P8_VOL_MIN 1800000 /* uV */
121#define USB_HSPHY_1P8_VOL_MAX 1800000 /* uV */
122#define USB_HSPHY_1P8_HPM_LOAD 19000 /* uA */
123
124#define USB_SSPHY_1P8_VOL_MIN 1800000 /* uV */
125#define USB_SSPHY_1P8_VOL_MAX 1800000 /* uV */
126#define USB_SSPHY_1P8_HPM_LOAD 23000 /* uA */
127
128#define USB_PHY_VDD_DIG_VOL_NONE 0 /* uV */
129#define USB_PHY_VDD_DIG_VOL_MIN 1045000 /* uV */
130#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
131
132enum usb_vdd_value {
133 VDD_NONE = 0,
134 VDD_MIN,
135 VDD_MAX,
136 VDD_VAL_MAX,
137};
138
139static const int vdd_val[VDD_TYPE_MAX][VDD_VAL_MAX] = {
140 { /* VDD_CX CORNER Voting */
141 [VDD_NONE] = RPM_VREG_CORNER_NONE,
142 [VDD_MIN] = RPM_VREG_CORNER_NOMINAL,
143 [VDD_MAX] = RPM_VREG_CORNER_HIGH,
144 },
145 { /* VDD_CX Voltage Voting */
146 [VDD_NONE] = USB_PHY_VDD_DIG_VOL_NONE,
147 [VDD_MIN] = USB_PHY_VDD_DIG_VOL_MIN,
148 [VDD_MAX] = USB_PHY_VDD_DIG_VOL_MAX,
149 },
Ido Shayevitzef72ddd2012-03-28 18:55:55 +0200150};
151
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300152static struct dwc3_msm *context;
Ido Shayevitzc9e92e92012-05-30 14:36:35 +0300153static u64 dwc3_msm_dma_mask = DMA_BIT_MASK(64);
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300154
155/**
156 *
157 * Read register with debug info.
158 *
159 * @base - DWC3 base virtual address.
160 * @offset - register offset.
161 *
162 * @return u32
163 */
164static inline u32 dwc3_msm_read_reg(void *base, u32 offset)
165{
166 u32 val = ioread32(base + offset);
167 return val;
168}
169
170/**
171 * Read register masked field with debug info.
172 *
173 * @base - DWC3 base virtual address.
174 * @offset - register offset.
175 * @mask - register bitmask.
176 *
177 * @return u32
178 */
179static inline u32 dwc3_msm_read_reg_field(void *base,
180 u32 offset,
181 const u32 mask)
182{
183 u32 shift = find_first_bit((void *)&mask, 32);
184 u32 val = ioread32(base + offset);
185 val &= mask; /* clear other bits */
186 val >>= shift;
187 return val;
188}
189
190/**
191 *
192 * Write register with debug info.
193 *
194 * @base - DWC3 base virtual address.
195 * @offset - register offset.
196 * @val - value to write.
197 *
198 */
199static inline void dwc3_msm_write_reg(void *base, u32 offset, u32 val)
200{
201 iowrite32(val, base + offset);
202}
203
204/**
205 * Write register masked field with debug info.
206 *
207 * @base - DWC3 base virtual address.
208 * @offset - register offset.
209 * @mask - register bitmask.
210 * @val - value to write.
211 *
212 */
213static inline void dwc3_msm_write_reg_field(void *base, u32 offset,
214 const u32 mask, u32 val)
215{
216 u32 shift = find_first_bit((void *)&mask, 32);
217 u32 tmp = ioread32(base + offset);
218
219 tmp &= ~mask; /* clear written bits */
220 val = tmp | (val << shift);
221 iowrite32(val, base + offset);
222}
223
224/**
225 * Return DBM EP number which is not already configured.
226 *
227 */
228static int dwc3_msm_find_avail_dbm_ep(void)
229{
230 int i;
231
232 for (i = 0; i < context->dbm_num_eps; i++)
233 if (!context->ep_num_mapping[i])
234 return i;
235
236 return -ENODEV; /* Not found */
237}
238
239/**
240 * Return DBM EP number according to usb endpoint number.
241 *
242 */
243static int dwc3_msm_find_matching_dbm_ep(u8 usb_ep)
244{
245 int i;
246
247 for (i = 0; i < context->dbm_num_eps; i++)
248 if (context->ep_num_mapping[i] == usb_ep)
249 return i;
250
251 return -ENODEV; /* Not found */
252}
253
254/**
255 * Return number of configured DBM endpoints.
256 *
257 */
258static int dwc3_msm_configured_dbm_ep_num(void)
259{
260 int i;
261 int count = 0;
262
263 for (i = 0; i < context->dbm_num_eps; i++)
264 if (context->ep_num_mapping[i])
265 count++;
266
267 return count;
268}
269
270/**
271 * Configure the DBM with the USB3 core event buffer.
272 * This function is called by the SNPS UDC upon initialization.
273 *
274 * @addr - address of the event buffer.
275 * @size - size of the event buffer.
276 *
277 */
278static int dwc3_msm_event_buffer_config(u32 addr, u16 size)
279{
280 dev_dbg(context->dev, "%s\n", __func__);
281
282 dwc3_msm_write_reg(context->base, DBM_GEVNTADR, addr);
283 dwc3_msm_write_reg_field(context->base, DBM_GEVNTSIZ,
284 DBM_GEVNTSIZ_MASK, size);
285
286 return 0;
287}
288
289/**
290 * Reset the DBM registers upon initialization.
291 *
292 */
293static int dwc3_msm_dbm_soft_reset(void)
294{
295 dev_dbg(context->dev, "%s\n", __func__);
296
297 dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
298 DBM_SFT_RST, 1);
299
300 return 0;
301}
302
303/**
304 * Soft reset specific DBM ep.
305 * This function is called by the function driver upon events
306 * such as transfer aborting, USB re-enumeration and USB
307 * disconnection.
308 *
309 * @dbm_ep - DBM ep number.
310 * @enter_reset - should we enter a reset state or get out of it.
311 *
312 */
313static int dwc3_msm_dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset)
314{
315 dev_dbg(context->dev, "%s\n", __func__);
316
317 if (dbm_ep >= context->dbm_num_eps) {
318 dev_err(context->dev,
319 "%s: Invalid DBM ep index\n", __func__);
320 return -ENODEV;
321 }
322
323 if (enter_reset) {
324 dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
325 DBM_SFT_RST_EPS, 1 << dbm_ep);
326 } else {
327 dwc3_msm_write_reg_field(context->base, DBM_SOFT_RESET,
328 DBM_SFT_RST_EPS, 0);
329 }
330
331 return 0;
332}
333
334/**
335 * Configure a USB DBM ep to work in BAM mode.
336 *
337 *
338 * @usb_ep - USB physical EP number.
339 * @producer - producer/consumer.
340 * @disable_wb - disable write back to system memory.
341 * @internal_mem - use internal USB memory for data fifo.
342 * @ioc - enable interrupt on completion.
343 *
344 * @return int - DBM ep number.
345 */
346static int dwc3_msm_dbm_ep_config(u8 usb_ep, u8 bam_pipe,
347 bool producer, bool disable_wb,
348 bool internal_mem, bool ioc)
349{
350 u8 dbm_ep;
351 u8 ioc_mask;
352
353 dev_dbg(context->dev, "%s\n", __func__);
354
355 dbm_ep = dwc3_msm_find_avail_dbm_ep();
356 if (dbm_ep < 0) {
357 dev_err(context->dev, "%s: No more DBM eps\n", __func__);
358 return -ENODEV;
359 }
360
361 context->ep_num_mapping[dbm_ep] = usb_ep;
362
363 /* First, reset the dbm endpoint */
364 dwc3_msm_dbm_ep_soft_reset(dbm_ep, false);
365
366 ioc_mask = dwc3_msm_read_reg_field(context->base, DBM_DBG_CNFG,
367 DBM_ENABLE_IOC_MASK);
368 ioc_mask &= ~(ioc << dbm_ep); /* Clear ioc bit for dbm_ep */
369 /* Set ioc bit for dbm_ep if needed */
370 dwc3_msm_write_reg_field(context->base, DBM_DBG_CNFG,
371 DBM_ENABLE_IOC_MASK, ioc_mask | (ioc << dbm_ep));
372
373 dwc3_msm_write_reg(context->base, DBM_EP_CFG(dbm_ep),
374 producer | disable_wb | internal_mem);
375 dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
376 DBM_USB3_EP_NUM, usb_ep);
377 dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
378 DBM_BAM_PIPE_NUM, bam_pipe);
379 dwc3_msm_write_reg_field(context->base, DBM_EP_CFG(dbm_ep),
380 DBM_EN_EP, 1);
381
382 return dbm_ep;
383}
384
385/**
386 * Configure a USB DBM ep to work in normal mode.
387 *
388 * @usb_ep - USB ep number.
389 *
390 */
391static int dwc3_msm_dbm_ep_unconfig(u8 usb_ep)
392{
393 u8 dbm_ep;
394
395 dev_dbg(context->dev, "%s\n", __func__);
396
397 dbm_ep = dwc3_msm_find_matching_dbm_ep(usb_ep);
398
399 if (dbm_ep < 0) {
400 dev_err(context->dev,
401 "%s: Invalid usb ep index\n", __func__);
402 return -ENODEV;
403 }
404
405 context->ep_num_mapping[dbm_ep] = 0;
406
407 dwc3_msm_write_reg(context->base, DBM_EP_CFG(dbm_ep), 0);
408
409 /* Reset the dbm endpoint */
410 dwc3_msm_dbm_ep_soft_reset(dbm_ep, true);
411
412 return 0;
413}
414
415/**
416 * Configure the DBM with the BAM's data fifo.
417 * This function is called by the USB BAM Driver
418 * upon initialization.
419 *
420 * @ep - pointer to usb endpoint.
421 * @addr - address of data fifo.
422 * @size - size of data fifo.
423 *
424 */
425int msm_data_fifo_config(struct usb_ep *ep, u32 addr, u32 size)
426{
427 u8 dbm_ep;
428 struct dwc3_ep *dep = to_dwc3_ep(ep);
429
430 dev_dbg(context->dev, "%s\n", __func__);
431
432 dbm_ep = dwc3_msm_find_matching_dbm_ep(dep->number);
433
434 if (dbm_ep >= context->dbm_num_eps) {
435 dev_err(context->dev,
436 "%s: Invalid DBM ep index\n", __func__);
437 return -ENODEV;
438 }
439
440 dwc3_msm_write_reg(context->base, DBM_DATA_FIFO(dbm_ep), addr);
441 dwc3_msm_write_reg_field(context->base, DBM_DATA_FIFO_SIZE(dbm_ep),
442 DBM_DATA_FIFO_SIZE_MASK, size);
443
444 return 0;
445}
446
447/**
448* Cleanups for msm endpoint on request complete.
449*
450* Also call original request complete.
451*
452* @usb_ep - pointer to usb_ep instance.
453* @request - pointer to usb_request instance.
454*
455* @return int - 0 on success, negetive on error.
456*/
457static void dwc3_msm_req_complete_func(struct usb_ep *ep,
458 struct usb_request *request)
459{
460 struct dwc3_request *req = to_dwc3_request(request);
461 struct dwc3_ep *dep = to_dwc3_ep(ep);
462 struct dwc3_msm_req_complete *req_complete = NULL;
463
464 /* Find original request complete function and remove it from list */
465 list_for_each_entry(req_complete,
466 &context->req_complete_list,
467 list_item) {
468 if (req_complete->req == request)
469 break;
470 }
471 if (!req_complete || req_complete->req != request) {
472 dev_err(dep->dwc->dev, "%s: could not find the request\n",
473 __func__);
474 return;
475 }
476 list_del(&req_complete->list_item);
477
478 /*
479 * Release another one TRB to the pool since DBM queue took 2 TRBs
480 * (normal and link), and the dwc3/gadget.c :: dwc3_gadget_giveback
481 * released only one.
482 */
483 if (req->queued)
484 dep->busy_slot++;
485
486 /* Unconfigure dbm ep */
487 dwc3_msm_dbm_ep_unconfig(dep->number);
488
489 /*
490 * If this is the last endpoint we unconfigured, than reset also
491 * the event buffers.
492 */
493 if (0 == dwc3_msm_configured_dbm_ep_num())
494 dwc3_msm_event_buffer_config(0, 0);
495
496 /*
497 * Call original complete function, notice that dwc->lock is already
498 * taken by the caller of this function (dwc3_gadget_giveback()).
499 */
500 request->complete = req_complete->orig_complete;
501 request->complete(ep, request);
502
503 kfree(req_complete);
504}
505
506/**
507* Helper function.
508* See the header of the dwc3_msm_ep_queue function.
509*
510* @dwc3_ep - pointer to dwc3_ep instance.
511* @req - pointer to dwc3_request instance.
512*
513* @return int - 0 on success, negetive on error.
514*/
515static int __dwc3_msm_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
516{
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300517 struct dwc3_trb *trb;
518 struct dwc3_trb *trb_link;
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300519 struct dwc3_gadget_ep_cmd_params params;
520 u32 cmd;
521 int ret = 0;
522
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300523 /* We push the request to the dep->req_queued list to indicate that
524 * this request is issued with start transfer. The request will be out
525 * from this list in 2 cases. The first is that the transfer will be
526 * completed (not if the transfer is endless using a circular TRBs with
527 * with link TRB). The second case is an option to do stop stransfer,
528 * this can be initiated by the function driver when calling dequeue.
529 */
530 req->queued = true;
531 list_add_tail(&req->list, &dep->req_queued);
532
533 /* First, prepare a normal TRB, point to the fake buffer */
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300534 trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300535 dep->free_slot++;
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300536 memset(trb, 0, sizeof(*trb));
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300537
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300538 req->trb = trb;
539 req->trb_dma = dwc3_trb_dma_offset(dep, trb);
540 trb->bph = DBM_TRB_BIT | DBM_TRB_DATA_SRC |
541 DBM_TRB_DMA | DBM_TRB_EP_NUM(dep->number);
542 trb->size = DWC3_TRB_SIZE_LENGTH(req->request.length);
543 trb->ctrl = DWC3_TRBCTL_NORMAL | DWC3_TRB_CTRL_HWO | DWC3_TRB_CTRL_CHN;
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300544
545 /* Second, prepare a Link TRB that points to the first TRB*/
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300546 trb_link = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300547 dep->free_slot++;
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300548
Ido Shayevitzfa65a582012-06-06 14:39:54 +0300549 trb_link->bpl = lower_32_bits(req->trb_dma);
550 trb_link->bph = DBM_TRB_BIT | DBM_TRB_DATA_SRC |
551 DBM_TRB_DMA | DBM_TRB_EP_NUM(dep->number);
552 trb_link->size = 0;
553 trb_link->ctrl = DWC3_TRBCTL_LINK_TRB | DWC3_TRB_CTRL_HWO;
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300554
555 /*
556 * Now start the transfer
557 */
558 memset(&params, 0, sizeof(params));
559 params.param0 = upper_32_bits(req->trb_dma);
560 params.param1 = lower_32_bits(req->trb_dma);
561 cmd = DWC3_DEPCMD_STARTTRANSFER;
562 ret = dwc3_send_gadget_ep_cmd(dep->dwc, dep->number, cmd, &params);
563 if (ret < 0) {
564 dev_dbg(dep->dwc->dev,
565 "%s: failed to send STARTTRANSFER command\n",
566 __func__);
567
Ido Shayevitz9fb83452012-04-01 17:45:58 +0300568 list_del(&req->list);
569 return ret;
570 }
571
572 return ret;
573}
574
575/**
576* Queue a usb request to the DBM endpoint.
577* This function should be called after the endpoint
578* was enabled by the ep_enable.
579*
580* This function prepares special structure of TRBs which
581* is familier with the DBM HW, so it will possible to use
582* this endpoint in DBM mode.
583*
584* The TRBs prepared by this function, is one normal TRB
585* which point to a fake buffer, followed by a link TRB
586* that points to the first TRB.
587*
588* The API of this function follow the regular API of
589* usb_ep_queue (see usb_ep_ops in include/linuk/usb/gadget.h).
590*
591* @usb_ep - pointer to usb_ep instance.
592* @request - pointer to usb_request instance.
593* @gfp_flags - possible flags.
594*
595* @return int - 0 on success, negetive on error.
596*/
597static int dwc3_msm_ep_queue(struct usb_ep *ep,
598 struct usb_request *request, gfp_t gfp_flags)
599{
600 struct dwc3_request *req = to_dwc3_request(request);
601 struct dwc3_ep *dep = to_dwc3_ep(ep);
602 struct dwc3 *dwc = dep->dwc;
603 struct dwc3_msm_req_complete *req_complete;
604 unsigned long flags;
605 int ret = 0;
606 u8 bam_pipe;
607 bool producer;
608 bool disable_wb;
609 bool internal_mem;
610 bool ioc;
611
612 if (!(request->udc_priv & MSM_SPS_MODE)) {
613 /* Not SPS mode, call original queue */
614 dev_vdbg(dwc->dev, "%s: not sps mode, use regular queue\n",
615 __func__);
616
617 return (context->original_ep_ops[dep->number])->queue(ep,
618 request,
619 gfp_flags);
620 }
621
622 if (!dep->endpoint.desc) {
623 dev_err(dwc->dev,
624 "%s: trying to queue request %p to disabled ep %s\n",
625 __func__, request, ep->name);
626 return -EPERM;
627 }
628
629 if (dep->number == 0 || dep->number == 1) {
630 dev_err(dwc->dev,
631 "%s: trying to queue dbm request %p to control ep %s\n",
632 __func__, request, ep->name);
633 return -EPERM;
634 }
635
636 if (dep->free_slot > 0 || dep->busy_slot > 0 ||
637 !list_empty(&dep->request_list) ||
638 !list_empty(&dep->req_queued)) {
639
640 dev_err(dwc->dev,
641 "%s: trying to queue dbm request %p tp ep %s\n",
642 __func__, request, ep->name);
643 return -EPERM;
644 }
645
646 /*
647 * Override req->complete function, but before doing that,
648 * store it's original pointer in the req_complete_list.
649 */
650 req_complete = kzalloc(sizeof(*req_complete), GFP_KERNEL);
651 if (!req_complete) {
652 dev_err(dep->dwc->dev, "%s: not enough memory\n", __func__);
653 return -ENOMEM;
654 }
655 req_complete->req = request;
656 req_complete->orig_complete = request->complete;
657 list_add_tail(&req_complete->list_item, &context->req_complete_list);
658 request->complete = dwc3_msm_req_complete_func;
659
660 /*
661 * Configure dbm event buffers if this is the first
662 * dbm endpoint we about to configure.
663 */
664 if (0 == dwc3_msm_configured_dbm_ep_num())
665 dwc3_msm_event_buffer_config(dwc->ev_buffs[0]->dma,
666 dwc->ev_buffs[0]->length);
667
668 /*
669 * Configure the DBM endpoint
670 */
671 bam_pipe = (request->udc_priv & MSM_PIPE_ID_MASK);
672 producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
673 disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
674 internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
675 ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
676
677 ret = dwc3_msm_dbm_ep_config(dep->number,
678 bam_pipe, producer,
679 disable_wb, internal_mem, ioc);
680 if (ret < 0) {
681 dev_err(context->dev,
682 "error %d after calling dwc3_msm_dbm_ep_config\n",
683 ret);
684 return ret;
685 }
686
687 dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
688 __func__, request, ep->name, request->length);
689
690 /*
691 * We must obtain the lock of the dwc3 core driver,
692 * including disabling interrupts, so we will be sure
693 * that we are the only ones that configure the HW device
694 * core and ensure that we queuing the request will finish
695 * as soon as possible so we will release back the lock.
696 */
697 spin_lock_irqsave(&dwc->lock, flags);
698 ret = __dwc3_msm_ep_queue(dep, req);
699 spin_unlock_irqrestore(&dwc->lock, flags);
700 if (ret < 0) {
701 dev_err(context->dev,
702 "error %d after calling __dwc3_msm_ep_queue\n", ret);
703 return ret;
704 }
705
706 return 0;
707}
708
709/**
710 * Configure MSM endpoint.
711 * This function do specific configurations
712 * to an endpoint which need specific implementaion
713 * in the MSM architecture.
714 *
715 * This function should be called by usb function/class
716 * layer which need a support from the specific MSM HW
717 * which wrap the USB3 core. (like DBM specific endpoints)
718 *
719 * @ep - a pointer to some usb_ep instance
720 *
721 * @return int - 0 on success, negetive on error.
722 */
723int msm_ep_config(struct usb_ep *ep)
724{
725 struct dwc3_ep *dep = to_dwc3_ep(ep);
726 struct usb_ep_ops *new_ep_ops;
727
728 /* Save original ep ops for future restore*/
729 if (context->original_ep_ops[dep->number]) {
730 dev_err(context->dev,
731 "ep [%s,%d] already configured as msm endpoint\n",
732 ep->name, dep->number);
733 return -EPERM;
734 }
735 context->original_ep_ops[dep->number] = ep->ops;
736
737 /* Set new usb ops as we like */
738 new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_KERNEL);
739 if (!new_ep_ops) {
740 dev_err(context->dev,
741 "%s: unable to allocate mem for new usb ep ops\n",
742 __func__);
743 return -ENOMEM;
744 }
745 (*new_ep_ops) = (*ep->ops);
746 new_ep_ops->queue = dwc3_msm_ep_queue;
747 ep->ops = new_ep_ops;
748
749 /*
750 * Do HERE more usb endpoint configurations
751 * which are specific to MSM.
752 */
753
754 return 0;
755}
756EXPORT_SYMBOL(msm_ep_config);
757
758/**
759 * Un-configure MSM endpoint.
760 * Tear down configurations done in the
761 * dwc3_msm_ep_config function.
762 *
763 * @ep - a pointer to some usb_ep instance
764 *
765 * @return int - 0 on success, negetive on error.
766 */
767int msm_ep_unconfig(struct usb_ep *ep)
768{
769 struct dwc3_ep *dep = to_dwc3_ep(ep);
770 struct usb_ep_ops *old_ep_ops;
771
772 /* Restore original ep ops */
773 if (!context->original_ep_ops[dep->number]) {
774 dev_err(context->dev,
775 "ep [%s,%d] was not configured as msm endpoint\n",
776 ep->name, dep->number);
777 return -EINVAL;
778 }
779 old_ep_ops = (struct usb_ep_ops *)ep->ops;
780 ep->ops = context->original_ep_ops[dep->number];
781 context->original_ep_ops[dep->number] = NULL;
782 kfree(old_ep_ops);
783
784 /*
785 * Do HERE more usb endpoint un-configurations
786 * which are specific to MSM.
787 */
788
789 return 0;
790}
791EXPORT_SYMBOL(msm_ep_unconfig);
792
Manu Gautam60e01352012-05-29 09:00:34 +0530793/* HSPHY */
794static int dwc3_hsusb_config_vddcx(int high)
795{
796 int min_vol, ret;
797 struct dwc3_msm *dwc = context;
798 enum usb_vdd_type vdd_type = context->hs_vdd_type;
799 int max_vol = vdd_val[vdd_type][VDD_MAX];
800
801 min_vol = vdd_val[vdd_type][high ? VDD_MIN : VDD_NONE];
802 ret = regulator_set_voltage(dwc->hsusb_vddcx, min_vol, max_vol);
803 if (ret) {
804 dev_err(dwc->dev, "unable to set voltage for HSUSB_VDDCX\n");
805 return ret;
806 }
807
808 dev_dbg(dwc->dev, "%s: min_vol:%d max_vol:%d\n", __func__,
809 min_vol, max_vol);
810
811 return ret;
812}
813
814static int dwc3_hsusb_ldo_init(int init)
815{
816 int rc = 0;
817 struct dwc3_msm *dwc = context;
818
819 if (!init) {
820 regulator_set_voltage(dwc->hsusb_1p8, 0, USB_HSPHY_1P8_VOL_MAX);
821 regulator_set_voltage(dwc->hsusb_3p3, 0, USB_HSPHY_3P3_VOL_MAX);
822 return 0;
823 }
824
825 dwc->hsusb_3p3 = devm_regulator_get(dwc->dev, "HSUSB_3p3");
826 if (IS_ERR(dwc->hsusb_3p3)) {
827 dev_err(dwc->dev, "unable to get hsusb 3p3\n");
828 return PTR_ERR(dwc->hsusb_3p3);
829 }
830
831 rc = regulator_set_voltage(dwc->hsusb_3p3,
832 USB_HSPHY_3P3_VOL_MIN, USB_HSPHY_3P3_VOL_MAX);
833 if (rc) {
834 dev_err(dwc->dev, "unable to set voltage for hsusb 3p3\n");
835 return rc;
836 }
837 dwc->hsusb_1p8 = devm_regulator_get(dwc->dev, "HSUSB_1p8");
838 if (IS_ERR(dwc->hsusb_1p8)) {
839 dev_err(dwc->dev, "unable to get hsusb 1p8\n");
840 rc = PTR_ERR(dwc->hsusb_1p8);
841 goto devote_3p3;
842 }
843 rc = regulator_set_voltage(dwc->hsusb_1p8,
844 USB_HSPHY_1P8_VOL_MIN, USB_HSPHY_1P8_VOL_MAX);
845 if (rc) {
846 dev_err(dwc->dev, "unable to set voltage for hsusb 1p8\n");
847 goto devote_3p3;
848 }
849
850 return 0;
851
852devote_3p3:
853 regulator_set_voltage(dwc->hsusb_3p3, 0, USB_HSPHY_3P3_VOL_MAX);
854
855 return rc;
856}
857
858static int dwc3_hsusb_ldo_enable(int on)
859{
860 int rc = 0;
861 struct dwc3_msm *dwc = context;
862
863 dev_dbg(dwc->dev, "reg (%s)\n", on ? "HPM" : "LPM");
864
865 if (!on)
866 goto disable_regulators;
867
868
869 rc = regulator_set_optimum_mode(dwc->hsusb_1p8, USB_HSPHY_1P8_HPM_LOAD);
870 if (rc < 0) {
871 dev_err(dwc->dev, "Unable to set HPM of regulator HSUSB_1p8\n");
872 return rc;
873 }
874
875 rc = regulator_enable(dwc->hsusb_1p8);
876 if (rc) {
877 dev_err(dwc->dev, "Unable to enable HSUSB_1p8\n");
878 goto put_1p8_lpm;
879 }
880
881 rc = regulator_set_optimum_mode(dwc->hsusb_3p3, USB_HSPHY_3P3_HPM_LOAD);
882 if (rc < 0) {
883 dev_err(dwc->dev, "Unable to set HPM of regulator HSUSB_3p3\n");
884 goto disable_1p8;
885 }
886
887 rc = regulator_enable(dwc->hsusb_3p3);
888 if (rc) {
889 dev_err(dwc->dev, "Unable to enable HSUSB_3p3\n");
890 goto put_3p3_lpm;
891 }
892
893 return 0;
894
895disable_regulators:
896 rc = regulator_disable(dwc->hsusb_3p3);
897 if (rc)
898 dev_err(dwc->dev, "Unable to disable HSUSB_3p3\n");
899
900put_3p3_lpm:
901 rc = regulator_set_optimum_mode(dwc->hsusb_3p3, 0);
902 if (rc < 0)
903 dev_err(dwc->dev, "Unable to set LPM of regulator HSUSB_3p3\n");
904
905disable_1p8:
906 rc = regulator_disable(dwc->hsusb_1p8);
907 if (rc)
908 dev_err(dwc->dev, "Unable to disable HSUSB_1p8\n");
909
910put_1p8_lpm:
911 rc = regulator_set_optimum_mode(dwc->hsusb_1p8, 0);
912 if (rc < 0)
913 dev_err(dwc->dev, "Unable to set LPM of regulator HSUSB_1p8\n");
914
915 return rc < 0 ? rc : 0;
916}
917
918/* SSPHY */
919static int dwc3_ssusb_config_vddcx(int high)
920{
921 int min_vol, ret;
922 struct dwc3_msm *dwc = context;
923 enum usb_vdd_type vdd_type = context->ss_vdd_type;
924 int max_vol = vdd_val[vdd_type][VDD_MAX];
925
926 min_vol = vdd_val[vdd_type][high ? VDD_MIN : VDD_NONE];
927 ret = regulator_set_voltage(dwc->ssusb_vddcx, min_vol, max_vol);
928 if (ret) {
929 dev_err(dwc->dev, "unable to set voltage for SSUSB_VDDCX\n");
930 return ret;
931 }
932
933 dev_dbg(dwc->dev, "%s: min_vol:%d max_vol:%d\n", __func__,
934 min_vol, max_vol);
935 return ret;
936}
937
938/* 3.3v supply not needed for SS PHY */
939static int dwc3_ssusb_ldo_init(int init)
940{
941 int rc = 0;
942 struct dwc3_msm *dwc = context;
943
944 if (!init) {
945 regulator_set_voltage(dwc->ssusb_1p8, 0, USB_SSPHY_1P8_VOL_MAX);
946 return 0;
947 }
948
949 dwc->ssusb_1p8 = devm_regulator_get(dwc->dev, "SSUSB_1p8");
950 if (IS_ERR(dwc->ssusb_1p8)) {
951 dev_err(dwc->dev, "unable to get ssusb 1p8\n");
952 return PTR_ERR(dwc->ssusb_1p8);
953 }
954 rc = regulator_set_voltage(dwc->ssusb_1p8,
955 USB_SSPHY_1P8_VOL_MIN, USB_SSPHY_1P8_VOL_MAX);
956 if (rc)
957 dev_err(dwc->dev, "unable to set voltage for ssusb 1p8\n");
958
959 return rc;
960}
961
962static int dwc3_ssusb_ldo_enable(int on)
963{
964 int rc = 0;
965 struct dwc3_msm *dwc = context;
966
967 dev_dbg(context->dev, "reg (%s)\n", on ? "HPM" : "LPM");
968
969 if (!on)
970 goto disable_regulators;
971
972
973 rc = regulator_set_optimum_mode(dwc->ssusb_1p8, USB_SSPHY_1P8_HPM_LOAD);
974 if (rc < 0) {
975 dev_err(dwc->dev, "Unable to set HPM of SSUSB_1p8\n");
976 return rc;
977 }
978
979 rc = regulator_enable(dwc->ssusb_1p8);
980 if (rc) {
981 dev_err(dwc->dev, "Unable to enable SSUSB_1p8\n");
982 goto put_1p8_lpm;
983 }
984
985 return 0;
986
987disable_regulators:
988 rc = regulator_disable(dwc->ssusb_1p8);
989 if (rc)
990 dev_err(dwc->dev, "Unable to disable SSUSB_1p8\n");
991
992put_1p8_lpm:
993 rc = regulator_set_optimum_mode(dwc->ssusb_1p8, 0);
994 if (rc < 0)
995 dev_err(dwc->dev, "Unable to set LPM of SSUSB_1p8\n");
996
997 return rc < 0 ? rc : 0;
998}
999
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001000static int __devinit dwc3_msm_probe(struct platform_device *pdev)
1001{
1002 struct device_node *node = pdev->dev.of_node;
1003 struct platform_device *dwc3;
1004 struct dwc3_msm *msm;
1005 struct resource *res;
1006 int ret = 0;
1007
1008 msm = devm_kzalloc(&pdev->dev, sizeof(*msm), GFP_KERNEL);
1009 if (!msm) {
1010 dev_err(&pdev->dev, "not enough memory\n");
1011 return -ENOMEM;
1012 }
1013
1014 platform_set_drvdata(pdev, msm);
Ido Shayevitz9fb83452012-04-01 17:45:58 +03001015 context = msm;
Manu Gautam60e01352012-05-29 09:00:34 +05301016 msm->dev = &pdev->dev;
Ido Shayevitz9fb83452012-04-01 17:45:58 +03001017
1018 INIT_LIST_HEAD(&msm->req_complete_list);
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001019
Manu Gautam60e01352012-05-29 09:00:34 +05301020 /* SS PHY */
1021 msm->ss_vdd_type = VDDCX_CORNER;
1022 msm->ssusb_vddcx = devm_regulator_get(&pdev->dev, "ssusb_vdd_dig");
1023 if (IS_ERR(msm->ssusb_vddcx)) {
1024 msm->ssusb_vddcx = devm_regulator_get(&pdev->dev,
1025 "SSUSB_VDDCX");
1026 if (IS_ERR(msm->ssusb_vddcx)) {
1027 dev_err(&pdev->dev, "unable to get ssusb vddcx\n");
1028 return PTR_ERR(msm->ssusb_vddcx);
1029 }
1030 msm->ss_vdd_type = VDDCX;
1031 dev_dbg(&pdev->dev, "ss_vdd_type: VDDCX\n");
1032 }
1033
1034 ret = dwc3_ssusb_config_vddcx(1);
1035 if (ret) {
1036 dev_err(&pdev->dev, "ssusb vddcx configuration failed\n");
1037 return ret;
1038 }
1039
1040 ret = regulator_enable(context->ssusb_vddcx);
1041 if (ret) {
1042 dev_err(&pdev->dev, "unable to enable the ssusb vddcx\n");
1043 goto unconfig_ss_vddcx;
1044 }
1045
1046 ret = dwc3_ssusb_ldo_init(1);
1047 if (ret) {
1048 dev_err(&pdev->dev, "ssusb vreg configuration failed\n");
1049 goto disable_ss_vddcx;
1050 }
1051
1052 ret = dwc3_ssusb_ldo_enable(1);
1053 if (ret) {
1054 dev_err(&pdev->dev, "ssusb vreg enable failed\n");
1055 goto free_ss_ldo_init;
1056 }
1057
1058 /* HS PHY */
1059 msm->hs_vdd_type = VDDCX_CORNER;
1060 msm->hsusb_vddcx = devm_regulator_get(&pdev->dev, "hsusb_vdd_dig");
1061 if (IS_ERR(msm->hsusb_vddcx)) {
1062 msm->hsusb_vddcx = devm_regulator_get(&pdev->dev,
1063 "HSUSB_VDDCX");
1064 if (IS_ERR(msm->hsusb_vddcx)) {
1065 dev_err(&pdev->dev, "unable to get hsusb vddcx\n");
1066 ret = PTR_ERR(msm->ssusb_vddcx);
1067 goto disable_ss_ldo;
1068 }
1069 msm->hs_vdd_type = VDDCX;
1070 dev_dbg(&pdev->dev, "hs_vdd_type: VDDCX\n");
1071 }
1072
1073 ret = dwc3_hsusb_config_vddcx(1);
1074 if (ret) {
1075 dev_err(&pdev->dev, "hsusb vddcx configuration failed\n");
1076 goto disable_ss_ldo;
1077 }
1078
1079 ret = regulator_enable(context->hsusb_vddcx);
1080 if (ret) {
1081 dev_err(&pdev->dev, "unable to enable the hsusb vddcx\n");
1082 goto unconfig_hs_vddcx;
1083 }
1084
1085 ret = dwc3_hsusb_ldo_init(1);
1086 if (ret) {
1087 dev_err(&pdev->dev, "hsusb vreg configuration failed\n");
1088 goto disable_hs_vddcx;
1089 }
1090
1091 ret = dwc3_hsusb_ldo_enable(1);
1092 if (ret) {
1093 dev_err(&pdev->dev, "hsusb vreg enable failed\n");
1094 goto free_hs_ldo_init;
1095 }
1096
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001097 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1098 if (!res) {
1099 dev_err(&pdev->dev, "missing memory base resource\n");
Manu Gautam60e01352012-05-29 09:00:34 +05301100 ret = -ENODEV;
1101 goto disable_hs_ldo;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001102 }
1103
1104 msm->base = devm_ioremap_nocache(&pdev->dev, res->start,
1105 resource_size(res));
1106 if (!msm->base) {
1107 dev_err(&pdev->dev, "ioremap failed\n");
Manu Gautam60e01352012-05-29 09:00:34 +05301108 ret = -ENODEV;
1109 goto disable_hs_ldo;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001110 }
1111
Ido Shayevitzca2691e2012-04-17 15:54:53 +03001112 dwc3 = platform_device_alloc("dwc3", -1);
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001113 if (!dwc3) {
1114 dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
Manu Gautam60e01352012-05-29 09:00:34 +05301115 ret = -ENODEV;
1116 goto disable_hs_ldo;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001117 }
1118
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001119 dwc3->dev.parent = &pdev->dev;
Ido Shayevitzc9e92e92012-05-30 14:36:35 +03001120 dwc3->dev.coherent_dma_mask = DMA_BIT_MASK(32);
1121 dwc3->dev.dma_mask = &dwc3_msm_dma_mask;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001122 dwc3->dev.dma_parms = pdev->dev.dma_parms;
1123 msm->resource_size = resource_size(res);
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001124 msm->dwc3 = dwc3;
1125
1126 if (of_property_read_u32(node, "qcom,dwc-usb3-msm-dbm-eps",
1127 &msm->dbm_num_eps)) {
1128 dev_err(&pdev->dev,
1129 "unable to read platform data num of dbm eps\n");
1130 msm->dbm_num_eps = DBM_MAX_EPS;
1131 }
1132
1133 if (msm->dbm_num_eps > DBM_MAX_EPS) {
1134 dev_err(&pdev->dev,
1135 "Driver doesn't support number of DBM EPs. "
1136 "max: %d, dbm_num_eps: %d\n",
1137 DBM_MAX_EPS, msm->dbm_num_eps);
1138 ret = -ENODEV;
Manu Gautam60e01352012-05-29 09:00:34 +05301139 goto put_pdev;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001140 }
1141
1142 ret = platform_device_add_resources(dwc3, pdev->resource,
1143 pdev->num_resources);
1144 if (ret) {
1145 dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");
Manu Gautam60e01352012-05-29 09:00:34 +05301146 goto put_pdev;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001147 }
1148
1149 ret = platform_device_add(dwc3);
1150 if (ret) {
1151 dev_err(&pdev->dev, "failed to register dwc3 device\n");
Manu Gautam60e01352012-05-29 09:00:34 +05301152 goto put_pdev;
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001153 }
1154
Ido Shayevitz9fb83452012-04-01 17:45:58 +03001155 /* Reset the DBM */
1156 dwc3_msm_dbm_soft_reset();
1157
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001158 return 0;
1159
Manu Gautam60e01352012-05-29 09:00:34 +05301160put_pdev:
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001161 platform_device_put(dwc3);
Manu Gautam60e01352012-05-29 09:00:34 +05301162disable_hs_ldo:
1163 dwc3_hsusb_ldo_enable(0);
1164free_hs_ldo_init:
1165 dwc3_hsusb_ldo_init(0);
1166disable_hs_vddcx:
1167 regulator_disable(context->hsusb_vddcx);
1168unconfig_hs_vddcx:
1169 dwc3_hsusb_config_vddcx(0);
1170disable_ss_ldo:
1171 dwc3_ssusb_ldo_enable(0);
1172free_ss_ldo_init:
1173 dwc3_ssusb_ldo_init(0);
1174disable_ss_vddcx:
1175 regulator_disable(context->ssusb_vddcx);
1176unconfig_ss_vddcx:
1177 dwc3_ssusb_config_vddcx(0);
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001178
1179 return ret;
1180}
1181
1182static int __devexit dwc3_msm_remove(struct platform_device *pdev)
1183{
1184 struct dwc3_msm *msm = platform_get_drvdata(pdev);
1185
1186 platform_device_unregister(msm->dwc3);
1187
Manu Gautam60e01352012-05-29 09:00:34 +05301188 dwc3_hsusb_ldo_enable(0);
1189 dwc3_hsusb_ldo_init(0);
1190 regulator_disable(msm->hsusb_vddcx);
1191 dwc3_hsusb_config_vddcx(0);
1192 dwc3_ssusb_ldo_enable(0);
1193 dwc3_ssusb_ldo_init(0);
1194 regulator_disable(msm->ssusb_vddcx);
1195 dwc3_ssusb_config_vddcx(0);
1196
Ido Shayevitzef72ddd2012-03-28 18:55:55 +02001197 return 0;
1198}
1199
1200static const struct of_device_id of_dwc3_matach[] = {
1201 {
1202 .compatible = "qcom,dwc-usb3-msm",
1203 },
1204 { },
1205};
1206MODULE_DEVICE_TABLE(of, of_dwc3_matach);
1207
1208static struct platform_driver dwc3_msm_driver = {
1209 .probe = dwc3_msm_probe,
1210 .remove = __devexit_p(dwc3_msm_remove),
1211 .driver = {
1212 .name = "msm-dwc3",
1213 .of_match_table = of_dwc3_matach,
1214 },
1215};
1216
1217MODULE_LICENSE("GPLV2");
1218MODULE_DESCRIPTION("DesignWare USB3 MSM Glue Layer");
1219
1220static int __devinit dwc3_msm_init(void)
1221{
1222 return platform_driver_register(&dwc3_msm_driver);
1223}
1224module_init(dwc3_msm_init);
1225
1226static void __exit dwc3_msm_exit(void)
1227{
1228 platform_driver_unregister(&dwc3_msm_driver);
1229}
1230module_exit(dwc3_msm_exit);