diff options
author | Pavankumar Kondeti <pkondeti@codeaurora.org> | 2010-12-07 07:24:02 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-10 17:23:33 -0500 |
commit | f01ef5748f4c4dcd2e49ccb7d75dc113219559d2 (patch) | |
tree | f67c19262909832ad72f11f0b1eb7083bcac0578 /drivers/usb | |
parent | 61948ee4d525174cceee2135a38a482124fcc02c (diff) |
USB: gadget: Introduce ci13xxx_udc_driver struct
Introduces ci13xxx_udc_driver struct for bus glue drivers to hint
ci13xxx_udc core about their special requirements. The flags include
avoiding hardware register access when controller is not in peripheral
mode, enabling pull-up upon VBUS, disabling streaming mode and dependency
on transceiver driver.
Initialize gadget_ops in udc_probe so that transceiver can notify VBUS
presence even when no gadget driver is bounded.
A notify_event callback is embedded in the same struct. This patch implements
two events called CONTROLLER_RESET_EVENT and CONTROLLER_STOPPED_EVENT to
notify the bus glue driver after resetting and stopping the controller for
performing SoC specific quirks.
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_pci.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 205 | ||||
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.h | 19 |
3 files changed, 175 insertions, 55 deletions
diff --git a/drivers/usb/gadget/ci13xxx_pci.c b/drivers/usb/gadget/ci13xxx_pci.c index 7a0f153e33c0..883ab5e832d1 100644 --- a/drivers/usb/gadget/ci13xxx_pci.c +++ b/drivers/usb/gadget/ci13xxx_pci.c | |||
@@ -38,6 +38,10 @@ static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev) | |||
38 | return udc_irq(); | 38 | return udc_irq(); |
39 | } | 39 | } |
40 | 40 | ||
41 | static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = { | ||
42 | .name = UDC_DRIVER_NAME, | ||
43 | }; | ||
44 | |||
41 | /** | 45 | /** |
42 | * ci13xxx_pci_probe: PCI probe | 46 | * ci13xxx_pci_probe: PCI probe |
43 | * @pdev: USB device controller being probed | 47 | * @pdev: USB device controller being probed |
@@ -82,7 +86,7 @@ static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | |||
82 | pci_set_master(pdev); | 86 | pci_set_master(pdev); |
83 | pci_try_set_mwi(pdev); | 87 | pci_try_set_mwi(pdev); |
84 | 88 | ||
85 | retval = udc_probe(&pdev->dev, regs, UDC_DRIVER_NAME); | 89 | retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs); |
86 | if (retval) | 90 | if (retval) |
87 | goto iounmap; | 91 | goto iounmap; |
88 | 92 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 956fa64f1359..c10d1aee5230 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/slab.h> | 62 | #include <linux/slab.h> |
63 | #include <linux/usb/ch9.h> | 63 | #include <linux/usb/ch9.h> |
64 | #include <linux/usb/gadget.h> | 64 | #include <linux/usb/gadget.h> |
65 | #include <linux/usb/otg.h> | ||
65 | 66 | ||
66 | #include "ci13xxx_udc.h" | 67 | #include "ci13xxx_udc.h" |
67 | 68 | ||
@@ -126,6 +127,9 @@ static struct { | |||
126 | size_t size; /* bank size */ | 127 | size_t size; /* bank size */ |
127 | } hw_bank; | 128 | } hw_bank; |
128 | 129 | ||
130 | /* MSM specific */ | ||
131 | #define ABS_AHBBURST (0x0090UL) | ||
132 | #define ABS_AHBMODE (0x0098UL) | ||
129 | /* UDC register map */ | 133 | /* UDC register map */ |
130 | #define ABS_CAPLENGTH (0x100UL) | 134 | #define ABS_CAPLENGTH (0x100UL) |
131 | #define ABS_HCCPARAMS (0x108UL) | 135 | #define ABS_HCCPARAMS (0x108UL) |
@@ -242,13 +246,7 @@ static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data) | |||
242 | return (reg & mask) >> ffs_nr(mask); | 246 | return (reg & mask) >> ffs_nr(mask); |
243 | } | 247 | } |
244 | 248 | ||
245 | /** | 249 | static int hw_device_init(void __iomem *base) |
246 | * hw_device_reset: resets chip (execute without interruption) | ||
247 | * @base: register base address | ||
248 | * | ||
249 | * This function returns an error code | ||
250 | */ | ||
251 | static int hw_device_reset(void __iomem *base) | ||
252 | { | 250 | { |
253 | u32 reg; | 251 | u32 reg; |
254 | 252 | ||
@@ -265,6 +263,28 @@ static int hw_device_reset(void __iomem *base) | |||
265 | hw_bank.size += CAP_LAST; | 263 | hw_bank.size += CAP_LAST; |
266 | hw_bank.size /= sizeof(u32); | 264 | hw_bank.size /= sizeof(u32); |
267 | 265 | ||
266 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
267 | if (reg == 0 || reg > ENDPT_MAX) | ||
268 | return -ENODEV; | ||
269 | |||
270 | hw_ep_max = reg; /* cache hw ENDPT_MAX */ | ||
271 | |||
272 | /* setup lock mode ? */ | ||
273 | |||
274 | /* ENDPTSETUPSTAT is '0' by default */ | ||
275 | |||
276 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | /** | ||
281 | * hw_device_reset: resets chip (execute without interruption) | ||
282 | * @base: register base address | ||
283 | * | ||
284 | * This function returns an error code | ||
285 | */ | ||
286 | static int hw_device_reset(struct ci13xxx *udc) | ||
287 | { | ||
268 | /* should flush & stop before reset */ | 288 | /* should flush & stop before reset */ |
269 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); | 289 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); |
270 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | 290 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); |
@@ -273,6 +293,14 @@ static int hw_device_reset(void __iomem *base) | |||
273 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) | 293 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) |
274 | udelay(10); /* not RTOS friendly */ | 294 | udelay(10); /* not RTOS friendly */ |
275 | 295 | ||
296 | |||
297 | if (udc->udc_driver->notify_event) | ||
298 | udc->udc_driver->notify_event(udc, | ||
299 | CI13XXX_CONTROLLER_RESET_EVENT); | ||
300 | |||
301 | if (udc->udc_driver->flags && CI13XXX_DISABLE_STREAMING) | ||
302 | hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS); | ||
303 | |||
276 | /* USBMODE should be configured step by step */ | 304 | /* USBMODE should be configured step by step */ |
277 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | 305 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); |
278 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); | 306 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); |
@@ -284,18 +312,6 @@ static int hw_device_reset(void __iomem *base) | |||
284 | return -ENODEV; | 312 | return -ENODEV; |
285 | } | 313 | } |
286 | 314 | ||
287 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
288 | if (reg == 0 || reg > ENDPT_MAX) | ||
289 | return -ENODEV; | ||
290 | |||
291 | hw_ep_max = reg; /* cache hw ENDPT_MAX */ | ||
292 | |||
293 | /* setup lock mode ? */ | ||
294 | |||
295 | /* ENDPTSETUPSTAT is '0' by default */ | ||
296 | |||
297 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
298 | |||
299 | return 0; | 315 | return 0; |
300 | } | 316 | } |
301 | 317 | ||
@@ -1551,8 +1567,6 @@ __acquires(mEp->lock) | |||
1551 | * Caller must hold lock | 1567 | * Caller must hold lock |
1552 | */ | 1568 | */ |
1553 | static int _gadget_stop_activity(struct usb_gadget *gadget) | 1569 | static int _gadget_stop_activity(struct usb_gadget *gadget) |
1554 | __releases(udc->lock) | ||
1555 | __acquires(udc->lock) | ||
1556 | { | 1570 | { |
1557 | struct usb_ep *ep; | 1571 | struct usb_ep *ep; |
1558 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); | 1572 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); |
@@ -1564,8 +1578,6 @@ __acquires(udc->lock) | |||
1564 | if (gadget == NULL) | 1578 | if (gadget == NULL) |
1565 | return -EINVAL; | 1579 | return -EINVAL; |
1566 | 1580 | ||
1567 | spin_unlock(udc->lock); | ||
1568 | |||
1569 | /* flush all endpoints */ | 1581 | /* flush all endpoints */ |
1570 | gadget_for_each_ep(ep, gadget) { | 1582 | gadget_for_each_ep(ep, gadget) { |
1571 | usb_ep_fifo_flush(ep); | 1583 | usb_ep_fifo_flush(ep); |
@@ -1585,8 +1597,6 @@ __acquires(udc->lock) | |||
1585 | mEp->status = NULL; | 1597 | mEp->status = NULL; |
1586 | } | 1598 | } |
1587 | 1599 | ||
1588 | spin_lock(udc->lock); | ||
1589 | |||
1590 | return 0; | 1600 | return 0; |
1591 | } | 1601 | } |
1592 | 1602 | ||
@@ -1615,6 +1625,7 @@ __acquires(udc->lock) | |||
1615 | 1625 | ||
1616 | dbg_event(0xFF, "BUS RST", 0); | 1626 | dbg_event(0xFF, "BUS RST", 0); |
1617 | 1627 | ||
1628 | spin_unlock(udc->lock); | ||
1618 | retval = _gadget_stop_activity(&udc->gadget); | 1629 | retval = _gadget_stop_activity(&udc->gadget); |
1619 | if (retval) | 1630 | if (retval) |
1620 | goto done; | 1631 | goto done; |
@@ -1623,7 +1634,6 @@ __acquires(udc->lock) | |||
1623 | if (retval) | 1634 | if (retval) |
1624 | goto done; | 1635 | goto done; |
1625 | 1636 | ||
1626 | spin_unlock(udc->lock); | ||
1627 | retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); | 1637 | retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); |
1628 | if (!retval) { | 1638 | if (!retval) { |
1629 | mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); | 1639 | mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); |
@@ -2321,12 +2331,45 @@ static const struct usb_ep_ops usb_ep_ops = { | |||
2321 | /****************************************************************************** | 2331 | /****************************************************************************** |
2322 | * GADGET block | 2332 | * GADGET block |
2323 | *****************************************************************************/ | 2333 | *****************************************************************************/ |
2334 | static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
2335 | { | ||
2336 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
2337 | unsigned long flags; | ||
2338 | int gadget_ready = 0; | ||
2339 | |||
2340 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS)) | ||
2341 | return -EOPNOTSUPP; | ||
2342 | |||
2343 | spin_lock_irqsave(udc->lock, flags); | ||
2344 | udc->vbus_active = is_active; | ||
2345 | if (udc->driver) | ||
2346 | gadget_ready = 1; | ||
2347 | spin_unlock_irqrestore(udc->lock, flags); | ||
2348 | |||
2349 | if (gadget_ready) { | ||
2350 | if (is_active) { | ||
2351 | hw_device_reset(udc); | ||
2352 | hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); | ||
2353 | } else { | ||
2354 | hw_device_state(0); | ||
2355 | if (udc->udc_driver->notify_event) | ||
2356 | udc->udc_driver->notify_event(udc, | ||
2357 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
2358 | _gadget_stop_activity(&udc->gadget); | ||
2359 | } | ||
2360 | } | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2324 | /** | 2365 | /** |
2325 | * Device operations part of the API to the USB controller hardware, | 2366 | * Device operations part of the API to the USB controller hardware, |
2326 | * which don't involve endpoints (or i/o) | 2367 | * which don't involve endpoints (or i/o) |
2327 | * Check "usb_gadget.h" for details | 2368 | * Check "usb_gadget.h" for details |
2328 | */ | 2369 | */ |
2329 | static const struct usb_gadget_ops usb_gadget_ops; | 2370 | static const struct usb_gadget_ops usb_gadget_ops = { |
2371 | .vbus_session = ci13xxx_vbus_session, | ||
2372 | }; | ||
2330 | 2373 | ||
2331 | /** | 2374 | /** |
2332 | * usb_gadget_probe_driver: register a gadget driver | 2375 | * usb_gadget_probe_driver: register a gadget driver |
@@ -2379,7 +2422,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2379 | info("hw_ep_max = %d", hw_ep_max); | 2422 | info("hw_ep_max = %d", hw_ep_max); |
2380 | 2423 | ||
2381 | udc->driver = driver; | 2424 | udc->driver = driver; |
2382 | udc->gadget.ops = NULL; | ||
2383 | udc->gadget.dev.driver = NULL; | 2425 | udc->gadget.dev.driver = NULL; |
2384 | 2426 | ||
2385 | retval = 0; | 2427 | retval = 0; |
@@ -2420,7 +2462,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2420 | 2462 | ||
2421 | /* bind gadget */ | 2463 | /* bind gadget */ |
2422 | driver->driver.bus = NULL; | 2464 | driver->driver.bus = NULL; |
2423 | udc->gadget.ops = &usb_gadget_ops; | ||
2424 | udc->gadget.dev.driver = &driver->driver; | 2465 | udc->gadget.dev.driver = &driver->driver; |
2425 | 2466 | ||
2426 | spin_unlock_irqrestore(udc->lock, flags); | 2467 | spin_unlock_irqrestore(udc->lock, flags); |
@@ -2428,11 +2469,19 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2428 | spin_lock_irqsave(udc->lock, flags); | 2469 | spin_lock_irqsave(udc->lock, flags); |
2429 | 2470 | ||
2430 | if (retval) { | 2471 | if (retval) { |
2431 | udc->gadget.ops = NULL; | ||
2432 | udc->gadget.dev.driver = NULL; | 2472 | udc->gadget.dev.driver = NULL; |
2433 | goto done; | 2473 | goto done; |
2434 | } | 2474 | } |
2435 | 2475 | ||
2476 | if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { | ||
2477 | if (udc->vbus_active) { | ||
2478 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) | ||
2479 | hw_device_reset(udc); | ||
2480 | } else { | ||
2481 | goto done; | ||
2482 | } | ||
2483 | } | ||
2484 | |||
2436 | retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); | 2485 | retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); |
2437 | 2486 | ||
2438 | done: | 2487 | done: |
@@ -2466,19 +2515,21 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2466 | 2515 | ||
2467 | spin_lock_irqsave(udc->lock, flags); | 2516 | spin_lock_irqsave(udc->lock, flags); |
2468 | 2517 | ||
2469 | hw_device_state(0); | 2518 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) || |
2470 | 2519 | udc->vbus_active) { | |
2471 | /* unbind gadget */ | 2520 | hw_device_state(0); |
2472 | if (udc->gadget.ops != NULL) { | 2521 | if (udc->udc_driver->notify_event) |
2522 | udc->udc_driver->notify_event(udc, | ||
2523 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
2473 | _gadget_stop_activity(&udc->gadget); | 2524 | _gadget_stop_activity(&udc->gadget); |
2525 | } | ||
2474 | 2526 | ||
2475 | spin_unlock_irqrestore(udc->lock, flags); | 2527 | /* unbind gadget */ |
2476 | driver->unbind(&udc->gadget); /* MAY SLEEP */ | 2528 | spin_unlock_irqrestore(udc->lock, flags); |
2477 | spin_lock_irqsave(udc->lock, flags); | 2529 | driver->unbind(&udc->gadget); /* MAY SLEEP */ |
2530 | spin_lock_irqsave(udc->lock, flags); | ||
2478 | 2531 | ||
2479 | udc->gadget.ops = NULL; | 2532 | udc->gadget.dev.driver = NULL; |
2480 | udc->gadget.dev.driver = NULL; | ||
2481 | } | ||
2482 | 2533 | ||
2483 | /* free resources */ | 2534 | /* free resources */ |
2484 | for (i = 0; i < hw_ep_max; i++) { | 2535 | for (i = 0; i < hw_ep_max; i++) { |
@@ -2535,6 +2586,14 @@ static irqreturn_t udc_irq(void) | |||
2535 | } | 2586 | } |
2536 | 2587 | ||
2537 | spin_lock(udc->lock); | 2588 | spin_lock(udc->lock); |
2589 | |||
2590 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) { | ||
2591 | if (hw_cread(CAP_USBMODE, USBMODE_CM) != | ||
2592 | USBMODE_CM_DEVICE) { | ||
2593 | spin_unlock(udc->lock); | ||
2594 | return IRQ_NONE; | ||
2595 | } | ||
2596 | } | ||
2538 | intr = hw_test_and_clear_intr_active(); | 2597 | intr = hw_test_and_clear_intr_active(); |
2539 | if (intr) { | 2598 | if (intr) { |
2540 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; | 2599 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; |
@@ -2593,14 +2652,16 @@ static void udc_release(struct device *dev) | |||
2593 | * No interrupts active, the IRQ has not been requested yet | 2652 | * No interrupts active, the IRQ has not been requested yet |
2594 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | 2653 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask |
2595 | */ | 2654 | */ |
2596 | static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | 2655 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, |
2656 | void __iomem *regs) | ||
2597 | { | 2657 | { |
2598 | struct ci13xxx *udc; | 2658 | struct ci13xxx *udc; |
2599 | int retval = 0; | 2659 | int retval = 0; |
2600 | 2660 | ||
2601 | trace("%p, %p, %p", dev, regs, name); | 2661 | trace("%p, %p, %p", dev, regs, name); |
2602 | 2662 | ||
2603 | if (dev == NULL || regs == NULL || name == NULL) | 2663 | if (dev == NULL || regs == NULL || driver == NULL || |
2664 | driver->name == NULL) | ||
2604 | return -EINVAL; | 2665 | return -EINVAL; |
2605 | 2666 | ||
2606 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); | 2667 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); |
@@ -2608,16 +2669,14 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
2608 | return -ENOMEM; | 2669 | return -ENOMEM; |
2609 | 2670 | ||
2610 | udc->lock = &udc_lock; | 2671 | udc->lock = &udc_lock; |
2672 | udc->regs = regs; | ||
2673 | udc->udc_driver = driver; | ||
2611 | 2674 | ||
2612 | retval = hw_device_reset(regs); | 2675 | udc->gadget.ops = &usb_gadget_ops; |
2613 | if (retval) | ||
2614 | goto done; | ||
2615 | |||
2616 | udc->gadget.ops = NULL; | ||
2617 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2676 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
2618 | udc->gadget.is_dualspeed = 1; | 2677 | udc->gadget.is_dualspeed = 1; |
2619 | udc->gadget.is_otg = 0; | 2678 | udc->gadget.is_otg = 0; |
2620 | udc->gadget.name = name; | 2679 | udc->gadget.name = driver->name; |
2621 | 2680 | ||
2622 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2681 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2623 | udc->gadget.ep0 = NULL; | 2682 | udc->gadget.ep0 = NULL; |
@@ -2628,23 +2687,57 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
2628 | udc->gadget.dev.parent = dev; | 2687 | udc->gadget.dev.parent = dev; |
2629 | udc->gadget.dev.release = udc_release; | 2688 | udc->gadget.dev.release = udc_release; |
2630 | 2689 | ||
2690 | retval = hw_device_init(regs); | ||
2691 | if (retval < 0) | ||
2692 | goto free_udc; | ||
2693 | |||
2694 | udc->transceiver = otg_get_transceiver(); | ||
2695 | |||
2696 | if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | ||
2697 | if (udc->transceiver == NULL) { | ||
2698 | retval = -ENODEV; | ||
2699 | goto free_udc; | ||
2700 | } | ||
2701 | } | ||
2702 | |||
2703 | if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) { | ||
2704 | retval = hw_device_reset(udc); | ||
2705 | if (retval) | ||
2706 | goto put_transceiver; | ||
2707 | } | ||
2708 | |||
2631 | retval = device_register(&udc->gadget.dev); | 2709 | retval = device_register(&udc->gadget.dev); |
2632 | if (retval) | 2710 | if (retval) { |
2633 | goto done; | 2711 | put_device(&udc->gadget.dev); |
2712 | goto put_transceiver; | ||
2713 | } | ||
2634 | 2714 | ||
2635 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 2715 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
2636 | retval = dbg_create_files(&udc->gadget.dev); | 2716 | retval = dbg_create_files(&udc->gadget.dev); |
2637 | #endif | 2717 | #endif |
2638 | if (retval) { | 2718 | if (retval) |
2639 | device_unregister(&udc->gadget.dev); | 2719 | goto unreg_device; |
2640 | goto done; | 2720 | |
2721 | if (udc->transceiver) { | ||
2722 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
2723 | if (retval) | ||
2724 | goto remove_dbg; | ||
2641 | } | 2725 | } |
2642 | 2726 | ||
2643 | _udc = udc; | 2727 | _udc = udc; |
2644 | return retval; | 2728 | return retval; |
2645 | 2729 | ||
2646 | done: | ||
2647 | err("error = %i", retval); | 2730 | err("error = %i", retval); |
2731 | remove_dbg: | ||
2732 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
2733 | dbg_remove_files(&udc->gadget.dev); | ||
2734 | #endif | ||
2735 | unreg_device: | ||
2736 | device_unregister(&udc->gadget.dev); | ||
2737 | put_transceiver: | ||
2738 | if (udc->transceiver) | ||
2739 | otg_put_transceiver(udc->transceiver); | ||
2740 | free_udc: | ||
2648 | kfree(udc); | 2741 | kfree(udc); |
2649 | _udc = NULL; | 2742 | _udc = NULL; |
2650 | return retval; | 2743 | return retval; |
@@ -2664,6 +2757,10 @@ static void udc_remove(void) | |||
2664 | return; | 2757 | return; |
2665 | } | 2758 | } |
2666 | 2759 | ||
2760 | if (udc->transceiver) { | ||
2761 | otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
2762 | otg_put_transceiver(udc->transceiver); | ||
2763 | } | ||
2667 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 2764 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
2668 | dbg_remove_files(&udc->gadget.dev); | 2765 | dbg_remove_files(&udc->gadget.dev); |
2669 | #endif | 2766 | #endif |
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 4026e9cede34..4fd19313e238 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -97,9 +97,24 @@ struct ci13xxx_ep { | |||
97 | struct dma_pool *td_pool; | 97 | struct dma_pool *td_pool; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct ci13xxx; | ||
101 | struct ci13xxx_udc_driver { | ||
102 | const char *name; | ||
103 | unsigned long flags; | ||
104 | #define CI13XXX_REGS_SHARED BIT(0) | ||
105 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) | ||
106 | #define CI13XXX_PULLUP_ON_VBUS BIT(2) | ||
107 | #define CI13XXX_DISABLE_STREAMING BIT(3) | ||
108 | |||
109 | #define CI13XXX_CONTROLLER_RESET_EVENT 0 | ||
110 | #define CI13XXX_CONTROLLER_STOPPED_EVENT 1 | ||
111 | void (*notify_event) (struct ci13xxx *udc, unsigned event); | ||
112 | }; | ||
113 | |||
100 | /* CI13XXX UDC descriptor & global resources */ | 114 | /* CI13XXX UDC descriptor & global resources */ |
101 | struct ci13xxx { | 115 | struct ci13xxx { |
102 | spinlock_t *lock; /* ctrl register bank access */ | 116 | spinlock_t *lock; /* ctrl register bank access */ |
117 | void __iomem *regs; /* registers address space */ | ||
103 | 118 | ||
104 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ | 119 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ |
105 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ | 120 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ |
@@ -108,6 +123,9 @@ struct ci13xxx { | |||
108 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | 123 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
109 | 124 | ||
110 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | 125 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
126 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ | ||
127 | int vbus_active; /* is VBUS active */ | ||
128 | struct otg_transceiver *transceiver; /* Transceiver struct */ | ||
111 | }; | 129 | }; |
112 | 130 | ||
113 | /****************************************************************************** | 131 | /****************************************************************************** |
@@ -157,6 +175,7 @@ struct ci13xxx { | |||
157 | #define USBMODE_CM_DEVICE (0x02UL << 0) | 175 | #define USBMODE_CM_DEVICE (0x02UL << 0) |
158 | #define USBMODE_CM_HOST (0x03UL << 0) | 176 | #define USBMODE_CM_HOST (0x03UL << 0) |
159 | #define USBMODE_SLOM BIT(3) | 177 | #define USBMODE_SLOM BIT(3) |
178 | #define USBMODE_SDIS BIT(4) | ||
160 | 179 | ||
161 | /* ENDPTCTRL */ | 180 | /* ENDPTCTRL */ |
162 | #define ENDPTCTRL_RXS BIT(0) | 181 | #define ENDPTCTRL_RXS BIT(0) |