|
@@ -59,7 +59,7 @@ ctrl_endpt_in_desc = {
|
|
*/
|
|
*/
|
|
static inline int hw_ep_bit(int num, int dir)
|
|
static inline int hw_ep_bit(int num, int dir)
|
|
{
|
|
{
|
|
- return num + (dir ? 16 : 0);
|
|
|
|
|
|
+ return num + ((dir == TX) ? 16 : 0);
|
|
}
|
|
}
|
|
|
|
|
|
static inline int ep_to_bit(struct ci_hdrc *ci, int n)
|
|
static inline int ep_to_bit(struct ci_hdrc *ci, int n)
|
|
@@ -121,9 +121,8 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir)
|
|
*/
|
|
*/
|
|
static int hw_ep_disable(struct ci_hdrc *ci, int num, int dir)
|
|
static int hw_ep_disable(struct ci_hdrc *ci, int num, int dir)
|
|
{
|
|
{
|
|
- hw_ep_flush(ci, num, dir);
|
|
|
|
hw_write(ci, OP_ENDPTCTRL + num,
|
|
hw_write(ci, OP_ENDPTCTRL + num,
|
|
- dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
|
|
|
|
|
|
+ (dir == TX) ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -139,7 +138,7 @@ static int hw_ep_enable(struct ci_hdrc *ci, int num, int dir, int type)
|
|
{
|
|
{
|
|
u32 mask, data;
|
|
u32 mask, data;
|
|
|
|
|
|
- if (dir) {
|
|
|
|
|
|
+ if (dir == TX) {
|
|
mask = ENDPTCTRL_TXT; /* type */
|
|
mask = ENDPTCTRL_TXT; /* type */
|
|
data = type << __ffs(mask);
|
|
data = type << __ffs(mask);
|
|
|
|
|
|
@@ -171,7 +170,7 @@ static int hw_ep_enable(struct ci_hdrc *ci, int num, int dir, int type)
|
|
*/
|
|
*/
|
|
static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir)
|
|
static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir)
|
|
{
|
|
{
|
|
- u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
|
|
|
|
|
|
+ u32 mask = (dir == TX) ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
|
|
|
|
|
|
return hw_read(ci, OP_ENDPTCTRL + num, mask) ? 1 : 0;
|
|
return hw_read(ci, OP_ENDPTCTRL + num, mask) ? 1 : 0;
|
|
}
|
|
}
|
|
@@ -188,6 +187,9 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl)
|
|
{
|
|
{
|
|
int n = hw_ep_bit(num, dir);
|
|
int n = hw_ep_bit(num, dir);
|
|
|
|
|
|
|
|
+ /* Synchronize before ep prime */
|
|
|
|
+ wmb();
|
|
|
|
+
|
|
if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num)))
|
|
if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num)))
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
|
|
|
|
@@ -218,8 +220,8 @@ static int hw_ep_set_halt(struct ci_hdrc *ci, int num, int dir, int value)
|
|
|
|
|
|
do {
|
|
do {
|
|
enum ci_hw_regs reg = OP_ENDPTCTRL + num;
|
|
enum ci_hw_regs reg = OP_ENDPTCTRL + num;
|
|
- u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
|
|
|
|
- u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
|
|
|
|
|
|
+ u32 mask_xs = (dir == TX) ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
|
|
|
|
+ u32 mask_xr = (dir == TX) ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
|
|
|
|
|
|
/* data toggle - reserved for EP0 but it's in ESS */
|
|
/* data toggle - reserved for EP0 but it's in ESS */
|
|
hw_write(ci, reg, mask_xs|mask_xr,
|
|
hw_write(ci, reg, mask_xs|mask_xr,
|
|
@@ -348,8 +350,7 @@ static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq,
|
|
if (node == NULL)
|
|
if (node == NULL)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- node->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC,
|
|
|
|
- &node->dma);
|
|
|
|
|
|
+ node->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC, &node->dma);
|
|
if (node->ptr == NULL) {
|
|
if (node->ptr == NULL) {
|
|
kfree(node);
|
|
kfree(node);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -506,8 +507,6 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
|
|
hwep->qh.ptr->cap |= mul << __ffs(QH_MULT);
|
|
hwep->qh.ptr->cap |= mul << __ffs(QH_MULT);
|
|
}
|
|
}
|
|
|
|
|
|
- wmb(); /* synchronize before ep prime */
|
|
|
|
-
|
|
|
|
ret = hw_ep_prime(ci, hwep->num, hwep->dir,
|
|
ret = hw_ep_prime(ci, hwep->num, hwep->dir,
|
|
hwep->type == USB_ENDPOINT_XFER_CONTROL);
|
|
hwep->type == USB_ENDPOINT_XFER_CONTROL);
|
|
done:
|
|
done:
|
|
@@ -534,9 +533,6 @@ static int reprime_dtd(struct ci_hdrc *ci, struct ci_hw_ep *hwep,
|
|
hwep->qh.ptr->td.token &=
|
|
hwep->qh.ptr->td.token &=
|
|
cpu_to_le32(~(TD_STATUS_HALTED | TD_STATUS_ACTIVE));
|
|
cpu_to_le32(~(TD_STATUS_HALTED | TD_STATUS_ACTIVE));
|
|
|
|
|
|
- /* Synchronize before ep prime */
|
|
|
|
- wmb();
|
|
|
|
-
|
|
|
|
return hw_ep_prime(ci, hwep->num, hwep->dir,
|
|
return hw_ep_prime(ci, hwep->num, hwep->dir,
|
|
hwep->type == USB_ENDPOINT_XFER_CONTROL);
|
|
hwep->type == USB_ENDPOINT_XFER_CONTROL);
|
|
}
|
|
}
|
|
@@ -590,7 +586,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
|
|
}
|
|
}
|
|
|
|
|
|
if (remaining_length) {
|
|
if (remaining_length) {
|
|
- if (hwep->dir) {
|
|
|
|
|
|
+ if (hwep->dir == TX) {
|
|
hwreq->req.status = -EPROTO;
|
|
hwreq->req.status = -EPROTO;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1051,9 +1047,9 @@ __acquires(ci->lock)
|
|
if (req.wLength != 0)
|
|
if (req.wLength != 0)
|
|
break;
|
|
break;
|
|
num = le16_to_cpu(req.wIndex);
|
|
num = le16_to_cpu(req.wIndex);
|
|
- dir = num & USB_ENDPOINT_DIR_MASK;
|
|
|
|
|
|
+ dir = (num & USB_ENDPOINT_DIR_MASK) ? TX : RX;
|
|
num &= USB_ENDPOINT_NUMBER_MASK;
|
|
num &= USB_ENDPOINT_NUMBER_MASK;
|
|
- if (dir) /* TX */
|
|
|
|
|
|
+ if (dir == TX)
|
|
num += ci->hw_ep_max / 2;
|
|
num += ci->hw_ep_max / 2;
|
|
if (!ci->ci_hw_ep[num].wedge) {
|
|
if (!ci->ci_hw_ep[num].wedge) {
|
|
spin_unlock(&ci->lock);
|
|
spin_unlock(&ci->lock);
|
|
@@ -1103,9 +1099,9 @@ __acquires(ci->lock)
|
|
if (req.wLength != 0)
|
|
if (req.wLength != 0)
|
|
break;
|
|
break;
|
|
num = le16_to_cpu(req.wIndex);
|
|
num = le16_to_cpu(req.wIndex);
|
|
- dir = num & USB_ENDPOINT_DIR_MASK;
|
|
|
|
|
|
+ dir = (num & USB_ENDPOINT_DIR_MASK) ? TX : RX;
|
|
num &= USB_ENDPOINT_NUMBER_MASK;
|
|
num &= USB_ENDPOINT_NUMBER_MASK;
|
|
- if (dir) /* TX */
|
|
|
|
|
|
+ if (dir == TX)
|
|
num += ci->hw_ep_max / 2;
|
|
num += ci->hw_ep_max / 2;
|
|
|
|
|
|
spin_unlock(&ci->lock);
|
|
spin_unlock(&ci->lock);
|
|
@@ -1680,12 +1676,10 @@ static int init_eps(struct ci_hdrc *ci)
|
|
usb_ep_set_maxpacket_limit(&hwep->ep, (unsigned short)~0);
|
|
usb_ep_set_maxpacket_limit(&hwep->ep, (unsigned short)~0);
|
|
|
|
|
|
INIT_LIST_HEAD(&hwep->qh.queue);
|
|
INIT_LIST_HEAD(&hwep->qh.queue);
|
|
- hwep->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL,
|
|
|
|
- &hwep->qh.dma);
|
|
|
|
|
|
+ hwep->qh.ptr = dma_pool_zalloc(ci->qh_pool, GFP_KERNEL,
|
|
|
|
+ &hwep->qh.dma);
|
|
if (hwep->qh.ptr == NULL)
|
|
if (hwep->qh.ptr == NULL)
|
|
retval = -ENOMEM;
|
|
retval = -ENOMEM;
|
|
- else
|
|
|
|
- memset(hwep->qh.ptr, 0, sizeof(*hwep->qh.ptr));
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* set up shorthands for ep0 out and in endpoints,
|
|
* set up shorthands for ep0 out and in endpoints,
|
|
@@ -1999,7 +1993,7 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)
|
|
if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC))
|
|
if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC))
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
|
|
|
|
- rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
|
|
|
|
|
|
+ rdrv = devm_kzalloc(ci->dev, sizeof(*rdrv), GFP_KERNEL);
|
|
if (!rdrv)
|
|
if (!rdrv)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|