diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 14:05:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 14:05:11 -0400 |
commit | 08d9c74d45ceb581c11d2ab265c32236b0321a56 (patch) | |
tree | 12ce14cf9d65ce49eed8518a144a96f9aa60014a /drivers/usb/chipidea | |
parent | 1f2235b8e79bd276f19809f7f2a270f55909d695 (diff) | |
parent | db89960e50f45274c07dc60926b5a49489b8a7a0 (diff) |
Merge branch 'chipidea-stable' into usb-next
These chipidea stable patches are needed for other chipidea patches to be
applied properly.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r-- | drivers/usb/chipidea/udc.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c7a032a4f0c5..d214448b677e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | 81 | * hw_device_state: enables/disables interrupts (execute without interruption) |
82 | * without interruption) | ||
83 | * @dma: 0 => disable, !0 => enable and set dma engine | 82 | * @dma: 0 => disable, !0 => enable and set dma engine |
84 | * | 83 | * |
85 | * This function returns an error code | 84 | * This function returns an error code |
@@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma) | |||
91 | /* interrupt, error, port change, reset, sleep/suspend */ | 90 | /* interrupt, error, port change, reset, sleep/suspend */ |
92 | hw_write(ci, OP_USBINTR, ~0, | 91 | hw_write(ci, OP_USBINTR, ~0, |
93 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | 92 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); |
94 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
95 | } else { | 93 | } else { |
96 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
97 | hw_write(ci, OP_USBINTR, ~0, 0); | 94 | hw_write(ci, OP_USBINTR, ~0, 0); |
98 | } | 95 | } |
99 | return 0; | 96 | return 0; |
@@ -774,10 +771,7 @@ __acquires(mEp->lock) | |||
774 | { | 771 | { |
775 | struct ci13xxx_req *mReq, *mReqTemp; | 772 | struct ci13xxx_req *mReq, *mReqTemp; |
776 | struct ci13xxx_ep *mEpTemp = mEp; | 773 | struct ci13xxx_ep *mEpTemp = mEp; |
777 | int uninitialized_var(retval); | 774 | int retval = 0; |
778 | |||
779 | if (list_empty(&mEp->qh.queue)) | ||
780 | return -EINVAL; | ||
781 | 775 | ||
782 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, | 776 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, |
783 | queue) { | 777 | queue) { |
@@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1420 | return -ENOTSUPP; | 1414 | return -ENOTSUPP; |
1421 | } | 1415 | } |
1422 | 1416 | ||
1417 | /* Change Data+ pullup status | ||
1418 | * this func is used by usb_gadget_connect/disconnet | ||
1419 | */ | ||
1420 | static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) | ||
1421 | { | ||
1422 | struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); | ||
1423 | |||
1424 | if (is_on) | ||
1425 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
1426 | else | ||
1427 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1423 | static int ci13xxx_start(struct usb_gadget *gadget, | 1432 | static int ci13xxx_start(struct usb_gadget *gadget, |
1424 | struct usb_gadget_driver *driver); | 1433 | struct usb_gadget_driver *driver); |
1425 | static int ci13xxx_stop(struct usb_gadget *gadget, | 1434 | static int ci13xxx_stop(struct usb_gadget *gadget, |
@@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget, | |||
1432 | static const struct usb_gadget_ops usb_gadget_ops = { | 1441 | static const struct usb_gadget_ops usb_gadget_ops = { |
1433 | .vbus_session = ci13xxx_vbus_session, | 1442 | .vbus_session = ci13xxx_vbus_session, |
1434 | .wakeup = ci13xxx_wakeup, | 1443 | .wakeup = ci13xxx_wakeup, |
1444 | .pullup = ci13xxx_pullup, | ||
1435 | .vbus_draw = ci13xxx_vbus_draw, | 1445 | .vbus_draw = ci13xxx_vbus_draw, |
1436 | .udc_start = ci13xxx_start, | 1446 | .udc_start = ci13xxx_start, |
1437 | .udc_stop = ci13xxx_stop, | 1447 | .udc_stop = ci13xxx_stop, |
@@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci) | |||
1455 | 1465 | ||
1456 | mEp->ep.name = mEp->name; | 1466 | mEp->ep.name = mEp->name; |
1457 | mEp->ep.ops = &usb_ep_ops; | 1467 | mEp->ep.ops = &usb_ep_ops; |
1458 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | 1468 | /* |
1469 | * for ep0: maxP defined in desc, for other | ||
1470 | * eps, maxP is set by epautoconfig() called | ||
1471 | * by gadget layer | ||
1472 | */ | ||
1473 | mEp->ep.maxpacket = (unsigned short)~0; | ||
1459 | 1474 | ||
1460 | INIT_LIST_HEAD(&mEp->qh.queue); | 1475 | INIT_LIST_HEAD(&mEp->qh.queue); |
1461 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, | 1476 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, |
@@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci) | |||
1475 | else | 1490 | else |
1476 | ci->ep0in = mEp; | 1491 | ci->ep0in = mEp; |
1477 | 1492 | ||
1493 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
1478 | continue; | 1494 | continue; |
1479 | } | 1495 | } |
1480 | 1496 | ||
@@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci) | |||
1484 | return retval; | 1500 | return retval; |
1485 | } | 1501 | } |
1486 | 1502 | ||
1503 | static void destroy_eps(struct ci13xxx *ci) | ||
1504 | { | ||
1505 | int i; | ||
1506 | |||
1507 | for (i = 0; i < ci->hw_ep_max; i++) { | ||
1508 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1509 | |||
1510 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1487 | /** | 1514 | /** |
1488 | * ci13xxx_start: register a gadget driver | 1515 | * ci13xxx_start: register a gadget driver |
1489 | * @gadget: our gadget | 1516 | * @gadget: our gadget |
@@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1691 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | 1718 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { |
1692 | if (ci->transceiver == NULL) { | 1719 | if (ci->transceiver == NULL) { |
1693 | retval = -ENODEV; | 1720 | retval = -ENODEV; |
1694 | goto free_pools; | 1721 | goto destroy_eps; |
1695 | } | 1722 | } |
1696 | } | 1723 | } |
1697 | 1724 | ||
@@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1729 | 1756 | ||
1730 | remove_trans: | 1757 | remove_trans: |
1731 | if (!IS_ERR_OR_NULL(ci->transceiver)) { | 1758 | if (!IS_ERR_OR_NULL(ci->transceiver)) { |
1732 | otg_set_peripheral(ci->transceiver->otg, &ci->gadget); | 1759 | otg_set_peripheral(ci->transceiver->otg, NULL); |
1733 | if (ci->global_phy) | 1760 | if (ci->global_phy) |
1734 | usb_put_phy(ci->transceiver); | 1761 | usb_put_phy(ci->transceiver); |
1735 | } | 1762 | } |
@@ -1742,6 +1769,8 @@ unreg_device: | |||
1742 | put_transceiver: | 1769 | put_transceiver: |
1743 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) | 1770 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) |
1744 | usb_put_phy(ci->transceiver); | 1771 | usb_put_phy(ci->transceiver); |
1772 | destroy_eps: | ||
1773 | destroy_eps(ci); | ||
1745 | free_pools: | 1774 | free_pools: |
1746 | dma_pool_destroy(ci->td_pool); | 1775 | dma_pool_destroy(ci->td_pool); |
1747 | free_qh_pool: | 1776 | free_qh_pool: |
@@ -1756,18 +1785,12 @@ free_qh_pool: | |||
1756 | */ | 1785 | */ |
1757 | static void udc_stop(struct ci13xxx *ci) | 1786 | static void udc_stop(struct ci13xxx *ci) |
1758 | { | 1787 | { |
1759 | int i; | ||
1760 | |||
1761 | if (ci == NULL) | 1788 | if (ci == NULL) |
1762 | return; | 1789 | return; |
1763 | 1790 | ||
1764 | usb_del_gadget_udc(&ci->gadget); | 1791 | usb_del_gadget_udc(&ci->gadget); |
1765 | 1792 | ||
1766 | for (i = 0; i < ci->hw_ep_max; i++) { | 1793 | destroy_eps(ci); |
1767 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1768 | |||
1769 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1770 | } | ||
1771 | 1794 | ||
1772 | dma_pool_destroy(ci->td_pool); | 1795 | dma_pool_destroy(ci->td_pool); |
1773 | dma_pool_destroy(ci->qh_pool); | 1796 | dma_pool_destroy(ci->qh_pool); |