Преглед на файлове

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.
Greg Kroah-Hartman преди 9 години
родител
ревизия
f21ca2c999

+ 2 - 0
Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt

@@ -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:

+ 1 - 0
Documentation/devicetree/bindings/usb/usbmisc-imx.txt

@@ -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:

+ 3 - 0
drivers/usb/chipidea/ci_hdrc_imx.c

@@ -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;
 
 

+ 1 - 0
drivers/usb/chipidea/ci_hdrc_imx.h

@@ -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 */
 };
 };
 
 

+ 3 - 0
drivers/usb/chipidea/host.c

@@ -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;

+ 18 - 24
drivers/usb/chipidea/udc.c

@@ -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;
 
 

+ 17 - 5
drivers/usb/chipidea/usbmisc_imx.c

@@ -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)
 
 
 	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);
-		writel(reg | MX6_BM_OVER_CUR_DIS,
-			usbmisc->base + data->index * 4);
+		reg |= MX6_BM_OVER_CUR_DIS;
+	} else if (data->oc_polarity == 1) {
+		/* 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)
 		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);
-		writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base);
+		reg |= MX6_BM_OVER_CUR_DIS;
+	} 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[] = {
 		.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);