Commit f21ca2c9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'usb-ci-v4.9-rc1' of...

Merge tag 'usb-ci-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-testing

Peter writes:

Most of them are refine patches, only new feature is
disable io watchdog for chipidea platform.
parents 81522637 e74e8372
...@@ -81,6 +81,8 @@ i.mx specific properties ...@@ -81,6 +81,8 @@ i.mx specific properties
- fsl,usbmisc: phandler of non-core register device, with one - fsl,usbmisc: phandler of non-core register device, with one
argument that indicate usb controller index argument that indicate usb controller index
- disable-over-current: disable over current detect - disable-over-current: disable over current detect
- over-current-active-high: over current signal polarity is high active,
typically over current signal polarity is low active.
- external-vbus-divider: enables off-chip resistor divider for Vbus - external-vbus-divider: enables off-chip resistor divider for Vbus
Example: Example:
......
...@@ -6,6 +6,7 @@ Required properties: ...@@ -6,6 +6,7 @@ Required properties:
"fsl,imx6q-usbmisc" for imx6q "fsl,imx6q-usbmisc" for imx6q
"fsl,vf610-usbmisc" for Vybrid vf610 "fsl,vf610-usbmisc" for Vybrid vf610
"fsl,imx6sx-usbmisc" for imx6sx "fsl,imx6sx-usbmisc" for imx6sx
"fsl,imx7d-usbmisc" for imx7d
- reg: Should contain registers location and length - reg: Should contain registers location and length
Examples: Examples:
......
...@@ -140,6 +140,9 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) ...@@ -140,6 +140,9 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
if (of_find_property(np, "disable-over-current", NULL)) if (of_find_property(np, "disable-over-current", NULL))
data->disable_oc = 1; data->disable_oc = 1;
if (of_find_property(np, "over-current-active-high", NULL))
data->oc_polarity = 1;
if (of_find_property(np, "external-vbus-divider", NULL)) if (of_find_property(np, "external-vbus-divider", NULL))
data->evdo = 1; data->evdo = 1;
......
...@@ -17,6 +17,7 @@ struct imx_usbmisc_data { ...@@ -17,6 +17,7 @@ struct imx_usbmisc_data {
int index; int index;
unsigned int disable_oc:1; /* over current detect disabled */ unsigned int disable_oc:1; /* over current detect disabled */
unsigned int oc_polarity:1; /* over current polarity if oc enabled */
unsigned int evdo:1; /* set external vbus divider option */ unsigned int evdo:1; /* set external vbus divider option */
}; };
......
...@@ -81,12 +81,15 @@ static int ehci_ci_reset(struct usb_hcd *hcd) ...@@ -81,12 +81,15 @@ static int ehci_ci_reset(struct usb_hcd *hcd)
{ {
struct device *dev = hcd->self.controller; struct device *dev = hcd->self.controller;
struct ci_hdrc *ci = dev_get_drvdata(dev); struct ci_hdrc *ci = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int ret; int ret;
ret = ehci_setup(hcd); ret = ehci_setup(hcd);
if (ret) if (ret)
return ret; return ret;
ehci->need_io_watchdog = 0;
ci_platform_configure(ci); ci_platform_configure(ci);
return ret; return ret;
......
...@@ -59,7 +59,7 @@ ctrl_endpt_in_desc = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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_xs = (dir == TX) ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; 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, ...@@ -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->ptr = dma_pool_zalloc(hwep->td_pool, GFP_ATOMIC, &node->dma);
&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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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.ptr = dma_pool_zalloc(ci->qh_pool, GFP_KERNEL,
&hwep->qh.dma); &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) ...@@ -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;
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#define MX6_BM_NON_BURST_SETTING BIT(1) #define MX6_BM_NON_BURST_SETTING BIT(1)
#define MX6_BM_OVER_CUR_DIS BIT(7) #define MX6_BM_OVER_CUR_DIS BIT(7)
#define MX6_BM_OVER_CUR_POLARITY BIT(8)
#define MX6_BM_WAKEUP_ENABLE BIT(10) #define MX6_BM_WAKEUP_ENABLE BIT(10)
#define MX6_BM_ID_WAKEUP BIT(16) #define MX6_BM_ID_WAKEUP BIT(16)
#define MX6_BM_VBUS_WAKEUP BIT(17) #define MX6_BM_VBUS_WAKEUP BIT(17)
...@@ -266,11 +267,14 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) ...@@ -266,11 +267,14 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
spin_lock_irqsave(&usbmisc->lock, flags); spin_lock_irqsave(&usbmisc->lock, flags);
reg = readl(usbmisc->base + data->index * 4);
if (data->disable_oc) { if (data->disable_oc) {
reg = readl(usbmisc->base + data->index * 4); reg |= MX6_BM_OVER_CUR_DIS;
writel(reg | MX6_BM_OVER_CUR_DIS, } else if (data->oc_polarity == 1) {
usbmisc->base + data->index * 4); /* High active */
reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
} }
writel(reg, usbmisc->base + data->index * 4);
/* SoC non-burst setting */ /* SoC non-burst setting */
reg = readl(usbmisc->base + data->index * 4); reg = readl(usbmisc->base + data->index * 4);
...@@ -365,10 +369,14 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) ...@@ -365,10 +369,14 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&usbmisc->lock, flags); spin_lock_irqsave(&usbmisc->lock, flags);
reg = readl(usbmisc->base);
if (data->disable_oc) { if (data->disable_oc) {
reg = readl(usbmisc->base); reg |= MX6_BM_OVER_CUR_DIS;
writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base); } else if (data->oc_polarity == 1) {
/* High active */
reg &= ~(MX6_BM_OVER_CUR_DIS | MX6_BM_OVER_CUR_POLARITY);
} }
writel(reg, usbmisc->base);
reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
...@@ -492,6 +500,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { ...@@ -492,6 +500,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
.compatible = "fsl,imx6ul-usbmisc", .compatible = "fsl,imx6ul-usbmisc",
.data = &imx6sx_usbmisc_ops, .data = &imx6sx_usbmisc_ops,
}, },
{
.compatible = "fsl,imx7d-usbmisc",
.data = &imx7d_usbmisc_ops,
},
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment