All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-25 19:21 ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-25 19:21 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-arm-kernel, linux-usb, linux-kernel, Sekhar Nori,
	Grygorii Strashko, David Fisher, Catalin Marinas,
	Thang Q. Nguyen, Yoshihiro Shimoda

Now not all DMA paremters configured properly for "xhci-hcd" platform
device which is created manually. For example: dma_pfn_offset, dam_ops
and iommu configuration will not corresponds "dwc3" devices
configuration. As result, this will cause problems like wrong DMA
addresses translation on platforms with LPAE enabled like Keystone 2.

When platform is using DT boot mode the DMA configuration will be
parsed and applied from DT, so, to fix this issue, reuse
of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
from DWC3 device node.

Cc: David Fisher <david.fisher1@synopsys.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: "Thang Q. Nguyen" <tqnguyen@apm.com>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/usb/dwc3/host.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index c679f63..93c8ef9 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -17,6 +17,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/of_device.h>
 
 #include "core.h"
 
@@ -32,12 +33,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 		return -ENOMEM;
 	}
 
-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
-
 	xhci->dev.parent	= dwc->dev;
-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
-
 	dwc->xhci = xhci;
 
 	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
@@ -62,6 +58,15 @@ int dwc3_host_init(struct dwc3 *dwc)
 	phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
 			  dev_name(&xhci->dev));
 
+	if (IS_ENABLED(CONFIG_OF) && dwc->dev->of_node) {
+		of_dma_configure(&xhci->dev, dwc->dev->of_node);
+	} else {
+		dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
+
+		xhci->dev.dma_mask	= dwc->dev->dma_mask;
+		xhci->dev.dma_parms	= dwc->dev->dma_parms;
+	}
+
 	ret = platform_device_add(xhci);
 	if (ret) {
 		dev_err(dwc->dev, "failed to register xHCI device\n");
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-25 19:21 ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-25 19:21 UTC (permalink / raw)
  To: linux-arm-kernel

Now not all DMA paremters configured properly for "xhci-hcd" platform
device which is created manually. For example: dma_pfn_offset, dam_ops
and iommu configuration will not corresponds "dwc3" devices
configuration. As result, this will cause problems like wrong DMA
addresses translation on platforms with LPAE enabled like Keystone 2.

When platform is using DT boot mode the DMA configuration will be
parsed and applied from DT, so, to fix this issue, reuse
of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
from DWC3 device node.

Cc: David Fisher <david.fisher1@synopsys.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: "Thang Q. Nguyen" <tqnguyen@apm.com>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/usb/dwc3/host.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index c679f63..93c8ef9 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -17,6 +17,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/of_device.h>
 
 #include "core.h"
 
@@ -32,12 +33,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 		return -ENOMEM;
 	}
 
-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
-
 	xhci->dev.parent	= dwc->dev;
-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
-
 	dwc->xhci = xhci;
 
 	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
@@ -62,6 +58,15 @@ int dwc3_host_init(struct dwc3 *dwc)
 	phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
 			  dev_name(&xhci->dev));
 
+	if (IS_ENABLED(CONFIG_OF) && dwc->dev->of_node) {
+		of_dma_configure(&xhci->dev, dwc->dev->of_node);
+	} else {
+		dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
+
+		xhci->dev.dma_mask	= dwc->dev->dma_mask;
+		xhci->dev.dma_parms	= dwc->dev->dma_parms;
+	}
+
 	ret = platform_device_add(xhci);
 	if (ret) {
 		dev_err(dwc->dev, "failed to register xHCI device\n");
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-25 19:21 ` Grygorii Strashko
@ 2016-04-26  6:17   ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-26  6:17 UTC (permalink / raw)
  To: Grygorii Strashko, Greg Kroah-Hartman
  Cc: linux-arm-kernel, linux-usb, linux-kernel, Sekhar Nori,
	Grygorii Strashko, David Fisher, Catalin Marinas,
	Thang Q. Nguyen, Yoshihiro Shimoda

[-- Attachment #1: Type: text/plain, Size: 752 bytes --]


Hi,

Grygorii Strashko <grygorii.strashko@ti.com> writes:
> Now not all DMA paremters configured properly for "xhci-hcd" platform
> device which is created manually. For example: dma_pfn_offset, dam_ops
> and iommu configuration will not corresponds "dwc3" devices
> configuration. As result, this will cause problems like wrong DMA
> addresses translation on platforms with LPAE enabled like Keystone 2.
>
> When platform is using DT boot mode the DMA configuration will be
> parsed and applied from DT, so, to fix this issue, reuse
> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> from DWC3 device node.

patch is incomplete. You left out non-DT users which might suffer from
the same problem.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-26  6:17   ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-26  6:17 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Grygorii Strashko <grygorii.strashko@ti.com> writes:
> Now not all DMA paremters configured properly for "xhci-hcd" platform
> device which is created manually. For example: dma_pfn_offset, dam_ops
> and iommu configuration will not corresponds "dwc3" devices
> configuration. As result, this will cause problems like wrong DMA
> addresses translation on platforms with LPAE enabled like Keystone 2.
>
> When platform is using DT boot mode the DMA configuration will be
> parsed and applied from DT, so, to fix this issue, reuse
> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> from DWC3 device node.

patch is incomplete. You left out non-DT users which might suffer from
the same problem.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160426/4123100d/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-26  6:17   ` Felipe Balbi
@ 2016-04-26  8:14     ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-26  8:14 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-arm-kernel, linux-usb, linux-kernel, Sekhar Nori,
	David Fisher, Catalin Marinas, Thang Q. Nguyen,
	Yoshihiro Shimoda

On 04/26/2016 09:17 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>> device which is created manually. For example: dma_pfn_offset, dam_ops
>> and iommu configuration will not corresponds "dwc3" devices
>> configuration. As result, this will cause problems like wrong DMA
>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>
>> When platform is using DT boot mode the DMA configuration will be
>> parsed and applied from DT, so, to fix this issue, reuse
>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>> from DWC3 device node.
> 
> patch is incomplete. You left out non-DT users which might suffer from
> the same problem.
> 

Honestly, I don't know how to fix it gracefully for non-DT case.
I can update commit message to mention that this is fix for DT case only.


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-26  8:14     ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-26  8:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/26/2016 09:17 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>> device which is created manually. For example: dma_pfn_offset, dam_ops
>> and iommu configuration will not corresponds "dwc3" devices
>> configuration. As result, this will cause problems like wrong DMA
>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>
>> When platform is using DT boot mode the DMA configuration will be
>> parsed and applied from DT, so, to fix this issue, reuse
>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>> from DWC3 device node.
> 
> patch is incomplete. You left out non-DT users which might suffer from
> the same problem.
> 

Honestly, I don't know how to fix it gracefully for non-DT case.
I can update commit message to mention that this is fix for DT case only.


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-26  8:14     ` Grygorii Strashko
@ 2016-04-27  5:41       ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27  5:41 UTC (permalink / raw)
  To: Grygorii Strashko, Greg Kroah-Hartman
  Cc: linux-arm-kernel, linux-usb, linux-kernel, Sekhar Nori,
	David Fisher, Catalin Marinas, Thang Q. Nguyen,
	Yoshihiro Shimoda

[-- Attachment #1: Type: text/plain, Size: 8251 bytes --]


Hi,

Grygorii Strashko <grygorii.strashko@ti.com> writes:
> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>> 
>> Hi,
>> 
>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>> and iommu configuration will not corresponds "dwc3" devices
>>> configuration. As result, this will cause problems like wrong DMA
>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>
>>> When platform is using DT boot mode the DMA configuration will be
>>> parsed and applied from DT, so, to fix this issue, reuse
>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>> from DWC3 device node.
>> 
>> patch is incomplete. You left out non-DT users which might suffer from
>> the same problem.
>> 
>
> Honestly, I don't know how to fix it gracefully for non-DT case.
> I can update commit message to mention that this is fix for DT case only.

no, that won't do :-) There are other users for this driver and they are
all "out-of-compliance" when it comes to DMA usage. Apparently, the
desired behavior is to pass correct device to DMA API which the gadget
side is already doing (see below). For the host side, the fix has to be
more involved.

Frankly, I'd prefer that DMA setup could be inherited from parent
device, then it wouldn't really matter and a bunch of this could be
simplified. Some sort of dma_inherit(struct device *dev, struct device
*parent) would go a long way, IMHO.

8<-------------------------------- cut here ------------------------
commit 2725d6f974c4c268ae5fb746f8e3b33b76135aa8
Author: Felipe Balbi <felipe.balbi@linux.intel.com>
Date:   Tue Apr 19 16:18:12 2016 +0300

    usb: dwc3: use parent device for DMA
    
    our parent device is the one which was initialized
    by either PCI or DeviceTree and that's the one which
    is configured properly for DMA access.
    
    Instead of copying DMA bits from parent to child,
    let's just rely on parent device for the entire DMA
    API.
    
    Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c050a88c16d4..09e4ff71a50f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -180,7 +180,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
 static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
 		struct dwc3_event_buffer *evt)
 {
-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
+	dma_free_coherent(dwc->dev->parent, evt->length, evt->buf, evt->dma);
 }
 
 /**
@@ -202,7 +202,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 
 	evt->dwc	= dwc;
 	evt->length	= length;
-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
+	evt->buf	= dma_alloc_coherent(dwc->dev->parent, length,
 			&evt->dma, GFP_KERNEL);
 	if (!evt->buf)
 		return ERR_PTR(-ENOMEM);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 143deb420481..c78238dc76fc 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -967,7 +967,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 		u32	transfer_size = 0;
 		u32	maxpacket;
 
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+		ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 				dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request\n");
@@ -995,7 +995,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 				dwc->ep0_bounce_addr, transfer_size,
 				DWC3_TRBCTL_CONTROL_DATA, false);
 	} else {
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+		ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 				dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request\n");
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 88fd30bf0c46..6929775bde57 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -191,7 +191,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (dwc->ep0_bounced && dep->number == 0)
 		dwc->ep0_bounced = false;
 	else
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
+		usb_gadget_unmap_request_by_dev(dwc->dev->parent, &req->request,
 				req->direction);
 
 	trace_dwc3_gadget_giveback(req);
@@ -335,7 +335,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 	if (dep->trb_pool)
 		return 0;
 
-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
+	dep->trb_pool = dma_alloc_coherent(dwc->dev->parent,
 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			&dep->trb_pool_dma, GFP_KERNEL);
 	if (!dep->trb_pool) {
@@ -351,7 +351,8 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
 	struct dwc3		*dwc = dep->dwc;
 
-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+	dma_free_coherent(dwc->dev->parent,
+			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			dep->trb_pool, dep->trb_pool_dma);
 
 	dep->trb_pool = NULL;
@@ -972,7 +973,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 		 * here and stop, unmap, free and del each of the linked
 		 * requests instead of what we do now.
 		 */
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
+		usb_gadget_unmap_request_by_dev(dwc->dev->parent, &req->request,
 				req->direction);
 		list_del(&req->list);
 		return ret;
@@ -1057,7 +1058,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * This will also avoid Host cancelling URBs due to too
 	 * many NAKs.
 	 */
-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+	ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 			dep->direction);
 	if (ret)
 		return ret;
@@ -2734,7 +2735,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 {
 	int					ret;
 
-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dwc->ctrl_req = dma_alloc_coherent(dwc->dev->parent,
+			sizeof(*dwc->ctrl_req),
 			&dwc->ctrl_req_addr, GFP_KERNEL);
 	if (!dwc->ctrl_req) {
 		dev_err(dwc->dev, "failed to allocate ctrl request\n");
@@ -2742,7 +2744,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err0;
 	}
 
-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+	dwc->ep0_trb = dma_alloc_coherent(dwc->dev->parent,
+			sizeof(*dwc->ep0_trb) * 2,
 			&dwc->ep0_trb_addr, GFP_KERNEL);
 	if (!dwc->ep0_trb) {
 		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
@@ -2756,7 +2759,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err2;
 	}
 
-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
+	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev->parent,
 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
 			GFP_KERNEL);
 	if (!dwc->ep0_bounce) {
@@ -2828,18 +2831,18 @@ err5:
 
 err4:
 	dwc3_gadget_free_endpoints(dwc);
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->dev->parent, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
 	kfree(dwc->setup_buf);
 
 err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 
 err0:
@@ -2854,16 +2857,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
 	dwc3_gadget_free_endpoints(dwc);
 
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->dev->parent, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 	kfree(dwc->setup_buf);
 	kfree(dwc->zlp_buf);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 }
 


-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27  5:41       ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27  5:41 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Grygorii Strashko <grygorii.strashko@ti.com> writes:
> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>> 
>> Hi,
>> 
>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>> and iommu configuration will not corresponds "dwc3" devices
>>> configuration. As result, this will cause problems like wrong DMA
>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>
>>> When platform is using DT boot mode the DMA configuration will be
>>> parsed and applied from DT, so, to fix this issue, reuse
>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>> from DWC3 device node.
>> 
>> patch is incomplete. You left out non-DT users which might suffer from
>> the same problem.
>> 
>
> Honestly, I don't know how to fix it gracefully for non-DT case.
> I can update commit message to mention that this is fix for DT case only.

no, that won't do :-) There are other users for this driver and they are
all "out-of-compliance" when it comes to DMA usage. Apparently, the
desired behavior is to pass correct device to DMA API which the gadget
side is already doing (see below). For the host side, the fix has to be
more involved.

Frankly, I'd prefer that DMA setup could be inherited from parent
device, then it wouldn't really matter and a bunch of this could be
simplified. Some sort of dma_inherit(struct device *dev, struct device
*parent) would go a long way, IMHO.

8<-------------------------------- cut here ------------------------
commit 2725d6f974c4c268ae5fb746f8e3b33b76135aa8
Author: Felipe Balbi <felipe.balbi@linux.intel.com>
Date:   Tue Apr 19 16:18:12 2016 +0300

    usb: dwc3: use parent device for DMA
    
    our parent device is the one which was initialized
    by either PCI or DeviceTree and that's the one which
    is configured properly for DMA access.
    
    Instead of copying DMA bits from parent to child,
    let's just rely on parent device for the entire DMA
    API.
    
    Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c050a88c16d4..09e4ff71a50f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -180,7 +180,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
 static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
 		struct dwc3_event_buffer *evt)
 {
-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
+	dma_free_coherent(dwc->dev->parent, evt->length, evt->buf, evt->dma);
 }
 
 /**
@@ -202,7 +202,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 
 	evt->dwc	= dwc;
 	evt->length	= length;
-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
+	evt->buf	= dma_alloc_coherent(dwc->dev->parent, length,
 			&evt->dma, GFP_KERNEL);
 	if (!evt->buf)
 		return ERR_PTR(-ENOMEM);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 143deb420481..c78238dc76fc 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -967,7 +967,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 		u32	transfer_size = 0;
 		u32	maxpacket;
 
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+		ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 				dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request\n");
@@ -995,7 +995,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 				dwc->ep0_bounce_addr, transfer_size,
 				DWC3_TRBCTL_CONTROL_DATA, false);
 	} else {
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+		ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 				dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request\n");
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 88fd30bf0c46..6929775bde57 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -191,7 +191,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (dwc->ep0_bounced && dep->number == 0)
 		dwc->ep0_bounced = false;
 	else
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
+		usb_gadget_unmap_request_by_dev(dwc->dev->parent, &req->request,
 				req->direction);
 
 	trace_dwc3_gadget_giveback(req);
@@ -335,7 +335,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 	if (dep->trb_pool)
 		return 0;
 
-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
+	dep->trb_pool = dma_alloc_coherent(dwc->dev->parent,
 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			&dep->trb_pool_dma, GFP_KERNEL);
 	if (!dep->trb_pool) {
@@ -351,7 +351,8 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
 	struct dwc3		*dwc = dep->dwc;
 
-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+	dma_free_coherent(dwc->dev->parent,
+			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			dep->trb_pool, dep->trb_pool_dma);
 
 	dep->trb_pool = NULL;
@@ -972,7 +973,7 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 		 * here and stop, unmap, free and del each of the linked
 		 * requests instead of what we do now.
 		 */
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
+		usb_gadget_unmap_request_by_dev(dwc->dev->parent, &req->request,
 				req->direction);
 		list_del(&req->list);
 		return ret;
@@ -1057,7 +1058,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * This will also avoid Host cancelling URBs due to too
 	 * many NAKs.
 	 */
-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
+	ret = usb_gadget_map_request_by_dev(dwc->dev->parent, &req->request,
 			dep->direction);
 	if (ret)
 		return ret;
@@ -2734,7 +2735,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 {
 	int					ret;
 
-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dwc->ctrl_req = dma_alloc_coherent(dwc->dev->parent,
+			sizeof(*dwc->ctrl_req),
 			&dwc->ctrl_req_addr, GFP_KERNEL);
 	if (!dwc->ctrl_req) {
 		dev_err(dwc->dev, "failed to allocate ctrl request\n");
@@ -2742,7 +2744,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err0;
 	}
 
-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+	dwc->ep0_trb = dma_alloc_coherent(dwc->dev->parent,
+			sizeof(*dwc->ep0_trb) * 2,
 			&dwc->ep0_trb_addr, GFP_KERNEL);
 	if (!dwc->ep0_trb) {
 		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
@@ -2756,7 +2759,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err2;
 	}
 
-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
+	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev->parent,
 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
 			GFP_KERNEL);
 	if (!dwc->ep0_bounce) {
@@ -2828,18 +2831,18 @@ err5:
 
 err4:
 	dwc3_gadget_free_endpoints(dwc);
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->dev->parent, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
 	kfree(dwc->setup_buf);
 
 err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 
 err0:
@@ -2854,16 +2857,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
 	dwc3_gadget_free_endpoints(dwc);
 
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->dev->parent, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 	kfree(dwc->setup_buf);
 	kfree(dwc->zlp_buf);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->dev->parent, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 }
 


-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160427/1df703bd/attachment-0001.sig>

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27  5:41       ` Felipe Balbi
@ 2016-04-27 11:55         ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-27 11:55 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-arm-kernel, linux-usb, linux-kernel, Sekhar Nori,
	David Fisher, Catalin Marinas, Thang Q. Nguyen,
	Yoshihiro Shimoda

On 04/27/2016 08:41 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>>>
>>> Hi,
>>>
>>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>>> and iommu configuration will not corresponds "dwc3" devices
>>>> configuration. As result, this will cause problems like wrong DMA
>>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>>
>>>> When platform is using DT boot mode the DMA configuration will be
>>>> parsed and applied from DT, so, to fix this issue, reuse
>>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>>> from DWC3 device node.
>>>
>>> patch is incomplete. You left out non-DT users which might suffer from
>>> the same problem.
>>>
>>
>> Honestly, I don't know how to fix it gracefully for non-DT case.
>> I can update commit message to mention that this is fix for DT case only.
> 
> no, that won't do :-) There are other users for this driver and they are
> all "out-of-compliance" when it comes to DMA usage. Apparently, the
> desired behavior is to pass correct device to DMA API which the gadget
> side is already doing (see below). For the host side, the fix has to be
> more involved.
> 
> Frankly, I'd prefer that DMA setup could be inherited from parent
> device, then it wouldn't really matter and a bunch of this could be
> simplified. Some sort of dma_inherit(struct device *dev, struct device
> *parent) would go a long way, IMHO.
> 
> 8<-------------------------------- cut here ------------------------
> commit 2725d6f974c4c268ae5fb746f8e3b33b76135aa8
> Author: Felipe Balbi <felipe.balbi@linux.intel.com>
> Date:   Tue Apr 19 16:18:12 2016 +0300
> 
>      usb: dwc3: use parent device for DMA
>      
>      our parent device is the one which was initialized
>      by either PCI or DeviceTree and that's the one which
>      is configured properly for DMA access.
>      
>      Instead of copying DMA bits from parent to child,
>      let's just rely on parent device for the entire DMA
>      API.

1) Patch I've sent fixes "xhci-hcd" platform device and not dwc3 core.
On TI boards dwc3 core devices are created from DT and so, I do not see
any problems with dwc3 core. Problem is with xhci.

2) there is minimum one dtsi file where dwc3 ("snps,dwc3") does not have parent device
ls1021a.dtsi (and 5 dtsi in arm64 folder)



>      
>      Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index c050a88c16d4..09e4ff71a50f 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -180,7 +180,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
>   static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>   		struct dwc3_event_buffer *evt)
>   {
> -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> +	dma_free_coherent(dwc->dev->parent, evt->length, evt->buf, evt->dma);
>   }

[...]

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 11:55         ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-27 11:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/27/2016 08:41 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>>>
>>> Hi,
>>>
>>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>>> and iommu configuration will not corresponds "dwc3" devices
>>>> configuration. As result, this will cause problems like wrong DMA
>>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>>
>>>> When platform is using DT boot mode the DMA configuration will be
>>>> parsed and applied from DT, so, to fix this issue, reuse
>>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>>> from DWC3 device node.
>>>
>>> patch is incomplete. You left out non-DT users which might suffer from
>>> the same problem.
>>>
>>
>> Honestly, I don't know how to fix it gracefully for non-DT case.
>> I can update commit message to mention that this is fix for DT case only.
> 
> no, that won't do :-) There are other users for this driver and they are
> all "out-of-compliance" when it comes to DMA usage. Apparently, the
> desired behavior is to pass correct device to DMA API which the gadget
> side is already doing (see below). For the host side, the fix has to be
> more involved.
> 
> Frankly, I'd prefer that DMA setup could be inherited from parent
> device, then it wouldn't really matter and a bunch of this could be
> simplified. Some sort of dma_inherit(struct device *dev, struct device
> *parent) would go a long way, IMHO.
> 
> 8<-------------------------------- cut here ------------------------
> commit 2725d6f974c4c268ae5fb746f8e3b33b76135aa8
> Author: Felipe Balbi <felipe.balbi@linux.intel.com>
> Date:   Tue Apr 19 16:18:12 2016 +0300
> 
>      usb: dwc3: use parent device for DMA
>      
>      our parent device is the one which was initialized
>      by either PCI or DeviceTree and that's the one which
>      is configured properly for DMA access.
>      
>      Instead of copying DMA bits from parent to child,
>      let's just rely on parent device for the entire DMA
>      API.

1) Patch I've sent fixes "xhci-hcd" platform device and not dwc3 core.
On TI boards dwc3 core devices are created from DT and so, I do not see
any problems with dwc3 core. Problem is with xhci.

2) there is minimum one dtsi file where dwc3 ("snps,dwc3") does not have parent device
ls1021a.dtsi (and 5 dtsi in arm64 folder)



>      
>      Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index c050a88c16d4..09e4ff71a50f 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -180,7 +180,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
>   static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>   		struct dwc3_event_buffer *evt)
>   {
> -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> +	dma_free_coherent(dwc->dev->parent, evt->length, evt->buf, evt->dma);
>   }

[...]

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27  5:41       ` Felipe Balbi
@ 2016-04-27 13:59         ` Catalin Marinas
  -1 siblings, 0 replies; 182+ messages in thread
From: Catalin Marinas @ 2016-04-27 13:59 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Grygorii Strashko, Greg Kroah-Hartman, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, linux-kernel, David Fisher,
	Thang Q. Nguyen, linux-arm-kernel, Arnd Bergmann

On Wed, Apr 27, 2016 at 08:41:06AM +0300, Felipe Balbi wrote:
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
> > On 04/26/2016 09:17 AM, Felipe Balbi wrote:
> >> Grygorii Strashko <grygorii.strashko@ti.com> writes:
> >>> Now not all DMA paremters configured properly for "xhci-hcd" platform
> >>> device which is created manually. For example: dma_pfn_offset, dam_ops
> >>> and iommu configuration will not corresponds "dwc3" devices
> >>> configuration. As result, this will cause problems like wrong DMA
> >>> addresses translation on platforms with LPAE enabled like Keystone 2.
> >>>
> >>> When platform is using DT boot mode the DMA configuration will be
> >>> parsed and applied from DT, so, to fix this issue, reuse
> >>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> >>> from DWC3 device node.
> >> 
> >> patch is incomplete. You left out non-DT users which might suffer from
> >> the same problem.
> >
> > Honestly, I don't know how to fix it gracefully for non-DT case.
> > I can update commit message to mention that this is fix for DT case only.
> 
> no, that won't do :-) There are other users for this driver and they are
> all "out-of-compliance" when it comes to DMA usage. Apparently, the
> desired behavior is to pass correct device to DMA API which the gadget
> side is already doing (see below). For the host side, the fix has to be
> more involved.
> 
> Frankly, I'd prefer that DMA setup could be inherited from parent
> device, then it wouldn't really matter and a bunch of this could be
> simplified. Some sort of dma_inherit(struct device *dev, struct device
> *parent) would go a long way, IMHO.

I would be in favour of a dma_inherit() function as well. We could hack
something up in the arch code (like below) but I would rather prefer an
explicit dma_inherit() call by drivers creating such devices.

diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index ba437f090a74..ea6fb9b0e8fa 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
 
 static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
 {
-	if (dev && dev->archdata.dma_ops)
-		return dev->archdata.dma_ops;
+	while (dev) {
+		if (dev->archdata.dma_ops)
+			return dev->archdata.dma_ops;
+		dev = dev->parent;
+	}
 
 	/*
 	 * We expect no ISA devices, and all other DMA masters are expected to

-- 
Catalin

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 13:59         ` Catalin Marinas
  0 siblings, 0 replies; 182+ messages in thread
From: Catalin Marinas @ 2016-04-27 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 27, 2016 at 08:41:06AM +0300, Felipe Balbi wrote:
> Grygorii Strashko <grygorii.strashko@ti.com> writes:
> > On 04/26/2016 09:17 AM, Felipe Balbi wrote:
> >> Grygorii Strashko <grygorii.strashko@ti.com> writes:
> >>> Now not all DMA paremters configured properly for "xhci-hcd" platform
> >>> device which is created manually. For example: dma_pfn_offset, dam_ops
> >>> and iommu configuration will not corresponds "dwc3" devices
> >>> configuration. As result, this will cause problems like wrong DMA
> >>> addresses translation on platforms with LPAE enabled like Keystone 2.
> >>>
> >>> When platform is using DT boot mode the DMA configuration will be
> >>> parsed and applied from DT, so, to fix this issue, reuse
> >>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> >>> from DWC3 device node.
> >> 
> >> patch is incomplete. You left out non-DT users which might suffer from
> >> the same problem.
> >
> > Honestly, I don't know how to fix it gracefully for non-DT case.
> > I can update commit message to mention that this is fix for DT case only.
> 
> no, that won't do :-) There are other users for this driver and they are
> all "out-of-compliance" when it comes to DMA usage. Apparently, the
> desired behavior is to pass correct device to DMA API which the gadget
> side is already doing (see below). For the host side, the fix has to be
> more involved.
> 
> Frankly, I'd prefer that DMA setup could be inherited from parent
> device, then it wouldn't really matter and a bunch of this could be
> simplified. Some sort of dma_inherit(struct device *dev, struct device
> *parent) would go a long way, IMHO.

I would be in favour of a dma_inherit() function as well. We could hack
something up in the arch code (like below) but I would rather prefer an
explicit dma_inherit() call by drivers creating such devices.

diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index ba437f090a74..ea6fb9b0e8fa 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
 
 static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
 {
-	if (dev && dev->archdata.dma_ops)
-		return dev->archdata.dma_ops;
+	while (dev) {
+		if (dev->archdata.dma_ops)
+			return dev->archdata.dma_ops;
+		dev = dev->parent;
+	}
 
 	/*
 	 * We expect no ISA devices, and all other DMA masters are expected to

-- 
Catalin

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 13:59         ` Catalin Marinas
@ 2016-04-27 14:11           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 14:11 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Felipe Balbi, Grygorii Strashko, Greg Kroah-Hartman,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, linux-arm-kernel

On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> 
> I would be in favour of a dma_inherit() function as well. We could hack
> something up in the arch code (like below) but I would rather prefer an
> explicit dma_inherit() call by drivers creating such devices.
> 
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index ba437f090a74..ea6fb9b0e8fa 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>  
>  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>  {
> -       if (dev && dev->archdata.dma_ops)
> -               return dev->archdata.dma_ops;
> +       while (dev) {
> +               if (dev->archdata.dma_ops)
> +                       return dev->archdata.dma_ops;
> +               dev = dev->parent;
> +       }

I think this would be a very bad idea: we don't want to have random
devices be able to perform DMA just because their parent devices
have been set up that way.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 14:11           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> 
> I would be in favour of a dma_inherit() function as well. We could hack
> something up in the arch code (like below) but I would rather prefer an
> explicit dma_inherit() call by drivers creating such devices.
> 
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index ba437f090a74..ea6fb9b0e8fa 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>  
>  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>  {
> -       if (dev && dev->archdata.dma_ops)
> -               return dev->archdata.dma_ops;
> +       while (dev) {
> +               if (dev->archdata.dma_ops)
> +                       return dev->archdata.dma_ops;
> +               dev = dev->parent;
> +       }

I think this would be a very bad idea: we don't want to have random
devices be able to perform DMA just because their parent devices
have been set up that way.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 13:59         ` Catalin Marinas
@ 2016-04-27 14:14           ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-27 14:14 UTC (permalink / raw)
  To: Catalin Marinas, Felipe Balbi
  Cc: Greg Kroah-Hartman, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen, linux-arm-kernel,
	Arnd Bergmann

On 04/27/2016 04:59 PM, Catalin Marinas wrote:
> On Wed, Apr 27, 2016 at 08:41:06AM +0300, Felipe Balbi wrote:
>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>>>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>>>> and iommu configuration will not corresponds "dwc3" devices
>>>>> configuration. As result, this will cause problems like wrong DMA
>>>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>>>
>>>>> When platform is using DT boot mode the DMA configuration will be
>>>>> parsed and applied from DT, so, to fix this issue, reuse
>>>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>>>> from DWC3 device node.
>>>>
>>>> patch is incomplete. You left out non-DT users which might suffer from
>>>> the same problem.
>>>
>>> Honestly, I don't know how to fix it gracefully for non-DT case.
>>> I can update commit message to mention that this is fix for DT case only.
>>
>> no, that won't do :-) There are other users for this driver and they are
>> all "out-of-compliance" when it comes to DMA usage. Apparently, the
>> desired behavior is to pass correct device to DMA API which the gadget
>> side is already doing (see below). For the host side, the fix has to be
>> more involved.
>>
>> Frankly, I'd prefer that DMA setup could be inherited from parent
>> device, then it wouldn't really matter and a bunch of this could be
>> simplified. Some sort of dma_inherit(struct device *dev, struct device
>> *parent) would go a long way, IMHO.
>
> I would be in favour of a dma_inherit() function as well. We could hack
> something up in the arch code (like below) but I would rather prefer an
> explicit dma_inherit() call by drivers creating such devices.
>
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index ba437f090a74..ea6fb9b0e8fa 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>
>   static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>   {
> -	if (dev && dev->archdata.dma_ops)
> -		return dev->archdata.dma_ops;
> +	while (dev) {
> +		if (dev->archdata.dma_ops)
> +			return dev->archdata.dma_ops;
> +		dev = dev->parent;
> +	}
>
>   	/*
>   	 * We expect no ISA devices, and all other DMA masters are expected to
>

It's no enough to W/A just dma_ops :(

  dma_inherit()...
FYI: http://www.spinics.net/lists/arm-kernel/msg384012.html
Maybe you'll be able to find the way to make it acceptable.

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 14:14           ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-04-27 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/27/2016 04:59 PM, Catalin Marinas wrote:
> On Wed, Apr 27, 2016 at 08:41:06AM +0300, Felipe Balbi wrote:
>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>> On 04/26/2016 09:17 AM, Felipe Balbi wrote:
>>>> Grygorii Strashko <grygorii.strashko@ti.com> writes:
>>>>> Now not all DMA paremters configured properly for "xhci-hcd" platform
>>>>> device which is created manually. For example: dma_pfn_offset, dam_ops
>>>>> and iommu configuration will not corresponds "dwc3" devices
>>>>> configuration. As result, this will cause problems like wrong DMA
>>>>> addresses translation on platforms with LPAE enabled like Keystone 2.
>>>>>
>>>>> When platform is using DT boot mode the DMA configuration will be
>>>>> parsed and applied from DT, so, to fix this issue, reuse
>>>>> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
>>>>> from DWC3 device node.
>>>>
>>>> patch is incomplete. You left out non-DT users which might suffer from
>>>> the same problem.
>>>
>>> Honestly, I don't know how to fix it gracefully for non-DT case.
>>> I can update commit message to mention that this is fix for DT case only.
>>
>> no, that won't do :-) There are other users for this driver and they are
>> all "out-of-compliance" when it comes to DMA usage. Apparently, the
>> desired behavior is to pass correct device to DMA API which the gadget
>> side is already doing (see below). For the host side, the fix has to be
>> more involved.
>>
>> Frankly, I'd prefer that DMA setup could be inherited from parent
>> device, then it wouldn't really matter and a bunch of this could be
>> simplified. Some sort of dma_inherit(struct device *dev, struct device
>> *parent) would go a long way, IMHO.
>
> I would be in favour of a dma_inherit() function as well. We could hack
> something up in the arch code (like below) but I would rather prefer an
> explicit dma_inherit() call by drivers creating such devices.
>
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index ba437f090a74..ea6fb9b0e8fa 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>
>   static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>   {
> -	if (dev && dev->archdata.dma_ops)
> -		return dev->archdata.dma_ops;
> +	while (dev) {
> +		if (dev->archdata.dma_ops)
> +			return dev->archdata.dma_ops;
> +		dev = dev->parent;
> +	}
>
>   	/*
>   	 * We expect no ISA devices, and all other DMA masters are expected to
>

It's no enough to W/A just dma_ops :(

  dma_inherit()...
FYI: http://www.spinics.net/lists/arm-kernel/msg384012.html
Maybe you'll be able to find the way to make it acceptable.

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 14:11           ` Arnd Bergmann
@ 2016-04-27 15:50             ` Catalin Marinas
  -1 siblings, 0 replies; 182+ messages in thread
From: Catalin Marinas @ 2016-04-27 15:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Grygorii Strashko, Greg Kroah-Hartman,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, linux-arm-kernel

On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> > 
> > I would be in favour of a dma_inherit() function as well. We could hack
> > something up in the arch code (like below) but I would rather prefer an
> > explicit dma_inherit() call by drivers creating such devices.
> > 
> > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> > index ba437f090a74..ea6fb9b0e8fa 100644
> > --- a/arch/arm64/include/asm/dma-mapping.h
> > +++ b/arch/arm64/include/asm/dma-mapping.h
> > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> >  
> >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> >  {
> > -       if (dev && dev->archdata.dma_ops)
> > -               return dev->archdata.dma_ops;
> > +       while (dev) {
> > +               if (dev->archdata.dma_ops)
> > +                       return dev->archdata.dma_ops;
> > +               dev = dev->parent;
> > +       }
> 
> I think this would be a very bad idea: we don't want to have random
> devices be able to perform DMA just because their parent devices
> have been set up that way.

I agree, it's a big hack. It would be nice to have a simpler way to do
this in driver code rather than explicitly calling
of_dma_configure/arch_setup_dma_ops as per the original patch in this
thread.

-- 
Catalin

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 15:50             ` Catalin Marinas
  0 siblings, 0 replies; 182+ messages in thread
From: Catalin Marinas @ 2016-04-27 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> > 
> > I would be in favour of a dma_inherit() function as well. We could hack
> > something up in the arch code (like below) but I would rather prefer an
> > explicit dma_inherit() call by drivers creating such devices.
> > 
> > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> > index ba437f090a74..ea6fb9b0e8fa 100644
> > --- a/arch/arm64/include/asm/dma-mapping.h
> > +++ b/arch/arm64/include/asm/dma-mapping.h
> > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> >  
> >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> >  {
> > -       if (dev && dev->archdata.dma_ops)
> > -               return dev->archdata.dma_ops;
> > +       while (dev) {
> > +               if (dev->archdata.dma_ops)
> > +                       return dev->archdata.dma_ops;
> > +               dev = dev->parent;
> > +       }
> 
> I think this would be a very bad idea: we don't want to have random
> devices be able to perform DMA just because their parent devices
> have been set up that way.

I agree, it's a big hack. It would be nice to have a simpler way to do
this in driver code rather than explicitly calling
of_dma_configure/arch_setup_dma_ops as per the original patch in this
thread.

-- 
Catalin

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 15:50             ` Catalin Marinas
@ 2016-04-27 16:04               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 16:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Catalin Marinas, Felipe Balbi, Grygorii Strashko,
	Greg Kroah-Hartman, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen

On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> > > 
> > > I would be in favour of a dma_inherit() function as well. We could hack
> > > something up in the arch code (like below) but I would rather prefer an
> > > explicit dma_inherit() call by drivers creating such devices.
> > > 
> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> > > index ba437f090a74..ea6fb9b0e8fa 100644
> > > --- a/arch/arm64/include/asm/dma-mapping.h
> > > +++ b/arch/arm64/include/asm/dma-mapping.h
> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> > >  
> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> > >  {
> > > -       if (dev && dev->archdata.dma_ops)
> > > -               return dev->archdata.dma_ops;
> > > +       while (dev) {
> > > +               if (dev->archdata.dma_ops)
> > > +                       return dev->archdata.dma_ops;
> > > +               dev = dev->parent;
> > > +       }
> > 
> > I think this would be a very bad idea: we don't want to have random
> > devices be able to perform DMA just because their parent devices
> > have been set up that way.
> 
> I agree, it's a big hack. It would be nice to have a simpler way to do
> this in driver code rather than explicitly calling
> of_dma_configure/arch_setup_dma_ops as per the original patch in this
> thread.
> 


I haven't followed the entire discussion, but what's wrong with passing
around a pointer to a 'struct device *hwdev' that represents the physical
device that does the DMA?

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 16:04               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 16:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> > > 
> > > I would be in favour of a dma_inherit() function as well. We could hack
> > > something up in the arch code (like below) but I would rather prefer an
> > > explicit dma_inherit() call by drivers creating such devices.
> > > 
> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> > > index ba437f090a74..ea6fb9b0e8fa 100644
> > > --- a/arch/arm64/include/asm/dma-mapping.h
> > > +++ b/arch/arm64/include/asm/dma-mapping.h
> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> > >  
> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> > >  {
> > > -       if (dev && dev->archdata.dma_ops)
> > > -               return dev->archdata.dma_ops;
> > > +       while (dev) {
> > > +               if (dev->archdata.dma_ops)
> > > +                       return dev->archdata.dma_ops;
> > > +               dev = dev->parent;
> > > +       }
> > 
> > I think this would be a very bad idea: we don't want to have random
> > devices be able to perform DMA just because their parent devices
> > have been set up that way.
> 
> I agree, it's a big hack. It would be nice to have a simpler way to do
> this in driver code rather than explicitly calling
> of_dma_configure/arch_setup_dma_ops as per the original patch in this
> thread.
> 


I haven't followed the entire discussion, but what's wrong with passing
around a pointer to a 'struct device *hwdev' that represents the physical
device that does the DMA?

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 16:04               ` Arnd Bergmann
@ 2016-04-27 16:53                 ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 16:53 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Catalin Marinas, Grygorii Strashko, Greg Kroah-Hartman,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen

[-- Attachment #1: Type: text/plain, Size: 6679 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
>> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
>> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
>> > > 
>> > > I would be in favour of a dma_inherit() function as well. We could hack
>> > > something up in the arch code (like below) but I would rather prefer an
>> > > explicit dma_inherit() call by drivers creating such devices.
>> > > 
>> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
>> > > index ba437f090a74..ea6fb9b0e8fa 100644
>> > > --- a/arch/arm64/include/asm/dma-mapping.h
>> > > +++ b/arch/arm64/include/asm/dma-mapping.h
>> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>> > >  
>> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>> > >  {
>> > > -       if (dev && dev->archdata.dma_ops)
>> > > -               return dev->archdata.dma_ops;
>> > > +       while (dev) {
>> > > +               if (dev->archdata.dma_ops)
>> > > +                       return dev->archdata.dma_ops;
>> > > +               dev = dev->parent;
>> > > +       }
>> > 
>> > I think this would be a very bad idea: we don't want to have random
>> > devices be able to perform DMA just because their parent devices
>> > have been set up that way.
>> 
>> I agree, it's a big hack. It would be nice to have a simpler way to do
>> this in driver code rather than explicitly calling
>> of_dma_configure/arch_setup_dma_ops as per the original patch in this
>> thread.
>
> I haven't followed the entire discussion, but what's wrong with passing
> around a pointer to a 'struct device *hwdev' that represents the physical
> device that does the DMA?

that will likely create duplicated solutions in several drivers and
it'll be a pain to maintain. There's another complication, dwc3 can be
integrated in many different ways. See the device child-parent tree
representations below:

a) with a parent PCI device:

pci_bus_type
 - dwc3-pci
   - dwc3
     - xhci-plat

b) with a parent platform_device (OF):

platform_bus_type
 - dwc3-${omap,st,of-simple,exynos,keystone}
   - dwc3
     - xhci-plat

c) without a parent at all (thanks Grygorii):

platform_bus_type
 - dwc3
   - xhci-plat

(a) and (b) above are the common cases. The DMA-capable device is
clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
having proper DMA configuration in OF platforms (because of the
unconditional of_dma_configure() during OF device creation) and
xhci-plat not knowing about DMA at all and hardcoding some crappy
defaults.

(c) is the uncommon case which creates some problems. In this case, dwc3
itself is the DMA-capable device and dwc3->dev->parent is the
platform_bus_type itself. Now consider the problem this creates:

i. the patch that I wrote [1] becomes invalid for (c), thanks to
Grygorii for pointing this out before it was too late.

ii. xhci-plat can also be described directly in DT (and is in some
cases). This means that assuming xhci-plat's parent's parent to be the
DMA-capable device is also an invalid assumption.

iii. one might argue that for DT-based platforms *with* a glue layer
((b) above), OF already "copies" some sensible DMA defaults during
device creation. PCI-based systems just don't have the luxury of
creating random PCI devices like that :-) I say it copies because I can
pass *any* struct device_node pointer and it'll just copy that to the
struct device argument. Here's of_dma_configure() to make your life
easier:

void of_dma_configure(struct device *dev, struct device_node *np)
{
	u64 dma_addr, paddr, size;
	int ret;
	bool coherent;
	unsigned long offset;
	struct iommu_ops *iommu;

	/*
	 * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
	 * setup the correct supported mask.
	 */
	if (!dev->coherent_dma_mask)
		dev->coherent_dma_mask = DMA_BIT_MASK(32);

	/*
	 * Set it to coherent_dma_mask by default if the architecture
	 * code has not set it.
	 */
	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;

	ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
	if (ret < 0) {
		dma_addr = offset = 0;
		size = dev->coherent_dma_mask + 1;
	} else {
		offset = PFN_DOWN(paddr - dma_addr);

		/*
		 * Add a work around to treat the size as mask + 1 in case
		 * it is defined in DT as a mask.
		 */
		if (size & 1) {
			dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
				 size);
			size = size + 1;
		}

		if (!size) {
			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
			return;
		}
		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
	}

	dev->dma_pfn_offset = offset;

	/*
	 * Limit coherent and dma mask based on size and default mask
	 * set by the driver.
	 */
	dev->coherent_dma_mask = min(dev->coherent_dma_mask,
				     DMA_BIT_MASK(ilog2(dma_addr + size)));
	*dev->dma_mask = min((*dev->dma_mask),
			     DMA_BIT_MASK(ilog2(dma_addr + size)));

	coherent = of_dma_is_coherent(np);
	dev_dbg(dev, "device is%sdma coherent\n",
		coherent ? " " : " not ");

	iommu = of_iommu_configure(dev, np);
	dev_dbg(dev, "device is%sbehind an iommu\n",
		iommu ? " " : " not ");

	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
}

The only clean way to fix this up is with a dma_inherit()-like API which
would allow dwc3's glue layers ((a) and (b) above) to initialize child's
(dwc3) DMA configuration during child's creation. Something like below:

diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index adc1e8a624cb..74b599269e2c 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
 		return -ENOMEM;
 	}
 
+	dma_inherit(&dwc->dev, dev);
+
 	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
 
 	res[0].start	= pci_resource_start(pci, 0);

that's all I'm asking for :-) dma_inherit() should, probably, be
arch-specific to handle details like IOMMU (which today sits under
archdata).

without something like this, we're gonna have to resort to tons of
checks trying to find the correct DMA configuration to use in all
possible usage scenarios of dwc3.

Note, however, that I'm using dwc3 as an example, but anywhere you see
manual platform_device creation, there's a potential problem WRT DMA
and/or IOMMU.

[1] https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=2725d6f974c4c268ae5fb746f8e3b33b76135aa8

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 16:53                 ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 16:53 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
>> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
>> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
>> > > 
>> > > I would be in favour of a dma_inherit() function as well. We could hack
>> > > something up in the arch code (like below) but I would rather prefer an
>> > > explicit dma_inherit() call by drivers creating such devices.
>> > > 
>> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
>> > > index ba437f090a74..ea6fb9b0e8fa 100644
>> > > --- a/arch/arm64/include/asm/dma-mapping.h
>> > > +++ b/arch/arm64/include/asm/dma-mapping.h
>> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>> > >  
>> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>> > >  {
>> > > -       if (dev && dev->archdata.dma_ops)
>> > > -               return dev->archdata.dma_ops;
>> > > +       while (dev) {
>> > > +               if (dev->archdata.dma_ops)
>> > > +                       return dev->archdata.dma_ops;
>> > > +               dev = dev->parent;
>> > > +       }
>> > 
>> > I think this would be a very bad idea: we don't want to have random
>> > devices be able to perform DMA just because their parent devices
>> > have been set up that way.
>> 
>> I agree, it's a big hack. It would be nice to have a simpler way to do
>> this in driver code rather than explicitly calling
>> of_dma_configure/arch_setup_dma_ops as per the original patch in this
>> thread.
>
> I haven't followed the entire discussion, but what's wrong with passing
> around a pointer to a 'struct device *hwdev' that represents the physical
> device that does the DMA?

that will likely create duplicated solutions in several drivers and
it'll be a pain to maintain. There's another complication, dwc3 can be
integrated in many different ways. See the device child-parent tree
representations below:

a) with a parent PCI device:

pci_bus_type
 - dwc3-pci
   - dwc3
     - xhci-plat

b) with a parent platform_device (OF):

platform_bus_type
 - dwc3-${omap,st,of-simple,exynos,keystone}
   - dwc3
     - xhci-plat

c) without a parent at all (thanks Grygorii):

platform_bus_type
 - dwc3
   - xhci-plat

(a) and (b) above are the common cases. The DMA-capable device is
clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
having proper DMA configuration in OF platforms (because of the
unconditional of_dma_configure() during OF device creation) and
xhci-plat not knowing about DMA at all and hardcoding some crappy
defaults.

(c) is the uncommon case which creates some problems. In this case, dwc3
itself is the DMA-capable device and dwc3->dev->parent is the
platform_bus_type itself. Now consider the problem this creates:

i. the patch that I wrote [1] becomes invalid for (c), thanks to
Grygorii for pointing this out before it was too late.

ii. xhci-plat can also be described directly in DT (and is in some
cases). This means that assuming xhci-plat's parent's parent to be the
DMA-capable device is also an invalid assumption.

iii. one might argue that for DT-based platforms *with* a glue layer
((b) above), OF already "copies" some sensible DMA defaults during
device creation. PCI-based systems just don't have the luxury of
creating random PCI devices like that :-) I say it copies because I can
pass *any* struct device_node pointer and it'll just copy that to the
struct device argument. Here's of_dma_configure() to make your life
easier:

void of_dma_configure(struct device *dev, struct device_node *np)
{
	u64 dma_addr, paddr, size;
	int ret;
	bool coherent;
	unsigned long offset;
	struct iommu_ops *iommu;

	/*
	 * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
	 * setup the correct supported mask.
	 */
	if (!dev->coherent_dma_mask)
		dev->coherent_dma_mask = DMA_BIT_MASK(32);

	/*
	 * Set it to coherent_dma_mask by default if the architecture
	 * code has not set it.
	 */
	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;

	ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
	if (ret < 0) {
		dma_addr = offset = 0;
		size = dev->coherent_dma_mask + 1;
	} else {
		offset = PFN_DOWN(paddr - dma_addr);

		/*
		 * Add a work around to treat the size as mask + 1 in case
		 * it is defined in DT as a mask.
		 */
		if (size & 1) {
			dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
				 size);
			size = size + 1;
		}

		if (!size) {
			dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
			return;
		}
		dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
	}

	dev->dma_pfn_offset = offset;

	/*
	 * Limit coherent and dma mask based on size and default mask
	 * set by the driver.
	 */
	dev->coherent_dma_mask = min(dev->coherent_dma_mask,
				     DMA_BIT_MASK(ilog2(dma_addr + size)));
	*dev->dma_mask = min((*dev->dma_mask),
			     DMA_BIT_MASK(ilog2(dma_addr + size)));

	coherent = of_dma_is_coherent(np);
	dev_dbg(dev, "device is%sdma coherent\n",
		coherent ? " " : " not ");

	iommu = of_iommu_configure(dev, np);
	dev_dbg(dev, "device is%sbehind an iommu\n",
		iommu ? " " : " not ");

	arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
}

The only clean way to fix this up is with a dma_inherit()-like API which
would allow dwc3's glue layers ((a) and (b) above) to initialize child's
(dwc3) DMA configuration during child's creation. Something like below:

diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index adc1e8a624cb..74b599269e2c 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
 		return -ENOMEM;
 	}
 
+	dma_inherit(&dwc->dev, dev);
+
 	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
 
 	res[0].start	= pci_resource_start(pci, 0);

that's all I'm asking for :-) dma_inherit() should, probably, be
arch-specific to handle details like IOMMU (which today sits under
archdata).

without something like this, we're gonna have to resort to tons of
checks trying to find the correct DMA configuration to use in all
possible usage scenarios of dwc3.

Note, however, that I'm using dwc3 as an example, but anywhere you see
manual platform_device creation, there's a potential problem WRT DMA
and/or IOMMU.

[1] https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=2725d6f974c4c268ae5fb746f8e3b33b76135aa8

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160427/68c33e22/attachment-0001.sig>

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 16:53                 ` Felipe Balbi
@ 2016-04-27 17:42                   ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 17:42 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Felipe Balbi, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

On Wednesday 27 April 2016 19:53:51 Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
> >> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> >> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> >> > > 
> >> > > I would be in favour of a dma_inherit() function as well. We could hack
> >> > > something up in the arch code (like below) but I would rather prefer an
> >> > > explicit dma_inherit() call by drivers creating such devices.
> >> > > 
> >> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> >> > > index ba437f090a74..ea6fb9b0e8fa 100644
> >> > > --- a/arch/arm64/include/asm/dma-mapping.h
> >> > > +++ b/arch/arm64/include/asm/dma-mapping.h
> >> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> >> > >  
> >> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> >> > >  {
> >> > > -       if (dev && dev->archdata.dma_ops)
> >> > > -               return dev->archdata.dma_ops;
> >> > > +       while (dev) {
> >> > > +               if (dev->archdata.dma_ops)
> >> > > +                       return dev->archdata.dma_ops;
> >> > > +               dev = dev->parent;
> >> > > +       }
> >> > 
> >> > I think this would be a very bad idea: we don't want to have random
> >> > devices be able to perform DMA just because their parent devices
> >> > have been set up that way.
> >> 
> >> I agree, it's a big hack. It would be nice to have a simpler way to do
> >> this in driver code rather than explicitly calling
> >> of_dma_configure/arch_setup_dma_ops as per the original patch in this
> >> thread.
> >
> > I haven't followed the entire discussion, but what's wrong with passing
> > around a pointer to a 'struct device *hwdev' that represents the physical
> > device that does the DMA?
> 
> that will likely create duplicated solutions in several drivers and
> it'll be a pain to maintain. There's another complication, dwc3 can be
> integrated in many different ways. See the device child-parent tree
> representations below:
> 
> a) with a parent PCI device:
> 
> pci_bus_type
>  - dwc3-pci
>    - dwc3
>      - xhci-plat
> 
> b) with a parent platform_device (OF):
> 
> platform_bus_type
>  - dwc3-${omap,st,of-simple,exynos,keystone}
>    - dwc3
>      - xhci-plat
> 
> c) without a parent at all (thanks Grygorii):
> 
> platform_bus_type
>  - dwc3
>    - xhci-plat
> 
> (a) and (b) above are the common cases. The DMA-capable device is
> clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
> having proper DMA configuration in OF platforms (because of the
> unconditional of_dma_configure() during OF device creation) and
> xhci-plat not knowing about DMA at all and hardcoding some crappy
> defaults.
> 
> (c) is the uncommon case which creates some problems. In this case, dwc3
> itself is the DMA-capable device and dwc3->dev->parent is the
> platform_bus_type itself. Now consider the problem this creates:
> 
> i. the patch that I wrote [1] becomes invalid for (c), thanks to
> Grygorii for pointing this out before it was too late.
> 
> ii. xhci-plat can also be described directly in DT (and is in some
> cases). This means that assuming xhci-plat's parent's parent to be the
> DMA-capable device is also an invalid assumption.
> 
> iii. one might argue that for DT-based platforms *with* a glue layer
> ((b) above), OF already "copies" some sensible DMA defaults during
> device creation.

But that is exactly the point I was trying to make: instead of copying
all the data into the xhci-plat device, just assign one pointer
inside the xhci-plat device from whoever creates it.

> The only clean way to fix this up is with a dma_inherit()-like API which
> would allow dwc3's glue layers ((a) and (b) above) to initialize child's
> (dwc3) DMA configuration during child's creation. Something like below:
> 
> diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
> index adc1e8a624cb..74b599269e2c 100644
> --- a/drivers/usb/dwc3/dwc3-pci.c
> +++ b/drivers/usb/dwc3/dwc3-pci.c
> @@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
>  		return -ENOMEM;
>  	}
>  
> +	dma_inherit(&dwc->dev, dev);
> +
>  	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
>  
>  	res[0].start	= pci_resource_start(pci, 0);
> 
> that's all I'm asking for :-) dma_inherit() should, probably, be
> arch-specific to handle details like IOMMU (which today sits under
> archdata).

It's still wrong: the archdata in the device can contain all sorts of
additional information about how to do DMA, and some of that information
is bus specific, e.g. when your dma_map_ops look like the on sparc:

static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
#ifdef CONFIG_SPARC_LEON
        if (sparc_cpu_model == sparc_leon)
                return leon_dma_ops;
#endif
#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
        if (dev->bus == &pci_bus_type)
                return &pci32_dma_ops;
#endif
        return dma_ops;
}

There is no way for a device to "inherit" the bus_type of its parent,
so it becomes an architecture specific hack. However, if you change
all the dma operations to work on the actual device that the dma
mapping API knows about, it just works.

I've looked at the usb HCD code now and see this:

struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
                struct device *dev, const char *bus_name,
                struct usb_hcd *primary_hcd)
{
	...
        hcd->self.controller = dev;
        hcd->self.uses_dma = (dev->dma_mask != NULL);
	...
}

What I think we need to do here is ensure that the device that gets
passed here and assigned to hcd->self.controller is the actual DMA
master device, i.e. the pci_device or platform_device that was created
from outside of the xhci stack. This is after all the pointer that
gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
functions.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 17:42                   ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 17:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 27 April 2016 19:53:51 Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
> >> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
> >> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
> >> > > 
> >> > > I would be in favour of a dma_inherit() function as well. We could hack
> >> > > something up in the arch code (like below) but I would rather prefer an
> >> > > explicit dma_inherit() call by drivers creating such devices.
> >> > > 
> >> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> >> > > index ba437f090a74..ea6fb9b0e8fa 100644
> >> > > --- a/arch/arm64/include/asm/dma-mapping.h
> >> > > +++ b/arch/arm64/include/asm/dma-mapping.h
> >> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
> >> > >  
> >> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
> >> > >  {
> >> > > -       if (dev && dev->archdata.dma_ops)
> >> > > -               return dev->archdata.dma_ops;
> >> > > +       while (dev) {
> >> > > +               if (dev->archdata.dma_ops)
> >> > > +                       return dev->archdata.dma_ops;
> >> > > +               dev = dev->parent;
> >> > > +       }
> >> > 
> >> > I think this would be a very bad idea: we don't want to have random
> >> > devices be able to perform DMA just because their parent devices
> >> > have been set up that way.
> >> 
> >> I agree, it's a big hack. It would be nice to have a simpler way to do
> >> this in driver code rather than explicitly calling
> >> of_dma_configure/arch_setup_dma_ops as per the original patch in this
> >> thread.
> >
> > I haven't followed the entire discussion, but what's wrong with passing
> > around a pointer to a 'struct device *hwdev' that represents the physical
> > device that does the DMA?
> 
> that will likely create duplicated solutions in several drivers and
> it'll be a pain to maintain. There's another complication, dwc3 can be
> integrated in many different ways. See the device child-parent tree
> representations below:
> 
> a) with a parent PCI device:
> 
> pci_bus_type
>  - dwc3-pci
>    - dwc3
>      - xhci-plat
> 
> b) with a parent platform_device (OF):
> 
> platform_bus_type
>  - dwc3-${omap,st,of-simple,exynos,keystone}
>    - dwc3
>      - xhci-plat
> 
> c) without a parent at all (thanks Grygorii):
> 
> platform_bus_type
>  - dwc3
>    - xhci-plat
> 
> (a) and (b) above are the common cases. The DMA-capable device is
> clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
> having proper DMA configuration in OF platforms (because of the
> unconditional of_dma_configure() during OF device creation) and
> xhci-plat not knowing about DMA at all and hardcoding some crappy
> defaults.
> 
> (c) is the uncommon case which creates some problems. In this case, dwc3
> itself is the DMA-capable device and dwc3->dev->parent is the
> platform_bus_type itself. Now consider the problem this creates:
> 
> i. the patch that I wrote [1] becomes invalid for (c), thanks to
> Grygorii for pointing this out before it was too late.
> 
> ii. xhci-plat can also be described directly in DT (and is in some
> cases). This means that assuming xhci-plat's parent's parent to be the
> DMA-capable device is also an invalid assumption.
> 
> iii. one might argue that for DT-based platforms *with* a glue layer
> ((b) above), OF already "copies" some sensible DMA defaults during
> device creation.

But that is exactly the point I was trying to make: instead of copying
all the data into the xhci-plat device, just assign one pointer
inside the xhci-plat device from whoever creates it.

> The only clean way to fix this up is with a dma_inherit()-like API which
> would allow dwc3's glue layers ((a) and (b) above) to initialize child's
> (dwc3) DMA configuration during child's creation. Something like below:
> 
> diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
> index adc1e8a624cb..74b599269e2c 100644
> --- a/drivers/usb/dwc3/dwc3-pci.c
> +++ b/drivers/usb/dwc3/dwc3-pci.c
> @@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
>  		return -ENOMEM;
>  	}
>  
> +	dma_inherit(&dwc->dev, dev);
> +
>  	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
>  
>  	res[0].start	= pci_resource_start(pci, 0);
> 
> that's all I'm asking for :-) dma_inherit() should, probably, be
> arch-specific to handle details like IOMMU (which today sits under
> archdata).

It's still wrong: the archdata in the device can contain all sorts of
additional information about how to do DMA, and some of that information
is bus specific, e.g. when your dma_map_ops look like the on sparc:

static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
#ifdef CONFIG_SPARC_LEON
        if (sparc_cpu_model == sparc_leon)
                return leon_dma_ops;
#endif
#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
        if (dev->bus == &pci_bus_type)
                return &pci32_dma_ops;
#endif
        return dma_ops;
}

There is no way for a device to "inherit" the bus_type of its parent,
so it becomes an architecture specific hack. However, if you change
all the dma operations to work on the actual device that the dma
mapping API knows about, it just works.

I've looked at the usb HCD code now and see this:

struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
                struct device *dev, const char *bus_name,
                struct usb_hcd *primary_hcd)
{
	...
        hcd->self.controller = dev;
        hcd->self.uses_dma = (dev->dma_mask != NULL);
	...
}

What I think we need to do here is ensure that the device that gets
passed here and assigned to hcd->self.controller is the actual DMA
master device, i.e. the pci_device or platform_device that was created
from outside of the xhci stack. This is after all the pointer that
gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
functions.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 17:42                   ` Arnd Bergmann
@ 2016-04-27 17:59                     ` Alan Stern
  -1 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-04-27 17:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Felipe Balbi, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

On Wed, 27 Apr 2016, Arnd Bergmann wrote:

> I've looked at the usb HCD code now and see this:
> 
> struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>                 struct device *dev, const char *bus_name,
>                 struct usb_hcd *primary_hcd)
> {
> 	...
>         hcd->self.controller = dev;
>         hcd->self.uses_dma = (dev->dma_mask != NULL);
> 	...
> }
> 
> What I think we need to do here is ensure that the device that gets
> passed here and assigned to hcd->self.controller is the actual DMA
> master device, i.e. the pci_device or platform_device that was created
> from outside of the xhci stack. This is after all the pointer that
> gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> functions.

It would be better to add a new field, since self.controller is also
used for lots of other purposes.  Something like hcd->self.dma_dev.

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 17:59                     ` Alan Stern
  0 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-04-27 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 27 Apr 2016, Arnd Bergmann wrote:

> I've looked at the usb HCD code now and see this:
> 
> struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>                 struct device *dev, const char *bus_name,
>                 struct usb_hcd *primary_hcd)
> {
> 	...
>         hcd->self.controller = dev;
>         hcd->self.uses_dma = (dev->dma_mask != NULL);
> 	...
> }
> 
> What I think we need to do here is ensure that the device that gets
> passed here and assigned to hcd->self.controller is the actual DMA
> master device, i.e. the pci_device or platform_device that was created
> from outside of the xhci stack. This is after all the pointer that
> gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> functions.

It would be better to add a new field, since self.controller is also
used for lots of other purposes.  Something like hcd->self.dma_dev.

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 17:59                     ` Alan Stern
@ 2016-04-27 18:08                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 18:08 UTC (permalink / raw)
  To: Alan Stern
  Cc: linux-arm-kernel, Felipe Balbi, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
> 
> > I've looked at the usb HCD code now and see this:
> > 
> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> >                 struct device *dev, const char *bus_name,
> >                 struct usb_hcd *primary_hcd)
> > {
> >       ...
> >         hcd->self.controller = dev;
> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
> >       ...
> > }
> > 
> > What I think we need to do here is ensure that the device that gets
> > passed here and assigned to hcd->self.controller is the actual DMA
> > master device, i.e. the pci_device or platform_device that was created
> > from outside of the xhci stack. This is after all the pointer that
> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> > functions.
> 
> It would be better to add a new field, since self.controller is also
> used for lots of other purposes.  Something like hcd->self.dma_dev.
> 

Ok, fair enough. I only took a brief look and all uses I found were
either for the DMA mapping API or some printk logging.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 18:08                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 18:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
> 
> > I've looked at the usb HCD code now and see this:
> > 
> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> >                 struct device *dev, const char *bus_name,
> >                 struct usb_hcd *primary_hcd)
> > {
> >       ...
> >         hcd->self.controller = dev;
> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
> >       ...
> > }
> > 
> > What I think we need to do here is ensure that the device that gets
> > passed here and assigned to hcd->self.controller is the actual DMA
> > master device, i.e. the pci_device or platform_device that was created
> > from outside of the xhci stack. This is after all the pointer that
> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> > functions.
> 
> It would be better to add a new field, since self.controller is also
> used for lots of other purposes.  Something like hcd->self.dma_dev.
> 

Ok, fair enough. I only took a brief look and all uses I found were
either for the DMA mapping API or some printk logging.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 18:08                       ` Arnd Bergmann
@ 2016-04-27 20:05                         ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 20:05 UTC (permalink / raw)
  To: Arnd Bergmann, Alan Stern
  Cc: linux-arm-kernel, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 2149 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
>> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
>> 
>> > I've looked at the usb HCD code now and see this:
>> > 
>> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>> >                 struct device *dev, const char *bus_name,
>> >                 struct usb_hcd *primary_hcd)
>> > {
>> >       ...
>> >         hcd->self.controller = dev;
>> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
>> >       ...
>> > }
>> > 
>> > What I think we need to do here is ensure that the device that gets
>> > passed here and assigned to hcd->self.controller is the actual DMA
>> > master device, i.e. the pci_device or platform_device that was created
>> > from outside of the xhci stack. This is after all the pointer that
>> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
>> > functions.
>> 
>> It would be better to add a new field, since self.controller is also
>> used for lots of other purposes.  Something like hcd->self.dma_dev.
>
> Ok, fair enough. I only took a brief look and all uses I found were
> either for the DMA mapping API or some printk logging.

I have a feeling you guys are not considering how the patch to implement
this will look like.

How are you expecting dwc3 to pass a pointer to the DMA device from
dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible :-)

Also, remember that the DMA device for dwc3 is not always
dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
us to figure that one out ?

I still think dma_inherit() (or something along those lines) is
necessary. Specially when you consider that, as I said previously,
that's pretty much what of_dma_configure() does.

Anyway, I'd really like to see a patch implementing this
hcd->self.dma_dev logic. Consider all the duplication with this
approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
own. Will that be passed to dwc3 as platform_data from glue layer ? What
about platforms which don't even use a glue layer ?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 20:05                         ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 20:05 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
>> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
>> 
>> > I've looked at the usb HCD code now and see this:
>> > 
>> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>> >                 struct device *dev, const char *bus_name,
>> >                 struct usb_hcd *primary_hcd)
>> > {
>> >       ...
>> >         hcd->self.controller = dev;
>> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
>> >       ...
>> > }
>> > 
>> > What I think we need to do here is ensure that the device that gets
>> > passed here and assigned to hcd->self.controller is the actual DMA
>> > master device, i.e. the pci_device or platform_device that was created
>> > from outside of the xhci stack. This is after all the pointer that
>> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
>> > functions.
>> 
>> It would be better to add a new field, since self.controller is also
>> used for lots of other purposes.  Something like hcd->self.dma_dev.
>
> Ok, fair enough. I only took a brief look and all uses I found were
> either for the DMA mapping API or some printk logging.

I have a feeling you guys are not considering how the patch to implement
this will look like.

How are you expecting dwc3 to pass a pointer to the DMA device from
dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible :-)

Also, remember that the DMA device for dwc3 is not always
dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
us to figure that one out ?

I still think dma_inherit() (or something along those lines) is
necessary. Specially when you consider that, as I said previously,
that's pretty much what of_dma_configure() does.

Anyway, I'd really like to see a patch implementing this
hcd->self.dma_dev logic. Consider all the duplication with this
approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
own. Will that be passed to dwc3 as platform_data from glue layer ? What
about platforms which don't even use a glue layer ?

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160427/4c9d86a6/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 17:42                   ` Arnd Bergmann
@ 2016-04-27 20:57                     ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 20:57 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Grygorii Strashko, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, linux-kernel, David Fisher, Thang Q. Nguyen,
	Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 6048 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 19:53:51 Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
>> >> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
>> >> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
>> >> > > 
>> >> > > I would be in favour of a dma_inherit() function as well. We could hack
>> >> > > something up in the arch code (like below) but I would rather prefer an
>> >> > > explicit dma_inherit() call by drivers creating such devices.
>> >> > > 
>> >> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
>> >> > > index ba437f090a74..ea6fb9b0e8fa 100644
>> >> > > --- a/arch/arm64/include/asm/dma-mapping.h
>> >> > > +++ b/arch/arm64/include/asm/dma-mapping.h
>> >> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>> >> > >  
>> >> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>> >> > >  {
>> >> > > -       if (dev && dev->archdata.dma_ops)
>> >> > > -               return dev->archdata.dma_ops;
>> >> > > +       while (dev) {
>> >> > > +               if (dev->archdata.dma_ops)
>> >> > > +                       return dev->archdata.dma_ops;
>> >> > > +               dev = dev->parent;
>> >> > > +       }
>> >> > 
>> >> > I think this would be a very bad idea: we don't want to have random
>> >> > devices be able to perform DMA just because their parent devices
>> >> > have been set up that way.
>> >> 
>> >> I agree, it's a big hack. It would be nice to have a simpler way to do
>> >> this in driver code rather than explicitly calling
>> >> of_dma_configure/arch_setup_dma_ops as per the original patch in this
>> >> thread.
>> >
>> > I haven't followed the entire discussion, but what's wrong with passing
>> > around a pointer to a 'struct device *hwdev' that represents the physical
>> > device that does the DMA?
>> 
>> that will likely create duplicated solutions in several drivers and
>> it'll be a pain to maintain. There's another complication, dwc3 can be
>> integrated in many different ways. See the device child-parent tree
>> representations below:
>> 
>> a) with a parent PCI device:
>> 
>> pci_bus_type
>>  - dwc3-pci
>>    - dwc3
>>      - xhci-plat
>> 
>> b) with a parent platform_device (OF):
>> 
>> platform_bus_type
>>  - dwc3-${omap,st,of-simple,exynos,keystone}
>>    - dwc3
>>      - xhci-plat
>> 
>> c) without a parent at all (thanks Grygorii):
>> 
>> platform_bus_type
>>  - dwc3
>>    - xhci-plat
>> 
>> (a) and (b) above are the common cases. The DMA-capable device is
>> clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
>> having proper DMA configuration in OF platforms (because of the
>> unconditional of_dma_configure() during OF device creation) and
>> xhci-plat not knowing about DMA at all and hardcoding some crappy
>> defaults.
>> 
>> (c) is the uncommon case which creates some problems. In this case, dwc3
>> itself is the DMA-capable device and dwc3->dev->parent is the
>> platform_bus_type itself. Now consider the problem this creates:
>> 
>> i. the patch that I wrote [1] becomes invalid for (c), thanks to
>> Grygorii for pointing this out before it was too late.
>> 
>> ii. xhci-plat can also be described directly in DT (and is in some
>> cases). This means that assuming xhci-plat's parent's parent to be the
>> DMA-capable device is also an invalid assumption.
>> 
>> iii. one might argue that for DT-based platforms *with* a glue layer
>> ((b) above), OF already "copies" some sensible DMA defaults during
>> device creation.
>
> But that is exactly the point I was trying to make: instead of copying
> all the data into the xhci-plat device, just assign one pointer
> inside the xhci-plat device from whoever creates it.

and how do you pass that pointer to xhci-plat from another driver ?
No, platform_data is not an option ;-)

>> The only clean way to fix this up is with a dma_inherit()-like API which
>> would allow dwc3's glue layers ((a) and (b) above) to initialize child's
>> (dwc3) DMA configuration during child's creation. Something like below:
>> 
>> diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
>> index adc1e8a624cb..74b599269e2c 100644
>> --- a/drivers/usb/dwc3/dwc3-pci.c
>> +++ b/drivers/usb/dwc3/dwc3-pci.c
>> @@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
>>  		return -ENOMEM;
>>  	}
>>  
>> +	dma_inherit(&dwc->dev, dev);
>> +
>>  	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
>>  
>>  	res[0].start	= pci_resource_start(pci, 0);
>> 
>> that's all I'm asking for :-) dma_inherit() should, probably, be
>> arch-specific to handle details like IOMMU (which today sits under
>> archdata).
>
> It's still wrong: the archdata in the device can contain all sorts of
> additional information about how to do DMA, and some of that information

yes, inherit all of that ;-)

> is bus specific, e.g. when your dma_map_ops look like the on sparc:

okay, let me be clear. The underlying bus is still pci_bus_type or
platform_bus_type; that won't change.

> static inline struct dma_map_ops *get_dma_ops(struct device *dev)
> {
> #ifdef CONFIG_SPARC_LEON
>         if (sparc_cpu_model == sparc_leon)
>                 return leon_dma_ops;
> #endif
> #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
>         if (dev->bus == &pci_bus_type)
>                 return &pci32_dma_ops;
> #endif
>         return dma_ops;
> }

this seems to be a rather fragile assumption, no ? Only works because
*_bus_type declarations are exported. I wonder if this is the only
reason *why* they are exported, probably not...

> There is no way for a device to "inherit" the bus_type of its parent,

I don't want to inherit bus_type, I just want DMA configuration to not
depend on bus_type directly ;-)

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 20:57                     ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-27 20:57 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 19:53:51 Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Wednesday 27 April 2016 16:50:19 Catalin Marinas wrote:
>> >> On Wed, Apr 27, 2016 at 04:11:17PM +0200, Arnd Bergmann wrote:
>> >> > On Wednesday 27 April 2016 14:59:00 Catalin Marinas wrote:
>> >> > > 
>> >> > > I would be in favour of a dma_inherit() function as well. We could hack
>> >> > > something up in the arch code (like below) but I would rather prefer an
>> >> > > explicit dma_inherit() call by drivers creating such devices.
>> >> > > 
>> >> > > diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
>> >> > > index ba437f090a74..ea6fb9b0e8fa 100644
>> >> > > --- a/arch/arm64/include/asm/dma-mapping.h
>> >> > > +++ b/arch/arm64/include/asm/dma-mapping.h
>> >> > > @@ -29,8 +29,11 @@ extern struct dma_map_ops dummy_dma_ops;
>> >> > >  
>> >> > >  static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
>> >> > >  {
>> >> > > -       if (dev && dev->archdata.dma_ops)
>> >> > > -               return dev->archdata.dma_ops;
>> >> > > +       while (dev) {
>> >> > > +               if (dev->archdata.dma_ops)
>> >> > > +                       return dev->archdata.dma_ops;
>> >> > > +               dev = dev->parent;
>> >> > > +       }
>> >> > 
>> >> > I think this would be a very bad idea: we don't want to have random
>> >> > devices be able to perform DMA just because their parent devices
>> >> > have been set up that way.
>> >> 
>> >> I agree, it's a big hack. It would be nice to have a simpler way to do
>> >> this in driver code rather than explicitly calling
>> >> of_dma_configure/arch_setup_dma_ops as per the original patch in this
>> >> thread.
>> >
>> > I haven't followed the entire discussion, but what's wrong with passing
>> > around a pointer to a 'struct device *hwdev' that represents the physical
>> > device that does the DMA?
>> 
>> that will likely create duplicated solutions in several drivers and
>> it'll be a pain to maintain. There's another complication, dwc3 can be
>> integrated in many different ways. See the device child-parent tree
>> representations below:
>> 
>> a) with a parent PCI device:
>> 
>> pci_bus_type
>>  - dwc3-pci
>>    - dwc3
>>      - xhci-plat
>> 
>> b) with a parent platform_device (OF):
>> 
>> platform_bus_type
>>  - dwc3-${omap,st,of-simple,exynos,keystone}
>>    - dwc3
>>      - xhci-plat
>> 
>> c) without a parent at all (thanks Grygorii):
>> 
>> platform_bus_type
>>  - dwc3
>>    - xhci-plat
>> 
>> (a) and (b) above are the common cases. The DMA-capable device is
>> clearly dwc3-${pci,omap,st,of-simple,exynos,keystone} with dwc3 only
>> having proper DMA configuration in OF platforms (because of the
>> unconditional of_dma_configure() during OF device creation) and
>> xhci-plat not knowing about DMA at all and hardcoding some crappy
>> defaults.
>> 
>> (c) is the uncommon case which creates some problems. In this case, dwc3
>> itself is the DMA-capable device and dwc3->dev->parent is the
>> platform_bus_type itself. Now consider the problem this creates:
>> 
>> i. the patch that I wrote [1] becomes invalid for (c), thanks to
>> Grygorii for pointing this out before it was too late.
>> 
>> ii. xhci-plat can also be described directly in DT (and is in some
>> cases). This means that assuming xhci-plat's parent's parent to be the
>> DMA-capable device is also an invalid assumption.
>> 
>> iii. one might argue that for DT-based platforms *with* a glue layer
>> ((b) above), OF already "copies" some sensible DMA defaults during
>> device creation.
>
> But that is exactly the point I was trying to make: instead of copying
> all the data into the xhci-plat device, just assign one pointer
> inside the xhci-plat device from whoever creates it.

and how do you pass that pointer to xhci-plat from another driver ?
No, platform_data is not an option ;-)

>> The only clean way to fix this up is with a dma_inherit()-like API which
>> would allow dwc3's glue layers ((a) and (b) above) to initialize child's
>> (dwc3) DMA configuration during child's creation. Something like below:
>> 
>> diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
>> index adc1e8a624cb..74b599269e2c 100644
>> --- a/drivers/usb/dwc3/dwc3-pci.c
>> +++ b/drivers/usb/dwc3/dwc3-pci.c
>> @@ -152,6 +152,8 @@ static int dwc3_pci_probe(struct pci_dev *pci,
>>  		return -ENOMEM;
>>  	}
>>  
>> +	dma_inherit(&dwc->dev, dev);
>> +
>>  	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
>>  
>>  	res[0].start	= pci_resource_start(pci, 0);
>> 
>> that's all I'm asking for :-) dma_inherit() should, probably, be
>> arch-specific to handle details like IOMMU (which today sits under
>> archdata).
>
> It's still wrong: the archdata in the device can contain all sorts of
> additional information about how to do DMA, and some of that information

yes, inherit all of that ;-)

> is bus specific, e.g. when your dma_map_ops look like the on sparc:

okay, let me be clear. The underlying bus is still pci_bus_type or
platform_bus_type; that won't change.

> static inline struct dma_map_ops *get_dma_ops(struct device *dev)
> {
> #ifdef CONFIG_SPARC_LEON
>         if (sparc_cpu_model == sparc_leon)
>                 return leon_dma_ops;
> #endif
> #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
>         if (dev->bus == &pci_bus_type)
>                 return &pci32_dma_ops;
> #endif
>         return dma_ops;
> }

this seems to be a rather fragile assumption, no ? Only works because
*_bus_type declarations are exported. I wonder if this is the only
reason *why* they are exported, probably not...

> There is no way for a device to "inherit" the bus_type of its parent,

I don't want to inherit bus_type, I just want DMA configuration to not
depend on bus_type directly ;-)

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160427/4310c981/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 20:05                         ` Felipe Balbi
@ 2016-04-27 21:05                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 21:05 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Felipe Balbi, Alan Stern, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

On Wednesday 27 April 2016 23:05:42 Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
> >> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
> >> 
> >> > I've looked at the usb HCD code now and see this:
> >> > 
> >> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> >> >                 struct device *dev, const char *bus_name,
> >> >                 struct usb_hcd *primary_hcd)
> >> > {
> >> >       ...
> >> >         hcd->self.controller = dev;
> >> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
> >> >       ...
> >> > }
> >> > 
> >> > What I think we need to do here is ensure that the device that gets
> >> > passed here and assigned to hcd->self.controller is the actual DMA
> >> > master device, i.e. the pci_device or platform_device that was created
> >> > from outside of the xhci stack. This is after all the pointer that
> >> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> >> > functions.
> >> 
> >> It would be better to add a new field, since self.controller is also
> >> used for lots of other purposes.  Something like hcd->self.dma_dev.
> >
> > Ok, fair enough. I only took a brief look and all uses I found were
> > either for the DMA mapping API or some printk logging.
> 
> I have a feeling you guys are not considering how the patch to implement
> this will look like.
> 
> How are you expecting dwc3 to pass a pointer to the DMA device from
> dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible 

Not any worse than it already is really. It already uses platform_data
for the exact case that is causing the problem here.

> Also, remember that the DMA device for dwc3 is not always
> dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
> us to figure that one out ?

Do you have an example for this? The ones I found here either
create the dwc3 device from PCI or from a platform glue driver.

> I still think dma_inherit() (or something along those lines) is
> necessary. Specially when you consider that, as I said previously,
> that's pretty much what of_dma_configure() does.

As I said, this is not an API that can work in general, because
it makes the assumption that everything related to DMA in a
device can be set in that device itself.

The simplest case where this does not work is a PCI device behind
an IOMMU: when you call dma_map_single() or dma_alloc_coherent(),
the dma_map_ops implementation for the IOMMU has to look at the
PCI device to find out the association with an IOMMU context,
and on most architectures you cannot bind an IOMMU context to
a platform device at all.

> Anyway, I'd really like to see a patch implementing this
> hcd->self.dma_dev logic. Consider all the duplication with this
> approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
> own. Will that be passed to dwc3 as platform_data from glue layer ? What
> about platforms which don't even use a glue layer ?

Let's separate the three problems here.

a) dwc3 creating a "xhci-hcd" platform_device that is not connected
   to any proper bus. We can work around that by adding the "self.dma_dev"
   pointer and pass that in platform_data. This is really easy, it's
   actually less code (and less iffy) than the current implementation of
   copying the parent dma mask.
   In the long run, this could be solved by doing away with the extra
   platform_device, by calling a variant of xhci_probe() from
   xhci_plat_probe() like we do for the normal *HCI drivers.

b) dwc3-pci creating a "dwc3" platform_device under the covers. This
   is pretty much the exact same problem as a) on another layer. In
   the short run, we can pass the device pointer as part of
   struct dwc3_platform_data (dwc3-pci is the only such user anway),
   and in the long run, it should be easy enough to get rid of the
   extra platform device by just calling a variant of dwc3_probe,
   which will again simplify the driver

c) some SoCs that have two separate device nodes to describe their
   dwc3 xhci. I don't think this is causing any additional problems,
   but if we want to make this behave more like other drivers in the
   long run or deal with machines that are missing a "dma-ranges"
   property in the parent node, we can kill off the
   of_platform_populate() hack and instead call dwc3_probe()
   directly from the glue drivers as in b), and have that
   do for_each_child_of_node() or similar to find the child node.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-27 21:05                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-27 21:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 27 April 2016 23:05:42 Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
> >> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
> >> 
> >> > I've looked at the usb HCD code now and see this:
> >> > 
> >> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> >> >                 struct device *dev, const char *bus_name,
> >> >                 struct usb_hcd *primary_hcd)
> >> > {
> >> >       ...
> >> >         hcd->self.controller = dev;
> >> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
> >> >       ...
> >> > }
> >> > 
> >> > What I think we need to do here is ensure that the device that gets
> >> > passed here and assigned to hcd->self.controller is the actual DMA
> >> > master device, i.e. the pci_device or platform_device that was created
> >> > from outside of the xhci stack. This is after all the pointer that
> >> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
> >> > functions.
> >> 
> >> It would be better to add a new field, since self.controller is also
> >> used for lots of other purposes.  Something like hcd->self.dma_dev.
> >
> > Ok, fair enough. I only took a brief look and all uses I found were
> > either for the DMA mapping API or some printk logging.
> 
> I have a feeling you guys are not considering how the patch to implement
> this will look like.
> 
> How are you expecting dwc3 to pass a pointer to the DMA device from
> dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible 

Not any worse than it already is really. It already uses platform_data
for the exact case that is causing the problem here.

> Also, remember that the DMA device for dwc3 is not always
> dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
> us to figure that one out ?

Do you have an example for this? The ones I found here either
create the dwc3 device from PCI or from a platform glue driver.

> I still think dma_inherit() (or something along those lines) is
> necessary. Specially when you consider that, as I said previously,
> that's pretty much what of_dma_configure() does.

As I said, this is not an API that can work in general, because
it makes the assumption that everything related to DMA in a
device can be set in that device itself.

The simplest case where this does not work is a PCI device behind
an IOMMU: when you call dma_map_single() or dma_alloc_coherent(),
the dma_map_ops implementation for the IOMMU has to look at the
PCI device to find out the association with an IOMMU context,
and on most architectures you cannot bind an IOMMU context to
a platform device at all.

> Anyway, I'd really like to see a patch implementing this
> hcd->self.dma_dev logic. Consider all the duplication with this
> approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
> own. Will that be passed to dwc3 as platform_data from glue layer ? What
> about platforms which don't even use a glue layer ?

Let's separate the three problems here.

a) dwc3 creating a "xhci-hcd" platform_device that is not connected
   to any proper bus. We can work around that by adding the "self.dma_dev"
   pointer and pass that in platform_data. This is really easy, it's
   actually less code (and less iffy) than the current implementation of
   copying the parent dma mask.
   In the long run, this could be solved by doing away with the extra
   platform_device, by calling a variant of xhci_probe() from
   xhci_plat_probe() like we do for the normal *HCI drivers.

b) dwc3-pci creating a "dwc3" platform_device under the covers. This
   is pretty much the exact same problem as a) on another layer. In
   the short run, we can pass the device pointer as part of
   struct dwc3_platform_data (dwc3-pci is the only such user anway),
   and in the long run, it should be easy enough to get rid of the
   extra platform device by just calling a variant of dwc3_probe,
   which will again simplify the driver

c) some SoCs that have two separate device nodes to describe their
   dwc3 xhci. I don't think this is causing any additional problems,
   but if we want to make this behave more like other drivers in the
   long run or deal with machines that are missing a "dma-ranges"
   property in the parent node, we can kill off the
   of_platform_populate() hack and instead call dwc3_probe()
   directly from the glue drivers as in b), and have that
   do for_each_child_of_node() or similar to find the child node.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-27 21:05                           ` Arnd Bergmann
@ 2016-04-28  6:37                             ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-28  6:37 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Alan Stern, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 6191 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 23:05:42 Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
>> >> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
>> >> 
>> >> > I've looked at the usb HCD code now and see this:
>> >> > 
>> >> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>> >> >                 struct device *dev, const char *bus_name,
>> >> >                 struct usb_hcd *primary_hcd)
>> >> > {
>> >> >       ...
>> >> >         hcd->self.controller = dev;
>> >> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
>> >> >       ...
>> >> > }
>> >> > 
>> >> > What I think we need to do here is ensure that the device that gets
>> >> > passed here and assigned to hcd->self.controller is the actual DMA
>> >> > master device, i.e. the pci_device or platform_device that was created
>> >> > from outside of the xhci stack. This is after all the pointer that
>> >> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
>> >> > functions.
>> >> 
>> >> It would be better to add a new field, since self.controller is also
>> >> used for lots of other purposes.  Something like hcd->self.dma_dev.
>> >
>> > Ok, fair enough. I only took a brief look and all uses I found were
>> > either for the DMA mapping API or some printk logging.
>> 
>> I have a feeling you guys are not considering how the patch to implement
>> this will look like.
>> 
>> How are you expecting dwc3 to pass a pointer to the DMA device from
>> dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible 
>
> Not any worse than it already is really. It already uses platform_data
> for the exact case that is causing the problem here.

there's no use of platform_data for passing around DMA configuration. By
platform_data I really mean platform_device_add_data().

>> Also, remember that the DMA device for dwc3 is not always
>> dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
>> us to figure that one out ?
>
> Do you have an example for this? The ones I found here either
> create the dwc3 device from PCI or from a platform glue driver.

arch/arm64/boot/dts/xilinx/zynqmp.dtsi

>> I still think dma_inherit() (or something along those lines) is
>> necessary. Specially when you consider that, as I said previously,
>> that's pretty much what of_dma_configure() does.
>
> As I said, this is not an API that can work in general, because
> it makes the assumption that everything related to DMA in a
> device can be set in that device itself.
>
> The simplest case where this does not work is a PCI device behind
> an IOMMU: when you call dma_map_single() or dma_alloc_coherent(),
> the dma_map_ops implementation for the IOMMU has to look at the
> PCI device to find out the association with an IOMMU context,
> and on most architectures you cannot bind an IOMMU context to
> a platform device at all.

no, it relies on dev->archdata for IOMMU. In fact, the first "patch"
(more of a hack) I wrote to fix IOMMU with dwc3 on Intel platforms was
to literally memcpy() pci's archdata to dwc3->dev and it worked just
fine with and without IOMMU enabled.

>> Anyway, I'd really like to see a patch implementing this
>> hcd->self.dma_dev logic. Consider all the duplication with this
>> approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
>> own. Will that be passed to dwc3 as platform_data from glue layer ? What
>> about platforms which don't even use a glue layer ?
>
> Let's separate the three problems here.
>
> a) dwc3 creating a "xhci-hcd" platform_device that is not connected
>    to any proper bus. We can work around that by adding the "self.dma_dev"

platform_bus_type *is* a proper bus.

>    pointer and pass that in platform_data. This is really easy, it's

Sorry but passing a struct device pointer in platform_data is
ridiculous. Not to mention that, as I said before, we can't assume which
device to pass to xhci_plat in the first place. It might be dwc->dev and
it might be dwc->dev->parent.

>    actually less code (and less iffy) than the current implementation of
>    copying the parent dma mask.
>    In the long run, this could be solved by doing away with the extra
>    platform_device, by calling a variant of xhci_probe() from
>    xhci_plat_probe() like we do for the normal *HCI drivers.

no, that's not something I'll do for dwc3. We have had this talk before
and I'm not giving up the benefits of splitting things to separate
devices.

> b) dwc3-pci creating a "dwc3" platform_device under the covers. This

it's not under the covers at all. It's pretty similar to what MFD
drivers do. It's just not wrapped in a nice API because there's no need
for that.

>    is pretty much the exact same problem as a) on another layer. In
>    the short run, we can pass the device pointer as part of
>    struct dwc3_platform_data (dwc3-pci is the only such user anway),

It's incredible that you'd even suggest this at all. Did we not have a
big trouble to solve on ARM land because of different mach-* passing
function pointers and other pointers from arch/arch/mach-* instead of
abstracting things away. Then came DT to the rescue, a setup where you
can't even pass code or kernel objects ;-)

>    and in the long run, it should be easy enough to get rid of the
>    extra platform device by just calling a variant of dwc3_probe,
>    which will again simplify the driver

also again definitely not something I'll do

> c) some SoCs that have two separate device nodes to describe their
>    dwc3 xhci. I don't think this is causing any additional problems,
>    but if we want to make this behave more like other drivers in the
>    long run or deal with machines that are missing a "dma-ranges"
>    property in the parent node, we can kill off the
>    of_platform_populate() hack and instead call dwc3_probe()
>    directly from the glue drivers as in b), and have that
>    do for_each_child_of_node() or similar to find the child node.

no, we cannot.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-28  6:37                             ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-28  6:37 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Wednesday 27 April 2016 23:05:42 Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Wednesday 27 April 2016 13:59:13 Alan Stern wrote:
>> >> On Wed, 27 Apr 2016, Arnd Bergmann wrote:
>> >> 
>> >> > I've looked at the usb HCD code now and see this:
>> >> > 
>> >> > struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>> >> >                 struct device *dev, const char *bus_name,
>> >> >                 struct usb_hcd *primary_hcd)
>> >> > {
>> >> >       ...
>> >> >         hcd->self.controller = dev;
>> >> >         hcd->self.uses_dma = (dev->dma_mask != NULL);
>> >> >       ...
>> >> > }
>> >> > 
>> >> > What I think we need to do here is ensure that the device that gets
>> >> > passed here and assigned to hcd->self.controller is the actual DMA
>> >> > master device, i.e. the pci_device or platform_device that was created
>> >> > from outside of the xhci stack. This is after all the pointer that
>> >> > gets passed into all the dma_map_*/dma_sync_*/dma_alloc_*/...
>> >> > functions.
>> >> 
>> >> It would be better to add a new field, since self.controller is also
>> >> used for lots of other purposes.  Something like hcd->self.dma_dev.
>> >
>> > Ok, fair enough. I only took a brief look and all uses I found were
>> > either for the DMA mapping API or some printk logging.
>> 
>> I have a feeling you guys are not considering how the patch to implement
>> this will look like.
>> 
>> How are you expecting dwc3 to pass a pointer to the DMA device from
>> dwc3.ko to xhci-plat ? platform_data ? That's gonna be horrible 
>
> Not any worse than it already is really. It already uses platform_data
> for the exact case that is causing the problem here.

there's no use of platform_data for passing around DMA configuration. By
platform_data I really mean platform_device_add_data().

>> Also, remember that the DMA device for dwc3 is not always
>> dwc3->dev->parent. It might be dwc3->dev itself. How are you expecting
>> us to figure that one out ?
>
> Do you have an example for this? The ones I found here either
> create the dwc3 device from PCI or from a platform glue driver.

arch/arm64/boot/dts/xilinx/zynqmp.dtsi

>> I still think dma_inherit() (or something along those lines) is
>> necessary. Specially when you consider that, as I said previously,
>> that's pretty much what of_dma_configure() does.
>
> As I said, this is not an API that can work in general, because
> it makes the assumption that everything related to DMA in a
> device can be set in that device itself.
>
> The simplest case where this does not work is a PCI device behind
> an IOMMU: when you call dma_map_single() or dma_alloc_coherent(),
> the dma_map_ops implementation for the IOMMU has to look at the
> PCI device to find out the association with an IOMMU context,
> and on most architectures you cannot bind an IOMMU context to
> a platform device at all.

no, it relies on dev->archdata for IOMMU. In fact, the first "patch"
(more of a hack) I wrote to fix IOMMU with dwc3 on Intel platforms was
to literally memcpy() pci's archdata to dwc3->dev and it worked just
fine with and without IOMMU enabled.

>> Anyway, I'd really like to see a patch implementing this
>> hcd->self.dma_dev logic. Consider all the duplication with this
>> approach, btw. struct dwc3 will *also* need a dwc->dma_dev of its
>> own. Will that be passed to dwc3 as platform_data from glue layer ? What
>> about platforms which don't even use a glue layer ?
>
> Let's separate the three problems here.
>
> a) dwc3 creating a "xhci-hcd" platform_device that is not connected
>    to any proper bus. We can work around that by adding the "self.dma_dev"

platform_bus_type *is* a proper bus.

>    pointer and pass that in platform_data. This is really easy, it's

Sorry but passing a struct device pointer in platform_data is
ridiculous. Not to mention that, as I said before, we can't assume which
device to pass to xhci_plat in the first place. It might be dwc->dev and
it might be dwc->dev->parent.

>    actually less code (and less iffy) than the current implementation of
>    copying the parent dma mask.
>    In the long run, this could be solved by doing away with the extra
>    platform_device, by calling a variant of xhci_probe() from
>    xhci_plat_probe() like we do for the normal *HCI drivers.

no, that's not something I'll do for dwc3. We have had this talk before
and I'm not giving up the benefits of splitting things to separate
devices.

> b) dwc3-pci creating a "dwc3" platform_device under the covers. This

it's not under the covers at all. It's pretty similar to what MFD
drivers do. It's just not wrapped in a nice API because there's no need
for that.

>    is pretty much the exact same problem as a) on another layer. In
>    the short run, we can pass the device pointer as part of
>    struct dwc3_platform_data (dwc3-pci is the only such user anway),

It's incredible that you'd even suggest this at all. Did we not have a
big trouble to solve on ARM land because of different mach-* passing
function pointers and other pointers from arch/arch/mach-* instead of
abstracting things away. Then came DT to the rescue, a setup where you
can't even pass code or kernel objects ;-)

>    and in the long run, it should be easy enough to get rid of the
>    extra platform device by just calling a variant of dwc3_probe,
>    which will again simplify the driver

also again definitely not something I'll do

> c) some SoCs that have two separate device nodes to describe their
>    dwc3 xhci. I don't think this is causing any additional problems,
>    but if we want to make this behave more like other drivers in the
>    long run or deal with machines that are missing a "dma-ranges"
>    property in the parent node, we can kill off the
>    of_platform_populate() hack and instead call dwc3_probe()
>    directly from the glue drivers as in b), and have that
>    do for_each_child_of_node() or similar to find the child node.

no, we cannot.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160428/e528cf76/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-28  6:37                             ` Felipe Balbi
@ 2016-04-28 14:16                               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-04-28 14:16 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Arnd Bergmann, linux-arm-kernel, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman

On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> >    pointer and pass that in platform_data. This is really easy, it's
> 
> Sorry but passing a struct device pointer in platform_data is
> ridiculous. Not to mention that, as I said before, we can't assume which
> device to pass to xhci_plat in the first place. It might be dwc->dev and
> it might be dwc->dev->parent.

+1.  Passing an unref-counted struct device through platform data is
totally mad, Arnd you're off your rocker if you think that's a good
idea.  What's more is that there's no way to properly refcount the
thing.

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-28 14:16                               ` Russell King - ARM Linux
  0 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-04-28 14:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> >    pointer and pass that in platform_data. This is really easy, it's
> 
> Sorry but passing a struct device pointer in platform_data is
> ridiculous. Not to mention that, as I said before, we can't assume which
> device to pass to xhci_plat in the first place. It might be dwc->dev and
> it might be dwc->dev->parent.

+1.  Passing an unref-counted struct device through platform data is
totally mad, Arnd you're off your rocker if you think that's a good
idea.  What's more is that there's no way to properly refcount the
thing.

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-28 14:16                               ` Russell King - ARM Linux
@ 2016-04-28 14:23                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-28 14:23 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Felipe Balbi, linux-arm-kernel, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	linux-kernel, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman

On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > >    pointer and pass that in platform_data. This is really easy, it's
> > 
> > Sorry but passing a struct device pointer in platform_data is
> > ridiculous. Not to mention that, as I said before, we can't assume which
> > device to pass to xhci_plat in the first place. It might be dwc->dev and
> > it might be dwc->dev->parent.
> 
> +1.  Passing an unref-counted struct device through platform data is
> totally mad, Arnd you're off your rocker if you think that's a good
> idea.  What's more is that there's no way to properly refcount the
> thing.

It's the parent device (or NULL), there is no way it can ever go away as
it's already refcounted through the device subsystem by the creation
of the child device.

I do realize that it's a hack, but the idea is to get rid of that
as soon as possibly by fixing the way the xhci device is probe so
we no longer need to fake a platform_device as the child here and
can just use the device itself.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-28 14:23                                 ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-04-28 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > >    pointer and pass that in platform_data. This is really easy, it's
> > 
> > Sorry but passing a struct device pointer in platform_data is
> > ridiculous. Not to mention that, as I said before, we can't assume which
> > device to pass to xhci_plat in the first place. It might be dwc->dev and
> > it might be dwc->dev->parent.
> 
> +1.  Passing an unref-counted struct device through platform data is
> totally mad, Arnd you're off your rocker if you think that's a good
> idea.  What's more is that there's no way to properly refcount the
> thing.

It's the parent device (or NULL), there is no way it can ever go away as
it's already refcounted through the device subsystem by the creation
of the child device.

I do realize that it's a hack, but the idea is to get rid of that
as soon as possibly by fixing the way the xhci device is probe so
we no longer need to fake a platform_device as the child here and
can just use the device itself.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-28 14:23                                 ` Arnd Bergmann
@ 2016-04-28 14:27                                   ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-28 14:27 UTC (permalink / raw)
  To: Arnd Bergmann, Russell King - ARM Linux
  Cc: linux-arm-kernel, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, linux-kernel,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 1989 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
>> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
>> > 
>> > Hi,
>> > 
>> > Arnd Bergmann <arnd@arndb.de> writes:
>> > >    pointer and pass that in platform_data. This is really easy, it's
>> > 
>> > Sorry but passing a struct device pointer in platform_data is
>> > ridiculous. Not to mention that, as I said before, we can't assume which
>> > device to pass to xhci_plat in the first place. It might be dwc->dev and
>> > it might be dwc->dev->parent.
>> 
>> +1.  Passing an unref-counted struct device through platform data is
>> totally mad, Arnd you're off your rocker if you think that's a good
>> idea.  What's more is that there's no way to properly refcount the
>> thing.
>
> It's the parent device (or NULL), there is no way it can ever go away as
> it's already refcounted through the device subsystem by the creation
> of the child device.

you're assuming that based on what we have today. We could get into a
situation where we need to use a completely unrelated device and the
problem exists again.

> I do realize that it's a hack, but the idea is to get rid of that
> as soon as possibly by fixing the way the xhci device is probe so
> we no longer need to fake a platform_device as the child here and
> can just use the device itself.

okay, let me try to be extra clear here:

We will *not* remove the extra platform_device because it actually
*does* exist and helps me hide/abstract a bunch of details and make
assumptions about order of certain events. We have already gone through
that in the past when I explained why I wrote dwc3 the way it is; if you
need a refresher, there are mailing list archives for that.

Moreover, this same problem exists for anything under drivers/mfd. It
just so happens that they're usually some i2c or spi device which don't
do DMA by themselves.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-04-28 14:27                                   ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-04-28 14:27 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
>> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
>> > 
>> > Hi,
>> > 
>> > Arnd Bergmann <arnd@arndb.de> writes:
>> > >    pointer and pass that in platform_data. This is really easy, it's
>> > 
>> > Sorry but passing a struct device pointer in platform_data is
>> > ridiculous. Not to mention that, as I said before, we can't assume which
>> > device to pass to xhci_plat in the first place. It might be dwc->dev and
>> > it might be dwc->dev->parent.
>> 
>> +1.  Passing an unref-counted struct device through platform data is
>> totally mad, Arnd you're off your rocker if you think that's a good
>> idea.  What's more is that there's no way to properly refcount the
>> thing.
>
> It's the parent device (or NULL), there is no way it can ever go away as
> it's already refcounted through the device subsystem by the creation
> of the child device.

you're assuming that based on what we have today. We could get into a
situation where we need to use a completely unrelated device and the
problem exists again.

> I do realize that it's a hack, but the idea is to get rid of that
> as soon as possibly by fixing the way the xhci device is probe so
> we no longer need to fake a platform_device as the child here and
> can just use the device itself.

okay, let me try to be extra clear here:

We will *not* remove the extra platform_device because it actually
*does* exist and helps me hide/abstract a bunch of details and make
assumptions about order of certain events. We have already gone through
that in the past when I explained why I wrote dwc3 the way it is; if you
need a refresher, there are mailing list archives for that.

Moreover, this same problem exists for anything under drivers/mfd. It
just so happens that they're usually some i2c or spi device which don't
do DMA by themselves.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160428/a6f1334a/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-25 19:21 ` Grygorii Strashko
@ 2016-05-05 17:07   ` Brian Norris
  -1 siblings, 0 replies; 182+ messages in thread
From: Brian Norris @ 2016-05-05 17:07 UTC (permalink / raw)
  To: Strashko, Grygorii
  Cc: Felipe Balbi, Greg Kroah-Hartman, linux-arm-kernel, linux-usb,
	linux-kernel, Sekhar Nori, David Fisher, Catalin Marinas,
	Thang Q. Nguyen, Yoshihiro Shimoda, linux-rockchip, dianders,
	wulf, Brian Norris, Arnd Bergmann

On Mon, Apr 25, 2016 at 10:21:34PM +0300, Strashko, Grygorii wrote:
> Now not all DMA paremters configured properly for "xhci-hcd" platform
> device which is created manually. For example: dma_pfn_offset, dam_ops
> and iommu configuration will not corresponds "dwc3" devices
> configuration. As result, this will cause problems like wrong DMA
> addresses translation on platforms with LPAE enabled like Keystone 2.
> 
> When platform is using DT boot mode the DMA configuration will be
> parsed and applied from DT, so, to fix this issue, reuse
> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> from DWC3 device node.
> 
> Cc: David Fisher <david.fisher1@synopsys.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Thang Q. Nguyen" <tqnguyen@apm.com>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>

Tested-by: Brian Norris <briannorris@chromium.org>

What's the status of this? I see that there was some divergent
discussion about the merits of a dma_inherit() API...

FWIW, I'll reiterate Grygorii's note that Felipe's alternative patch
does NOT resolve the problem with the creation of the xhci-hcd platform
device:

https://patchwork.kernel.org/patch/8952721/

Brian

> ---
> drivers/usb/dwc3/host.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index c679f63..93c8ef9 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -17,6 +17,7 @@
>  
>  #include <linux/platform_device.h>
>  #include <linux/usb/xhci_pdriver.h>
> +#include <linux/of_device.h>
>  
>  #include "core.h"
>  
> @@ -32,12 +33,7 @@ int dwc3_host_init(struct dwc3 *dwc)
>  		return -ENOMEM;
>  	}
>  
> -	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
> -
>  	xhci->dev.parent	= dwc->dev;
> -	xhci->dev.dma_mask	= dwc->dev->dma_mask;
> -	xhci->dev.dma_parms	= dwc->dev->dma_parms;
> -
>  	dwc->xhci = xhci;
>  
>  	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
> @@ -62,6 +58,15 @@ int dwc3_host_init(struct dwc3 *dwc)
>  	phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
>  			  dev_name(&xhci->dev));
>  
> +	if (IS_ENABLED(CONFIG_OF) && dwc->dev->of_node) {
> +		of_dma_configure(&xhci->dev, dwc->dev->of_node);
> +	} else {
> +		dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
> +
> +		xhci->dev.dma_mask	= dwc->dev->dma_mask;
> +		xhci->dev.dma_parms	= dwc->dev->dma_parms;
> +	}
> +
>  	ret = platform_device_add(xhci);
>  	if (ret) {
>  		dev_err(dwc->dev, "failed to register xHCI device\n");

^ permalink raw reply	[flat|nested] 182+ messages in thread

* usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-05-05 17:07   ` Brian Norris
  0 siblings, 0 replies; 182+ messages in thread
From: Brian Norris @ 2016-05-05 17:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 25, 2016 at 10:21:34PM +0300, Strashko, Grygorii wrote:
> Now not all DMA paremters configured properly for "xhci-hcd" platform
> device which is created manually. For example: dma_pfn_offset, dam_ops
> and iommu configuration will not corresponds "dwc3" devices
> configuration. As result, this will cause problems like wrong DMA
> addresses translation on platforms with LPAE enabled like Keystone 2.
> 
> When platform is using DT boot mode the DMA configuration will be
> parsed and applied from DT, so, to fix this issue, reuse
> of_dma_configure() API and retrieve DMA configuartion for "xhci-hcd"
> from DWC3 device node.
> 
> Cc: David Fisher <david.fisher1@synopsys.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: "Thang Q. Nguyen" <tqnguyen@apm.com>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>

Tested-by: Brian Norris <briannorris@chromium.org>

What's the status of this? I see that there was some divergent
discussion about the merits of a dma_inherit() API...

FWIW, I'll reiterate Grygorii's note that Felipe's alternative patch
does NOT resolve the problem with the creation of the xhci-hcd platform
device:

https://patchwork.kernel.org/patch/8952721/

Brian

> ---
> drivers/usb/dwc3/host.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index c679f63..93c8ef9 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -17,6 +17,7 @@
>  
>  #include <linux/platform_device.h>
>  #include <linux/usb/xhci_pdriver.h>
> +#include <linux/of_device.h>
>  
>  #include "core.h"
>  
> @@ -32,12 +33,7 @@ int dwc3_host_init(struct dwc3 *dwc)
>  		return -ENOMEM;
>  	}
>  
> -	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
> -
>  	xhci->dev.parent	= dwc->dev;
> -	xhci->dev.dma_mask	= dwc->dev->dma_mask;
> -	xhci->dev.dma_parms	= dwc->dev->dma_parms;
> -
>  	dwc->xhci = xhci;
>  
>  	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
> @@ -62,6 +58,15 @@ int dwc3_host_init(struct dwc3 *dwc)
>  	phy_create_lookup(dwc->usb3_generic_phy, "usb3-phy",
>  			  dev_name(&xhci->dev));
>  
> +	if (IS_ENABLED(CONFIG_OF) && dwc->dev->of_node) {
> +		of_dma_configure(&xhci->dev, dwc->dev->of_node);
> +	} else {
> +		dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
> +
> +		xhci->dev.dma_mask	= dwc->dev->dma_mask;
> +		xhci->dev.dma_parms	= dwc->dev->dma_parms;
> +	}
> +
>  	ret = platform_device_add(xhci);
>  	if (ret) {
>  		dev_err(dwc->dev, "failed to register xHCI device\n");

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-04-28 14:27                                   ` Felipe Balbi
@ 2016-09-01 22:14                                     ` Leo Li
  -1 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-09-01 22:14 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Arnd Bergmann, Russell King - ARM Linux, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

On Thu, Apr 28, 2016 at 9:27 AM, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
>>> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
>>> >
>>> > Hi,
>>> >
>>> > Arnd Bergmann <arnd@arndb.de> writes:
>>> > >    pointer and pass that in platform_data. This is really easy, it's
>>> >
>>> > Sorry but passing a struct device pointer in platform_data is
>>> > ridiculous. Not to mention that, as I said before, we can't assume which
>>> > device to pass to xhci_plat in the first place. It might be dwc->dev and
>>> > it might be dwc->dev->parent.
>>>
>>> +1.  Passing an unref-counted struct device through platform data is
>>> totally mad, Arnd you're off your rocker if you think that's a good
>>> idea.  What's more is that there's no way to properly refcount the
>>> thing.
>>
>> It's the parent device (or NULL), there is no way it can ever go away as
>> it's already refcounted through the device subsystem by the creation
>> of the child device.
>
> you're assuming that based on what we have today. We could get into a
> situation where we need to use a completely unrelated device and the
> problem exists again.
>
>> I do realize that it's a hack, but the idea is to get rid of that
>> as soon as possibly by fixing the way the xhci device is probe so
>> we no longer need to fake a platform_device as the child here and
>> can just use the device itself.
>
> okay, let me try to be extra clear here:
>
> We will *not* remove the extra platform_device because it actually
> *does* exist and helps me hide/abstract a bunch of details and make
> assumptions about order of certain events. We have already gone through
> that in the past when I explained why I wrote dwc3 the way it is; if you
> need a refresher, there are mailing list archives for that.
>
> Moreover, this same problem exists for anything under drivers/mfd. It
> just so happens that they're usually some i2c or spi device which don't
> do DMA by themselves.

Hi Felipe and Arnd,

It has been a while since the last response to this discussion, but we
haven't reached an agreement yet!  Can we get to a conclusion on if it
is valid to create child platform device for abstraction purpose?  If
yes, can this child device do DMA by itself?

- Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-01 22:14                                     ` Leo Li
  0 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-09-01 22:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 28, 2016 at 9:27 AM, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday 28 April 2016 15:16:12 Russell King - ARM Linux wrote:
>>> On Thu, Apr 28, 2016 at 09:37:08AM +0300, Felipe Balbi wrote:
>>> >
>>> > Hi,
>>> >
>>> > Arnd Bergmann <arnd@arndb.de> writes:
>>> > >    pointer and pass that in platform_data. This is really easy, it's
>>> >
>>> > Sorry but passing a struct device pointer in platform_data is
>>> > ridiculous. Not to mention that, as I said before, we can't assume which
>>> > device to pass to xhci_plat in the first place. It might be dwc->dev and
>>> > it might be dwc->dev->parent.
>>>
>>> +1.  Passing an unref-counted struct device through platform data is
>>> totally mad, Arnd you're off your rocker if you think that's a good
>>> idea.  What's more is that there's no way to properly refcount the
>>> thing.
>>
>> It's the parent device (or NULL), there is no way it can ever go away as
>> it's already refcounted through the device subsystem by the creation
>> of the child device.
>
> you're assuming that based on what we have today. We could get into a
> situation where we need to use a completely unrelated device and the
> problem exists again.
>
>> I do realize that it's a hack, but the idea is to get rid of that
>> as soon as possibly by fixing the way the xhci device is probe so
>> we no longer need to fake a platform_device as the child here and
>> can just use the device itself.
>
> okay, let me try to be extra clear here:
>
> We will *not* remove the extra platform_device because it actually
> *does* exist and helps me hide/abstract a bunch of details and make
> assumptions about order of certain events. We have already gone through
> that in the past when I explained why I wrote dwc3 the way it is; if you
> need a refresher, there are mailing list archives for that.
>
> Moreover, this same problem exists for anything under drivers/mfd. It
> just so happens that they're usually some i2c or spi device which don't
> do DMA by themselves.

Hi Felipe and Arnd,

It has been a while since the last response to this discussion, but we
haven't reached an agreement yet!  Can we get to a conclusion on if it
is valid to create child platform device for abstraction purpose?  If
yes, can this child device do DMA by itself?

- Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-01 22:14                                     ` Leo Li
@ 2016-09-02 10:43                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 10:43 UTC (permalink / raw)
  To: Leo Li
  Cc: Felipe Balbi, Russell King - ARM Linux, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> 
> Hi Felipe and Arnd,
> 
> It has been a while since the last response to this discussion, but we
> haven't reached an agreement yet!  Can we get to a conclusion on if it
> is valid to create child platform device for abstraction purpose?  If
> yes, can this child device do DMA by itself?

I'd say it's no problem for a driver to create child devices in order
to represent different aspects of a device, but you should not rely on
those devices working when used with the dma-mapping interfaces.

This used to be simpler back when we could configure the kernel for
only one SoC platform at a time, and the platforms could provide their
own overrides for the dma-mapping interfaces. These days, we rely on
firmware or bootloader to describe various aspects of how DMA is done,
so you can't assume that passing a device without an of_node pointer
or ACPI data into those functions will do the right thing.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 10:43                                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> 
> Hi Felipe and Arnd,
> 
> It has been a while since the last response to this discussion, but we
> haven't reached an agreement yet!  Can we get to a conclusion on if it
> is valid to create child platform device for abstraction purpose?  If
> yes, can this child device do DMA by itself?

I'd say it's no problem for a driver to create child devices in order
to represent different aspects of a device, but you should not rely on
those devices working when used with the dma-mapping interfaces.

This used to be simpler back when we could configure the kernel for
only one SoC platform at a time, and the platforms could provide their
own overrides for the dma-mapping interfaces. These days, we rely on
firmware or bootloader to describe various aspects of how DMA is done,
so you can't assume that passing a device without an of_node pointer
or ACPI data into those functions will do the right thing.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 10:43                                       ` Arnd Bergmann
@ 2016-09-02 10:47                                         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 10:47 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, David Fisher,
	Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> > 
> > Hi Felipe and Arnd,
> > 
> > It has been a while since the last response to this discussion, but we
> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> > is valid to create child platform device for abstraction purpose?  If
> > yes, can this child device do DMA by itself?
> 
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.

That's absolutely right.  Consider the USB model - only the USB host
controller can perform DMA, not the USB devices themselves.  All DMA
mappings need to be mapped using the USB host controller device struct
not the USB device struct.

The same _should_ be true everywhere else: the struct device representing
the device performing DMA must be the one used to map the transfer.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 10:47                                         ` Russell King - ARM Linux
  0 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> > 
> > Hi Felipe and Arnd,
> > 
> > It has been a while since the last response to this discussion, but we
> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> > is valid to create child platform device for abstraction purpose?  If
> > yes, can this child device do DMA by itself?
> 
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.

That's absolutely right.  Consider the USB model - only the USB host
controller can perform DMA, not the USB devices themselves.  All DMA
mappings need to be mapped using the USB host controller device struct
not the USB device struct.

The same _should_ be true everywhere else: the struct device representing
the device performing DMA must be the one used to map the transfer.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 10:43                                       ` Arnd Bergmann
@ 2016-09-02 10:53                                         ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 10:53 UTC (permalink / raw)
  To: Arnd Bergmann, Leo Li
  Cc: Russell King - ARM Linux, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, David Fisher,
	Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

[-- Attachment #1: Type: text/plain, Size: 1837 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>> 
>> Hi Felipe and Arnd,
>> 
>> It has been a while since the last response to this discussion, but we
>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>> is valid to create child platform device for abstraction purpose?  If
>> yes, can this child device do DMA by itself?
>
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.

heh, that looks like an excuse to me :-)

This will always be a problem for e.g. MFD, for example. Are you saying
MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
you read it that way, right?

> This used to be simpler back when we could configure the kernel for
> only one SoC platform at a time, and the platforms could provide their
> own overrides for the dma-mapping interfaces. These days, we rely on

right, so we have a very old regression that just took a complex driver
such as dwc3 to trigger ;-)

> firmware or bootloader to describe various aspects of how DMA is done,

there's no DMA description in DT. Every OF device gets the same 32-bit
DMA mask and that is, itself, wrong for several devices.

> so you can't assume that passing a device without an of_node pointer
> or ACPI data into those functions will do the right thing.

That's not the problem, however. We can very easily pass along
ACPI_COMPANION() to any platform_device we want, but that's not enough
because DMA-related bits are passed along with archdata; but archdata
isn't generic in any way. Some arches (like x86) _do_ use it for DMA,
but some don't.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 10:53                                         ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 10:53 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>> 
>> Hi Felipe and Arnd,
>> 
>> It has been a while since the last response to this discussion, but we
>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>> is valid to create child platform device for abstraction purpose?  If
>> yes, can this child device do DMA by itself?
>
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.

heh, that looks like an excuse to me :-)

This will always be a problem for e.g. MFD, for example. Are you saying
MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
you read it that way, right?

> This used to be simpler back when we could configure the kernel for
> only one SoC platform at a time, and the platforms could provide their
> own overrides for the dma-mapping interfaces. These days, we rely on

right, so we have a very old regression that just took a complex driver
such as dwc3 to trigger ;-)

> firmware or bootloader to describe various aspects of how DMA is done,

there's no DMA description in DT. Every OF device gets the same 32-bit
DMA mask and that is, itself, wrong for several devices.

> so you can't assume that passing a device without an of_node pointer
> or ACPI data into those functions will do the right thing.

That's not the problem, however. We can very easily pass along
ACPI_COMPANION() to any platform_device we want, but that's not enough
because DMA-related bits are passed along with archdata; but archdata
isn't generic in any way. Some arches (like x86) _do_ use it for DMA,
but some don't.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160902/70477046/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 10:47                                         ` Russell King - ARM Linux
@ 2016-09-02 11:08                                           ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 11:08 UTC (permalink / raw)
  To: Russell King - ARM Linux, Arnd Bergmann
  Cc: Leo Li, Grygorii Strashko, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel, Stuart Yoder,
	Scott Wood

[-- Attachment #1: Type: text/plain, Size: 1636 bytes --]


Hi,

Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>> > 
>> > Hi Felipe and Arnd,
>> > 
>> > It has been a while since the last response to this discussion, but we
>> > haven't reached an agreement yet!  Can we get to a conclusion on if it
>> > is valid to create child platform device for abstraction purpose?  If
>> > yes, can this child device do DMA by itself?
>> 
>> I'd say it's no problem for a driver to create child devices in order
>> to represent different aspects of a device, but you should not rely on
>> those devices working when used with the dma-mapping interfaces.
>
> That's absolutely right.  Consider the USB model - only the USB host
> controller can perform DMA, not the USB devices themselves.  All DMA
> mappings need to be mapped using the USB host controller device struct
> not the USB device struct.
>
> The same _should_ be true everywhere else: the struct device representing
> the device performing DMA must be the one used to map the transfer.

How do we fix dwc3 in dual-role, then?

Peripheral-side dwc3 is easy, we just require a glue-layer to be present
and use dwc3.ko's parent device (which will be the PCI device or OF
device). But for host side dwc3, the problem is slightly more complex
because we're using xhci-plat.ko by just instantiating a xhci-platform
device so xhci-plat can probe.

xhci core has no means to know if its own device or the parent of its
parent should be used for DMA. Any ideas?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 11:08                                           ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 11:08 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>> > 
>> > Hi Felipe and Arnd,
>> > 
>> > It has been a while since the last response to this discussion, but we
>> > haven't reached an agreement yet!  Can we get to a conclusion on if it
>> > is valid to create child platform device for abstraction purpose?  If
>> > yes, can this child device do DMA by itself?
>> 
>> I'd say it's no problem for a driver to create child devices in order
>> to represent different aspects of a device, but you should not rely on
>> those devices working when used with the dma-mapping interfaces.
>
> That's absolutely right.  Consider the USB model - only the USB host
> controller can perform DMA, not the USB devices themselves.  All DMA
> mappings need to be mapped using the USB host controller device struct
> not the USB device struct.
>
> The same _should_ be true everywhere else: the struct device representing
> the device performing DMA must be the one used to map the transfer.

How do we fix dwc3 in dual-role, then?

Peripheral-side dwc3 is easy, we just require a glue-layer to be present
and use dwc3.ko's parent device (which will be the PCI device or OF
device). But for host side dwc3, the problem is slightly more complex
because we're using xhci-plat.ko by just instantiating a xhci-platform
device so xhci-plat can probe.

xhci core has no means to know if its own device or the parent of its
parent should be used for DMA. Any ideas?

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160902/359a1892/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 10:53                                         ` Felipe Balbi
@ 2016-09-02 11:55                                           ` Robin Murphy
  -1 siblings, 0 replies; 182+ messages in thread
From: Robin Murphy @ 2016-09-02 11:55 UTC (permalink / raw)
  To: Felipe Balbi, Arnd Bergmann, Leo Li
  Cc: Grygorii Strashko, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel

On 02/09/16 11:53, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>
>>> Hi Felipe and Arnd,
>>>
>>> It has been a while since the last response to this discussion, but we
>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>> is valid to create child platform device for abstraction purpose?  If
>>> yes, can this child device do DMA by itself?
>>
>> I'd say it's no problem for a driver to create child devices in order
>> to represent different aspects of a device, but you should not rely on
>> those devices working when used with the dma-mapping interfaces.
> 
> heh, that looks like an excuse to me :-)
> 
> This will always be a problem for e.g. MFD, for example. Are you saying
> MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
> you read it that way, right?
> 
>> This used to be simpler back when we could configure the kernel for
>> only one SoC platform at a time, and the platforms could provide their
>> own overrides for the dma-mapping interfaces. These days, we rely on
> 
> right, so we have a very old regression that just took a complex driver
> such as dwc3 to trigger ;-)
> 
>> firmware or bootloader to describe various aspects of how DMA is done,
> 
> there's no DMA description in DT. Every OF device gets the same 32-bit
> DMA mask and that is, itself, wrong for several devices.

Huh? There's only no DMA description in DT if the device can be assumed
to be happy with the defaults. Anything else should be using
"dma-ranges", "dma-coherent", etc. to describe non-default integration
aspects. For devices with an inherent fixed addressing capability !=32
bits, then it's down to the driver to call dma_set_mask() appropriately
to override the default 32-bit mask (which is not unique to OF-probed
devices either).

Sure, it's by no means a perfect API, but you're railing against
untruths here.

Robin.

>> so you can't assume that passing a device without an of_node pointer
>> or ACPI data into those functions will do the right thing.
> 
> That's not the problem, however. We can very easily pass along
> ACPI_COMPANION() to any platform_device we want, but that's not enough
> because DMA-related bits are passed along with archdata; but archdata
> isn't generic in any way. Some arches (like x86) _do_ use it for DMA,
> but some don't.
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 11:55                                           ` Robin Murphy
  0 siblings, 0 replies; 182+ messages in thread
From: Robin Murphy @ 2016-09-02 11:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/09/16 11:53, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>
>>> Hi Felipe and Arnd,
>>>
>>> It has been a while since the last response to this discussion, but we
>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>> is valid to create child platform device for abstraction purpose?  If
>>> yes, can this child device do DMA by itself?
>>
>> I'd say it's no problem for a driver to create child devices in order
>> to represent different aspects of a device, but you should not rely on
>> those devices working when used with the dma-mapping interfaces.
> 
> heh, that looks like an excuse to me :-)
> 
> This will always be a problem for e.g. MFD, for example. Are you saying
> MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
> you read it that way, right?
> 
>> This used to be simpler back when we could configure the kernel for
>> only one SoC platform at a time, and the platforms could provide their
>> own overrides for the dma-mapping interfaces. These days, we rely on
> 
> right, so we have a very old regression that just took a complex driver
> such as dwc3 to trigger ;-)
> 
>> firmware or bootloader to describe various aspects of how DMA is done,
> 
> there's no DMA description in DT. Every OF device gets the same 32-bit
> DMA mask and that is, itself, wrong for several devices.

Huh? There's only no DMA description in DT if the device can be assumed
to be happy with the defaults. Anything else should be using
"dma-ranges", "dma-coherent", etc. to describe non-default integration
aspects. For devices with an inherent fixed addressing capability !=32
bits, then it's down to the driver to call dma_set_mask() appropriately
to override the default 32-bit mask (which is not unique to OF-probed
devices either).

Sure, it's by no means a perfect API, but you're railing against
untruths here.

Robin.

>> so you can't assume that passing a device without an of_node pointer
>> or ACPI data into those functions will do the right thing.
> 
> That's not the problem, however. We can very easily pass along
> ACPI_COMPANION() to any platform_device we want, but that's not enough
> because DMA-related bits are passed along with archdata; but archdata
> isn't generic in any way. Some arches (like x86) _do_ use it for DMA,
> but some don't.
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 11:55                                           ` Robin Murphy
@ 2016-09-02 12:56                                             ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 12:56 UTC (permalink / raw)
  To: Robin Murphy, Arnd Bergmann, Leo Li
  Cc: Grygorii Strashko, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]


Hi,

Robin Murphy <robin.murphy@arm.com> writes:
>>>> It has been a while since the last response to this discussion, but we
>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>> is valid to create child platform device for abstraction purpose?  If
>>>> yes, can this child device do DMA by itself?
>>>
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>> 
>> heh, that looks like an excuse to me :-)
>> 
>> This will always be a problem for e.g. MFD, for example. Are you saying
>> MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
>> you read it that way, right?
>> 
>>> This used to be simpler back when we could configure the kernel for
>>> only one SoC platform at a time, and the platforms could provide their
>>> own overrides for the dma-mapping interfaces. These days, we rely on
>> 
>> right, so we have a very old regression that just took a complex driver
>> such as dwc3 to trigger ;-)
>> 
>>> firmware or bootloader to describe various aspects of how DMA is done,
>> 
>> there's no DMA description in DT. Every OF device gets the same 32-bit
>> DMA mask and that is, itself, wrong for several devices.
>
> Huh? There's only no DMA description in DT if the device can be assumed
> to be happy with the defaults. Anything else should be using
> "dma-ranges", "dma-coherent", etc. to describe non-default integration

heh, guilty as charged. I never noticed we had dma-ranges or
dma-coherent.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 12:56                                             ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 12:56 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Robin Murphy <robin.murphy@arm.com> writes:
>>>> It has been a while since the last response to this discussion, but we
>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>> is valid to create child platform device for abstraction purpose?  If
>>>> yes, can this child device do DMA by itself?
>>>
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>> 
>> heh, that looks like an excuse to me :-)
>> 
>> This will always be a problem for e.g. MFD, for example. Are you saying
>> MFD child-devices shouldn't be allowed to do DMA? It becomes silly when
>> you read it that way, right?
>> 
>>> This used to be simpler back when we could configure the kernel for
>>> only one SoC platform at a time, and the platforms could provide their
>>> own overrides for the dma-mapping interfaces. These days, we rely on
>> 
>> right, so we have a very old regression that just took a complex driver
>> such as dwc3 to trigger ;-)
>> 
>>> firmware or bootloader to describe various aspects of how DMA is done,
>> 
>> there's no DMA description in DT. Every OF device gets the same 32-bit
>> DMA mask and that is, itself, wrong for several devices.
>
> Huh? There's only no DMA description in DT if the device can be assumed
> to be happy with the defaults. Anything else should be using
> "dma-ranges", "dma-coherent", etc. to describe non-default integration

heh, guilty as charged. I never noticed we had dma-ranges or
dma-coherent.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160902/777330c0/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 11:55                                           ` Robin Murphy
@ 2016-09-02 13:10                                             ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 13:10 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Robin Murphy, Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman

On Friday, September 2, 2016 12:55:33 PM CEST Robin Murphy wrote:
> 
> Huh? There's only no DMA description in DT if the device can be assumed
> to be happy with the defaults. Anything else should be using
> "dma-ranges", "dma-coherent", etc. to describe non-default integration
> aspects. For devices with an inherent fixed addressing capability !=32
> bits, then it's down to the driver to call dma_set_mask() appropriately
> to override the default 32-bit mask (which is not unique to OF-probed
> devices either).

The iommu configuration would be the main other one worth mentioning.

Note that there is a known bug with dma_set_mask(), which always succeeds
at the moment, even if the dma-ranges limit the possible addresses
in a way that should fail.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 13:10                                             ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 13:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, September 2, 2016 12:55:33 PM CEST Robin Murphy wrote:
> 
> Huh? There's only no DMA description in DT if the device can be assumed
> to be happy with the defaults. Anything else should be using
> "dma-ranges", "dma-coherent", etc. to describe non-default integration
> aspects. For devices with an inherent fixed addressing capability !=32
> bits, then it's down to the driver to call dma_set_mask() appropriately
> to override the default 32-bit mask (which is not unique to OF-probed
> devices either).

The iommu configuration would be the main other one worth mentioning.

Note that there is a known bug with dma_set_mask(), which always succeeds
at the moment, even if the dma-ranges limit the possible addresses
in a way that should fail.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 11:08                                           ` Felipe Balbi
@ 2016-09-02 14:11                                             ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 14:11 UTC (permalink / raw)
  To: Russell King - ARM Linux, Arnd Bergmann
  Cc: Leo Li, Grygorii Strashko, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel, Stuart Yoder,
	Scott Wood


Hi,

Felipe Balbi <balbi@kernel.org> writes:
> Hi,
>
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>> > 
>>> > Hi Felipe and Arnd,
>>> > 
>>> > It has been a while since the last response to this discussion, but we
>>> > haven't reached an agreement yet!  Can we get to a conclusion on if it
>>> > is valid to create child platform device for abstraction purpose?  If
>>> > yes, can this child device do DMA by itself?
>>> 
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>>
>> That's absolutely right.  Consider the USB model - only the USB host
>> controller can perform DMA, not the USB devices themselves.  All DMA
>> mappings need to be mapped using the USB host controller device struct
>> not the USB device struct.
>>
>> The same _should_ be true everywhere else: the struct device representing
>> the device performing DMA must be the one used to map the transfer.
>
> How do we fix dwc3 in dual-role, then?
>
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
>
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?

another thing to consider is that dwc3 only works on omap because DT
defaults to 32-bit DMA mask for anything described in DT that doesn't
provide dma-ranges. Isn't that somewhat odd as well?

Based on your reply, Russell, dwc3-omap should be the DMA device, but
dwc3 works just as well because of the whole 32-bit default.

-- 
balbi

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 14:11                                             ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-02 14:11 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Felipe Balbi <balbi@kernel.org> writes:
> Hi,
>
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>> > 
>>> > Hi Felipe and Arnd,
>>> > 
>>> > It has been a while since the last response to this discussion, but we
>>> > haven't reached an agreement yet!  Can we get to a conclusion on if it
>>> > is valid to create child platform device for abstraction purpose?  If
>>> > yes, can this child device do DMA by itself?
>>> 
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>>
>> That's absolutely right.  Consider the USB model - only the USB host
>> controller can perform DMA, not the USB devices themselves.  All DMA
>> mappings need to be mapped using the USB host controller device struct
>> not the USB device struct.
>>
>> The same _should_ be true everywhere else: the struct device representing
>> the device performing DMA must be the one used to map the transfer.
>
> How do we fix dwc3 in dual-role, then?
>
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
>
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?

another thing to consider is that dwc3 only works on omap because DT
defaults to 32-bit DMA mask for anything described in DT that doesn't
provide dma-ranges. Isn't that somewhat odd as well?

Based on your reply, Russell, dwc3-omap should be the DMA device, but
dwc3 works just as well because of the whole 32-bit default.

-- 
balbi

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 11:08                                           ` Felipe Balbi
@ 2016-09-02 14:21                                             ` Alan Stern
  -1 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-09-02 14:21 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Russell King - ARM Linux, Arnd Bergmann, Leo Li,
	Grygorii Strashko, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, lkml, David Fisher, Thang Q. Nguyen,
	Greg Kroah-Hartman, linux-arm-kernel, Stuart Yoder, Scott Wood

On Fri, 2 Sep 2016, Felipe Balbi wrote:

> Hi,
> 
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> >> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> >> > 
> >> > Hi Felipe and Arnd,
> >> > 
> >> > It has been a while since the last response to this discussion, but we
> >> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> >> > is valid to create child platform device for abstraction purpose?  If
> >> > yes, can this child device do DMA by itself?
> >> 
> >> I'd say it's no problem for a driver to create child devices in order
> >> to represent different aspects of a device, but you should not rely on
> >> those devices working when used with the dma-mapping interfaces.
> >
> > That's absolutely right.  Consider the USB model - only the USB host
> > controller can perform DMA, not the USB devices themselves.  All DMA
> > mappings need to be mapped using the USB host controller device struct
> > not the USB device struct.
> >
> > The same _should_ be true everywhere else: the struct device representing
> > the device performing DMA must be the one used to map the transfer.
> 
> How do we fix dwc3 in dual-role, then?
> 
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
> 
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?

In theory, you can store a flag somewhere in the platform device,
something that would tell xhci-hcd that it has to use the parent's
parent for DMA purposes.

I know it would be somewhat of a hack, but ought to work.

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 14:21                                             ` Alan Stern
  0 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-09-02 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2 Sep 2016, Felipe Balbi wrote:

> Hi,
> 
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> >> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> >> > 
> >> > Hi Felipe and Arnd,
> >> > 
> >> > It has been a while since the last response to this discussion, but we
> >> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> >> > is valid to create child platform device for abstraction purpose?  If
> >> > yes, can this child device do DMA by itself?
> >> 
> >> I'd say it's no problem for a driver to create child devices in order
> >> to represent different aspects of a device, but you should not rely on
> >> those devices working when used with the dma-mapping interfaces.
> >
> > That's absolutely right.  Consider the USB model - only the USB host
> > controller can perform DMA, not the USB devices themselves.  All DMA
> > mappings need to be mapped using the USB host controller device struct
> > not the USB device struct.
> >
> > The same _should_ be true everywhere else: the struct device representing
> > the device performing DMA must be the one used to map the transfer.
> 
> How do we fix dwc3 in dual-role, then?
> 
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
> 
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?

In theory, you can store a flag somewhere in the platform device,
something that would tell xhci-hcd that it has to use the parent's
parent for DMA purposes.

I know it would be somewhat of a hack, but ought to work.

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 14:21                                             ` Alan Stern
@ 2016-09-02 15:51                                               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Alan Stern, Felipe Balbi, Grygorii Strashko, Stuart Yoder,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	Russell King - ARM Linux, lkml, Scott Wood, David Fisher,
	Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman

On Friday, September 2, 2016 10:21:23 AM CEST Alan Stern wrote:
> On Fri, 2 Sep 2016, Felipe Balbi wrote:
> 
> > Hi,
> > 
> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > > On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> > >> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> > >> > 
> > >> > Hi Felipe and Arnd,
> > >> > 
> > >> > It has been a while since the last response to this discussion, but we
> > >> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> > >> > is valid to create child platform device for abstraction purpose?  If
> > >> > yes, can this child device do DMA by itself?
> > >> 
> > >> I'd say it's no problem for a driver to create child devices in order
> > >> to represent different aspects of a device, but you should not rely on
> > >> those devices working when used with the dma-mapping interfaces.
> > >
> > > That's absolutely right.  Consider the USB model - only the USB host
> > > controller can perform DMA, not the USB devices themselves.  All DMA
> > > mappings need to be mapped using the USB host controller device struct
> > > not the USB device struct.
> > >
> > > The same _should_ be true everywhere else: the struct device representing
> > > the device performing DMA must be the one used to map the transfer.
> > 
> > How do we fix dwc3 in dual-role, then?
> > 
> > Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> > and use dwc3.ko's parent device (which will be the PCI device or OF
> > device). But for host side dwc3, the problem is slightly more complex
> > because we're using xhci-plat.ko by just instantiating a xhci-platform
> > device so xhci-plat can probe.
> > 
> > xhci core has no means to know if its own device or the parent of its
> > parent should be used for DMA. Any ideas?
> 
> In theory, you can store a flag somewhere in the platform device,
> something that would tell xhci-hcd that it has to use the parent's
> parent for DMA purposes.
> 
> I know it would be somewhat of a hack, but ought to work.

Speaking of that flag, I suppose we need the same logic to know where
to look for USB devices attached to a dwc3 host when we need to describe
them in DT. By default we look for child device nodes under the
node of the HCD device node, but that would be wrong here too.

	Arnd 

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 15:51                                               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-02 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, September 2, 2016 10:21:23 AM CEST Alan Stern wrote:
> On Fri, 2 Sep 2016, Felipe Balbi wrote:
> 
> > Hi,
> > 
> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > > On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
> > >> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
> > >> > 
> > >> > Hi Felipe and Arnd,
> > >> > 
> > >> > It has been a while since the last response to this discussion, but we
> > >> > haven't reached an agreement yet!  Can we get to a conclusion on if it
> > >> > is valid to create child platform device for abstraction purpose?  If
> > >> > yes, can this child device do DMA by itself?
> > >> 
> > >> I'd say it's no problem for a driver to create child devices in order
> > >> to represent different aspects of a device, but you should not rely on
> > >> those devices working when used with the dma-mapping interfaces.
> > >
> > > That's absolutely right.  Consider the USB model - only the USB host
> > > controller can perform DMA, not the USB devices themselves.  All DMA
> > > mappings need to be mapped using the USB host controller device struct
> > > not the USB device struct.
> > >
> > > The same _should_ be true everywhere else: the struct device representing
> > > the device performing DMA must be the one used to map the transfer.
> > 
> > How do we fix dwc3 in dual-role, then?
> > 
> > Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> > and use dwc3.ko's parent device (which will be the PCI device or OF
> > device). But for host side dwc3, the problem is slightly more complex
> > because we're using xhci-plat.ko by just instantiating a xhci-platform
> > device so xhci-plat can probe.
> > 
> > xhci core has no means to know if its own device or the parent of its
> > parent should be used for DMA. Any ideas?
> 
> In theory, you can store a flag somewhere in the platform device,
> something that would tell xhci-hcd that it has to use the parent's
> parent for DMA purposes.
> 
> I know it would be somewhat of a hack, but ought to work.

Speaking of that flag, I suppose we need the same logic to know where
to look for USB devices attached to a dwc3 host when we need to describe
them in DT. By default we look for child device nodes under the
node of the HCD device node, but that would be wrong here too.

	Arnd 

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 11:08                                           ` Felipe Balbi
@ 2016-09-02 16:23                                             ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-02 16:23 UTC (permalink / raw)
  To: Felipe Balbi, Russell King - ARM Linux, Arnd Bergmann
  Cc: Leo Li, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, lkml, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel, Stuart Yoder, Scott Wood

On 09/02/2016 02:08 PM, Felipe Balbi wrote:
> 
> Hi,
> 
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>>
>>>> Hi Felipe and Arnd,
>>>>
>>>> It has been a while since the last response to this discussion, but we
>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>> is valid to create child platform device for abstraction purpose?  If
>>>> yes, can this child device do DMA by itself?
>>>
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>>
>> That's absolutely right.  Consider the USB model - only the USB host
>> controller can perform DMA, not the USB devices themselves.  All DMA
>> mappings need to be mapped using the USB host controller device struct
>> not the USB device struct.
>>
>> The same _should_ be true everywhere else: the struct device representing
>> the device performing DMA must be the one used to map the transfer.
> 
> How do we fix dwc3 in dual-role, then?
> 
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
> 
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?
> 

Wouldn't be possible to use dma_mask for such purposes?
Like, case 1:
 dwc3-omap (dma_mask=X) -> dwc3 (dma_mask = NULL) -> xhci-plat (NULL)
and then it might be possible to find proper parent by traversing DD
hierarchy.

or :
dwc3 (dma_mask = X) -> xhci-plat (NULL)

or :
xhci-plat (dma_mask = X)

of course, it might be needed to skip DMA configuration for devices
which parents have been configured for dma already (easy for xhci-plat,
but can be not easy for dwc3).

just thinking..

Also, I'd like to note that problem become more complex when scsi layer is used
on top USB ;(

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 16:23                                             ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-02 16:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/02/2016 02:08 PM, Felipe Balbi wrote:
> 
> Hi,
> 
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>>
>>>> Hi Felipe and Arnd,
>>>>
>>>> It has been a while since the last response to this discussion, but we
>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>> is valid to create child platform device for abstraction purpose?  If
>>>> yes, can this child device do DMA by itself?
>>>
>>> I'd say it's no problem for a driver to create child devices in order
>>> to represent different aspects of a device, but you should not rely on
>>> those devices working when used with the dma-mapping interfaces.
>>
>> That's absolutely right.  Consider the USB model - only the USB host
>> controller can perform DMA, not the USB devices themselves.  All DMA
>> mappings need to be mapped using the USB host controller device struct
>> not the USB device struct.
>>
>> The same _should_ be true everywhere else: the struct device representing
>> the device performing DMA must be the one used to map the transfer.
> 
> How do we fix dwc3 in dual-role, then?
> 
> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
> and use dwc3.ko's parent device (which will be the PCI device or OF
> device). But for host side dwc3, the problem is slightly more complex
> because we're using xhci-plat.ko by just instantiating a xhci-platform
> device so xhci-plat can probe.
> 
> xhci core has no means to know if its own device or the parent of its
> parent should be used for DMA. Any ideas?
> 

Wouldn't be possible to use dma_mask for such purposes?
Like, case 1:
 dwc3-omap (dma_mask=X) -> dwc3 (dma_mask = NULL) -> xhci-plat (NULL)
and then it might be possible to find proper parent by traversing DD
hierarchy.

or :
dwc3 (dma_mask = X) -> xhci-plat (NULL)

or :
xhci-plat (dma_mask = X)

of course, it might be needed to skip DMA configuration for devices
which parents have been configured for dma already (easy for xhci-plat,
but can be not easy for dwc3).

just thinking..

Also, I'd like to note that problem become more complex when scsi layer is used
on top USB ;(

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 10:43                                       ` Arnd Bergmann
@ 2016-09-02 22:16                                         ` Leo Li
  -1 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-09-02 22:16 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Russell King - ARM Linux, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

On Fri, Sep 2, 2016 at 5:43 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>
>> Hi Felipe and Arnd,
>>
>> It has been a while since the last response to this discussion, but we
>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>> is valid to create child platform device for abstraction purpose?  If
>> yes, can this child device do DMA by itself?
>
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.
>
> This used to be simpler back when we could configure the kernel for
> only one SoC platform at a time, and the platforms could provide their
> own overrides for the dma-mapping interfaces. These days, we rely on
> firmware or bootloader to describe various aspects of how DMA is done,
> so you can't assume that passing a device without an of_node pointer
> or ACPI data into those functions will do the right thing.

Can we use the firmware or bootloader information to provide the
default dma-mapping attributes for devices that doesn't have an
of_node pointer or ACPI data?  This will at least restore what we had
previously provided .  I'm concerned that changing all the drivers
that are creating child device will be a big effort.  Like I mentioned
in another thread, there are many instances of platform_device_add()
under the drivers/ directory.

- Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-02 22:16                                         ` Leo Li
  0 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-09-02 22:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 2, 2016 at 5:43 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>
>> Hi Felipe and Arnd,
>>
>> It has been a while since the last response to this discussion, but we
>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>> is valid to create child platform device for abstraction purpose?  If
>> yes, can this child device do DMA by itself?
>
> I'd say it's no problem for a driver to create child devices in order
> to represent different aspects of a device, but you should not rely on
> those devices working when used with the dma-mapping interfaces.
>
> This used to be simpler back when we could configure the kernel for
> only one SoC platform at a time, and the platforms could provide their
> own overrides for the dma-mapping interfaces. These days, we rely on
> firmware or bootloader to describe various aspects of how DMA is done,
> so you can't assume that passing a device without an of_node pointer
> or ACPI data into those functions will do the right thing.

Can we use the firmware or bootloader information to provide the
default dma-mapping attributes for devices that doesn't have an
of_node pointer or ACPI data?  This will at least restore what we had
previously provided .  I'm concerned that changing all the drivers
that are creating child device will be a big effort.  Like I mentioned
in another thread, there are many instances of platform_device_add()
under the drivers/ directory.

- Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 22:16                                         ` Leo Li
@ 2016-09-05 15:39                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-05 15:39 UTC (permalink / raw)
  To: Leo Li
  Cc: Felipe Balbi, Russell King - ARM Linux, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Stuart Yoder, Scott Wood

On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> 
> Can we use the firmware or bootloader information to provide the
> default dma-mapping attributes for devices that doesn't have an
> of_node pointer or ACPI data?  This will at least restore what we had
> previously provided .  I'm concerned that changing all the drivers
> that are creating child device will be a big effort.  Like I mentioned
> in another thread, there are many instances of platform_device_add()
> under the drivers/ directory.

Fortunately, there are not too many drivers that call platform_device_add
*and* try to set up a dma mask for the child device:

git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'

drivers/base/platform.c
drivers/bcma/main.c
drivers/eisa/virtual_root.c
drivers/mfd/mfd-core.c
drivers/mfd/omap-usb-host.c
drivers/misc/mic/card/mic_x100.c
drivers/platform/goldfish/pdev_bus.c
drivers/ssb/main.c
drivers/usb/chipidea/core.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/host.c
drivers/usb/gadget/udc/bdc/bdc_pci.c
drivers/usb/host/bcma-hcd.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/ssb-hcd.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/ux500.c

Most of these are probably never used with any nonstandard
DMA settings (IOMMU, cache coherency, offset, ...).

One thing we could possibly do is to go through these and
replace the hardcoded dma mask setup with of_dma_configure()
in all cases in which we actually use DT for probing, which
should cover the interesting cases.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-05 15:39                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-05 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> 
> Can we use the firmware or bootloader information to provide the
> default dma-mapping attributes for devices that doesn't have an
> of_node pointer or ACPI data?  This will at least restore what we had
> previously provided .  I'm concerned that changing all the drivers
> that are creating child device will be a big effort.  Like I mentioned
> in another thread, there are many instances of platform_device_add()
> under the drivers/ directory.

Fortunately, there are not too many drivers that call platform_device_add
*and* try to set up a dma mask for the child device:

git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'

drivers/base/platform.c
drivers/bcma/main.c
drivers/eisa/virtual_root.c
drivers/mfd/mfd-core.c
drivers/mfd/omap-usb-host.c
drivers/misc/mic/card/mic_x100.c
drivers/platform/goldfish/pdev_bus.c
drivers/ssb/main.c
drivers/usb/chipidea/core.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/host.c
drivers/usb/gadget/udc/bdc/bdc_pci.c
drivers/usb/host/bcma-hcd.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/ssb-hcd.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/ux500.c

Most of these are probably never used with any nonstandard
DMA settings (IOMMU, cache coherency, offset, ...).

One thing we could possibly do is to go through these and
replace the hardcoded dma mask setup with of_dma_configure()
in all cases in which we actually use DT for probing, which
should cover the interesting cases.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-05 15:39                                           ` Arnd Bergmann
@ 2016-09-06  6:35                                             ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-06  6:35 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> > 
> > Can we use the firmware or bootloader information to provide the
> > default dma-mapping attributes for devices that doesn't have an
> > of_node pointer or ACPI data?  This will at least restore what we had
> > previously provided .  I'm concerned that changing all the drivers
> > that are creating child device will be a big effort.  Like I mentioned
> > in another thread, there are many instances of platform_device_add()
> > under the drivers/ directory.
> 
> Fortunately, there are not too many drivers that call platform_device_add
> *and* try to set up a dma mask for the child device:
> 
> git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'
> 
> drivers/base/platform.c
> drivers/bcma/main.c
> drivers/eisa/virtual_root.c
> drivers/mfd/mfd-core.c
> drivers/mfd/omap-usb-host.c
> drivers/misc/mic/card/mic_x100.c
> drivers/platform/goldfish/pdev_bus.c
> drivers/ssb/main.c
> drivers/usb/chipidea/core.c
> drivers/usb/dwc3/dwc3-exynos.c
> drivers/usb/dwc3/host.c
> drivers/usb/gadget/udc/bdc/bdc_pci.c
> drivers/usb/host/bcma-hcd.c
> drivers/usb/host/fsl-mph-dr-of.c
> drivers/usb/host/ssb-hcd.c
> drivers/usb/misc/ftdi-elan.c
> drivers/usb/musb/blackfin.c
> drivers/usb/musb/musb_dsps.c
> drivers/usb/musb/omap2430.c
> drivers/usb/musb/ux500.c
> 
> Most of these are probably never used with any nonstandard
> DMA settings (IOMMU, cache coherency, offset, ...).
> 
> One thing we could possibly do is to go through these and
> replace the hardcoded dma mask setup with of_dma_configure()
> in all cases in which we actually use DT for probing, which
> should cover the interesting cases.
> 

One case I am going to work is to let USB chipidea driver support iommu,
the chipidea core device is no of_node, and created by
platform_add_device on the runtime. Using of_dma_configure with parent
of_node is a solution from my point, like [1].

https://lkml.org/lkml/2016/2/22/7

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06  6:35                                             ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-06  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> > 
> > Can we use the firmware or bootloader information to provide the
> > default dma-mapping attributes for devices that doesn't have an
> > of_node pointer or ACPI data?  This will at least restore what we had
> > previously provided .  I'm concerned that changing all the drivers
> > that are creating child device will be a big effort.  Like I mentioned
> > in another thread, there are many instances of platform_device_add()
> > under the drivers/ directory.
> 
> Fortunately, there are not too many drivers that call platform_device_add
> *and* try to set up a dma mask for the child device:
> 
> git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'
> 
> drivers/base/platform.c
> drivers/bcma/main.c
> drivers/eisa/virtual_root.c
> drivers/mfd/mfd-core.c
> drivers/mfd/omap-usb-host.c
> drivers/misc/mic/card/mic_x100.c
> drivers/platform/goldfish/pdev_bus.c
> drivers/ssb/main.c
> drivers/usb/chipidea/core.c
> drivers/usb/dwc3/dwc3-exynos.c
> drivers/usb/dwc3/host.c
> drivers/usb/gadget/udc/bdc/bdc_pci.c
> drivers/usb/host/bcma-hcd.c
> drivers/usb/host/fsl-mph-dr-of.c
> drivers/usb/host/ssb-hcd.c
> drivers/usb/misc/ftdi-elan.c
> drivers/usb/musb/blackfin.c
> drivers/usb/musb/musb_dsps.c
> drivers/usb/musb/omap2430.c
> drivers/usb/musb/ux500.c
> 
> Most of these are probably never used with any nonstandard
> DMA settings (IOMMU, cache coherency, offset, ...).
> 
> One thing we could possibly do is to go through these and
> replace the hardcoded dma mask setup with of_dma_configure()
> in all cases in which we actually use DT for probing, which
> should cover the interesting cases.
> 

One case I am going to work is to let USB chipidea driver support iommu,
the chipidea core device is no of_node, and created by
platform_add_device on the runtime. Using of_dma_configure with parent
of_node is a solution from my point, like [1].

https://lkml.org/lkml/2016/2/22/7

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06  6:35                                             ` Peter Chen
@ 2016-09-06  6:40                                               ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-06  6:40 UTC (permalink / raw)
  To: Peter Chen, Arnd Bergmann
  Cc: Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2461 bytes --]


Hi,

Peter Chen <hzpeterchen@gmail.com> writes:
> On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
>> On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
>> > 
>> > Can we use the firmware or bootloader information to provide the
>> > default dma-mapping attributes for devices that doesn't have an
>> > of_node pointer or ACPI data?  This will at least restore what we had
>> > previously provided .  I'm concerned that changing all the drivers
>> > that are creating child device will be a big effort.  Like I mentioned
>> > in another thread, there are many instances of platform_device_add()
>> > under the drivers/ directory.
>> 
>> Fortunately, there are not too many drivers that call platform_device_add
>> *and* try to set up a dma mask for the child device:
>> 
>> git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'
>> 
>> drivers/base/platform.c
>> drivers/bcma/main.c
>> drivers/eisa/virtual_root.c
>> drivers/mfd/mfd-core.c
>> drivers/mfd/omap-usb-host.c
>> drivers/misc/mic/card/mic_x100.c
>> drivers/platform/goldfish/pdev_bus.c
>> drivers/ssb/main.c
>> drivers/usb/chipidea/core.c
>> drivers/usb/dwc3/dwc3-exynos.c
>> drivers/usb/dwc3/host.c
>> drivers/usb/gadget/udc/bdc/bdc_pci.c
>> drivers/usb/host/bcma-hcd.c
>> drivers/usb/host/fsl-mph-dr-of.c
>> drivers/usb/host/ssb-hcd.c
>> drivers/usb/misc/ftdi-elan.c
>> drivers/usb/musb/blackfin.c
>> drivers/usb/musb/musb_dsps.c
>> drivers/usb/musb/omap2430.c
>> drivers/usb/musb/ux500.c
>> 
>> Most of these are probably never used with any nonstandard
>> DMA settings (IOMMU, cache coherency, offset, ...).
>> 
>> One thing we could possibly do is to go through these and
>> replace the hardcoded dma mask setup with of_dma_configure()
>> in all cases in which we actually use DT for probing, which
>> should cover the interesting cases.
>> 
>
> One case I am going to work is to let USB chipidea driver support iommu,
> the chipidea core device is no of_node, and created by
> platform_add_device on the runtime. Using of_dma_configure with parent
> of_node is a solution from my point, like [1].
>
> https://lkml.org/lkml/2016/2/22/7

this only solves the problem for DT devices. Legacy devices and
PCI-based systems will still suffer from the same problem. At least for
dwc3, I will only be taking patches that solve the problem for all
users, not a subset of them.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06  6:40                                               ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-06  6:40 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Peter Chen <hzpeterchen@gmail.com> writes:
> On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
>> On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
>> > 
>> > Can we use the firmware or bootloader information to provide the
>> > default dma-mapping attributes for devices that doesn't have an
>> > of_node pointer or ACPI data?  This will at least restore what we had
>> > previously provided .  I'm concerned that changing all the drivers
>> > that are creating child device will be a big effort.  Like I mentioned
>> > in another thread, there are many instances of platform_device_add()
>> > under the drivers/ directory.
>> 
>> Fortunately, there are not too many drivers that call platform_device_add
>> *and* try to set up a dma mask for the child device:
>> 
>> git grep -wl dma_mask drivers | xargs grep -wl 'platform_device_\(add\|register\)'
>> 
>> drivers/base/platform.c
>> drivers/bcma/main.c
>> drivers/eisa/virtual_root.c
>> drivers/mfd/mfd-core.c
>> drivers/mfd/omap-usb-host.c
>> drivers/misc/mic/card/mic_x100.c
>> drivers/platform/goldfish/pdev_bus.c
>> drivers/ssb/main.c
>> drivers/usb/chipidea/core.c
>> drivers/usb/dwc3/dwc3-exynos.c
>> drivers/usb/dwc3/host.c
>> drivers/usb/gadget/udc/bdc/bdc_pci.c
>> drivers/usb/host/bcma-hcd.c
>> drivers/usb/host/fsl-mph-dr-of.c
>> drivers/usb/host/ssb-hcd.c
>> drivers/usb/misc/ftdi-elan.c
>> drivers/usb/musb/blackfin.c
>> drivers/usb/musb/musb_dsps.c
>> drivers/usb/musb/omap2430.c
>> drivers/usb/musb/ux500.c
>> 
>> Most of these are probably never used with any nonstandard
>> DMA settings (IOMMU, cache coherency, offset, ...).
>> 
>> One thing we could possibly do is to go through these and
>> replace the hardcoded dma mask setup with of_dma_configure()
>> in all cases in which we actually use DT for probing, which
>> should cover the interesting cases.
>> 
>
> One case I am going to work is to let USB chipidea driver support iommu,
> the chipidea core device is no of_node, and created by
> platform_add_device on the runtime. Using of_dma_configure with parent
> of_node is a solution from my point, like [1].
>
> https://lkml.org/lkml/2016/2/22/7

this only solves the problem for DT devices. Legacy devices and
PCI-based systems will still suffer from the same problem. At least for
dwc3, I will only be taking patches that solve the problem for all
users, not a subset of them.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160906/ccfce4b7/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06  6:35                                             ` Peter Chen
@ 2016-09-06 10:38                                               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 10:38 UTC (permalink / raw)
  To: Peter Chen
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Tuesday, September 6, 2016 2:35:29 PM CEST Peter Chen wrote:
> On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> > On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:

> > 
> > Most of these are probably never used with any nonstandard
> > DMA settings (IOMMU, cache coherency, offset, ...).
> > 
> > One thing we could possibly do is to go through these and
> > replace the hardcoded dma mask setup with of_dma_configure()
> > in all cases in which we actually use DT for probing, which
> > should cover the interesting cases.
> > 
> 
> One case I am going to work is to let USB chipidea driver support iommu,
> the chipidea core device is no of_node, and created by
> platform_add_device on the runtime. Using of_dma_configure with parent
> of_node is a solution from my point, like [1].
> 
> https://lkml.org/lkml/2016/2/22/7

Right, that should make it work with iommu as well. However, it does
not solve the other issue I mentioned above, with boards that have
USB devices hardwired to a chipidea host controller that need
configuration from DT. For that, we still need to come up with another
way to associate the DT hierarchy in the host bridge node with
the Linux platform_device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06 10:38                                               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, September 6, 2016 2:35:29 PM CEST Peter Chen wrote:
> On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> > On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:

> > 
> > Most of these are probably never used with any nonstandard
> > DMA settings (IOMMU, cache coherency, offset, ...).
> > 
> > One thing we could possibly do is to go through these and
> > replace the hardcoded dma mask setup with of_dma_configure()
> > in all cases in which we actually use DT for probing, which
> > should cover the interesting cases.
> > 
> 
> One case I am going to work is to let USB chipidea driver support iommu,
> the chipidea core device is no of_node, and created by
> platform_add_device on the runtime. Using of_dma_configure with parent
> of_node is a solution from my point, like [1].
> 
> https://lkml.org/lkml/2016/2/22/7

Right, that should make it work with iommu as well. However, it does
not solve the other issue I mentioned above, with boards that have
USB devices hardwired to a chipidea host controller that need
configuration from DT. For that, we still need to come up with another
way to associate the DT hierarchy in the host bridge node with
the Linux platform_device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06  6:40                                               ` Felipe Balbi
@ 2016-09-06 10:46                                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 10:46 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> 
> this only solves the problem for DT devices. Legacy devices and
> PCI-based systems will still suffer from the same problem. At least for
> dwc3, I will only be taking patches that solve the problem for all
> users, not a subset of them.

I don't think legacy devices are a worry, because they wouldn't
have this problem. For the PCI case, you are right that it cannot
work, in particular for machines that have complex IOMMU setup.

Some architectures (at least arm64 and sparc) check the bus_type of
a device in order to find the correct set of dma_map_ops for that
device, so there is no real way to handle this as long as you
pass a platform_device into an API that expects a pci_device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06 10:46                                                 ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> 
> this only solves the problem for DT devices. Legacy devices and
> PCI-based systems will still suffer from the same problem. At least for
> dwc3, I will only be taking patches that solve the problem for all
> users, not a subset of them.

I don't think legacy devices are a worry, because they wouldn't
have this problem. For the PCI case, you are right that it cannot
work, in particular for machines that have complex IOMMU setup.

Some architectures (at least arm64 and sparc) check the bus_type of
a device in order to find the correct set of dma_map_ops for that
device, so there is no real way to handle this as long as you
pass a platform_device into an API that expects a pci_device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06 10:46                                                 ` Arnd Bergmann
@ 2016-09-06 10:50                                                   ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-06 10:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
>> 
>> this only solves the problem for DT devices. Legacy devices and
>> PCI-based systems will still suffer from the same problem. At least for
>> dwc3, I will only be taking patches that solve the problem for all
>> users, not a subset of them.
>
> I don't think legacy devices are a worry, because they wouldn't
> have this problem. For the PCI case, you are right that it cannot
> work, in particular for machines that have complex IOMMU setup.
>
> Some architectures (at least arm64 and sparc) check the bus_type of
> a device in order to find the correct set of dma_map_ops for that
> device, so there is no real way to handle this as long as you
> pass a platform_device into an API that expects a pci_device.

Then I guess we're left with adding a "struct device *dma_dev" to struct
dwc3 and trying to figure out if we should use parent or self. Does
anybody see any problems with that?

Note, we would NOT be passing device pointers are platform_data, we
would have dwc3.ko figure out if it should use self or its parent device
for dma.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06 10:50                                                   ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-06 10:50 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
>> 
>> this only solves the problem for DT devices. Legacy devices and
>> PCI-based systems will still suffer from the same problem. At least for
>> dwc3, I will only be taking patches that solve the problem for all
>> users, not a subset of them.
>
> I don't think legacy devices are a worry, because they wouldn't
> have this problem. For the PCI case, you are right that it cannot
> work, in particular for machines that have complex IOMMU setup.
>
> Some architectures (at least arm64 and sparc) check the bus_type of
> a device in order to find the correct set of dma_map_ops for that
> device, so there is no real way to handle this as long as you
> pass a platform_device into an API that expects a pci_device.

Then I guess we're left with adding a "struct device *dma_dev" to struct
dwc3 and trying to figure out if we should use parent or self. Does
anybody see any problems with that?

Note, we would NOT be passing device pointers are platform_data, we
would have dwc3.ko figure out if it should use self or its parent device
for dma.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160906/84e28d17/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06 10:50                                                   ` Felipe Balbi
@ 2016-09-06 13:27                                                     ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 13:27 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> >> 
> >> this only solves the problem for DT devices. Legacy devices and
> >> PCI-based systems will still suffer from the same problem. At least for
> >> dwc3, I will only be taking patches that solve the problem for all
> >> users, not a subset of them.
> >
> > I don't think legacy devices are a worry, because they wouldn't
> > have this problem. For the PCI case, you are right that it cannot
> > work, in particular for machines that have complex IOMMU setup.
> >
> > Some architectures (at least arm64 and sparc) check the bus_type of
> > a device in order to find the correct set of dma_map_ops for that
> > device, so there is no real way to handle this as long as you
> > pass a platform_device into an API that expects a pci_device.
> 
> Then I guess we're left with adding a "struct device *dma_dev" to struct
> dwc3 and trying to figure out if we should use parent or self. Does
> anybody see any problems with that?

I think we actually need the device pointer in the usb_hcd structure,
so it can be passed in these API calls from the USB core

drivers/usb/core/buffer.c:      return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
drivers/usb/core/buffer.c:      dma_free_coherent(hcd->self.controller, size, addr, dma);
drivers/usb/core/buffer.c:          (!hcd->self.controller->dma_mask &&
drivers/usb/core/buffer.c:              hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
drivers/usb/core/hcd.c:                 urb->setup_dma = dma_map_single(
drivers/usb/core/hcd.c:                 if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/hcd.c:                         n = dma_map_sg(
drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_page(
drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_single(
drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/usb.c:         urb->transfer_dma = dma_map_single(controller,
drivers/usb/core/usb.c: return dma_map_sg(controller, sg, nents,
drivers/usb/core/usb.c:         dma_sync_single_for_cpu(controller,
drivers/usb/core/usb.c:                 dma_sync_single_for_cpu(controller,
drivers/usb/core/usb.c: dma_sync_sg_for_cpu(controller, sg, n_hw_ents,

as these are all called on behalf of the host controller node.
Looking for more instances of hcd->self.controller, I find this
instance:

drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");

I'm unsure which device pointer we want here, but I suspect this also
needs to be the one that has the device node in order to make the lookup
of the phy structure by device node work right. Can you clarify how
this works today?

We probably also need to add the of_node of the host controller device
to struct usb_hcd in order to make usb_of_get_child_node() work
in the case where the hcd itself is not device that is listed
in DT. It might be a good idea to use 'struct fwnode_handle' for that,
so we can in the future also allow ACPI platforms to specify 

> Note, we would NOT be passing device pointers are platform_data, we
> would have dwc3.ko figure out if it should use self or its parent device
> for dma.

Ok, sounds good.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-06 13:27                                                     ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-06 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> >> 
> >> this only solves the problem for DT devices. Legacy devices and
> >> PCI-based systems will still suffer from the same problem. At least for
> >> dwc3, I will only be taking patches that solve the problem for all
> >> users, not a subset of them.
> >
> > I don't think legacy devices are a worry, because they wouldn't
> > have this problem. For the PCI case, you are right that it cannot
> > work, in particular for machines that have complex IOMMU setup.
> >
> > Some architectures (at least arm64 and sparc) check the bus_type of
> > a device in order to find the correct set of dma_map_ops for that
> > device, so there is no real way to handle this as long as you
> > pass a platform_device into an API that expects a pci_device.
> 
> Then I guess we're left with adding a "struct device *dma_dev" to struct
> dwc3 and trying to figure out if we should use parent or self. Does
> anybody see any problems with that?

I think we actually need the device pointer in the usb_hcd structure,
so it can be passed in these API calls from the USB core

drivers/usb/core/buffer.c:      return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
drivers/usb/core/buffer.c:      dma_free_coherent(hcd->self.controller, size, addr, dma);
drivers/usb/core/buffer.c:          (!hcd->self.controller->dma_mask &&
drivers/usb/core/buffer.c:              hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
drivers/usb/core/hcd.c:                 urb->setup_dma = dma_map_single(
drivers/usb/core/hcd.c:                 if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/hcd.c:                         n = dma_map_sg(
drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_page(
drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_single(
drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
drivers/usb/core/usb.c:         urb->transfer_dma = dma_map_single(controller,
drivers/usb/core/usb.c: return dma_map_sg(controller, sg, nents,
drivers/usb/core/usb.c:         dma_sync_single_for_cpu(controller,
drivers/usb/core/usb.c:                 dma_sync_single_for_cpu(controller,
drivers/usb/core/usb.c: dma_sync_sg_for_cpu(controller, sg, n_hw_ents,

as these are all called on behalf of the host controller node.
Looking for more instances of hcd->self.controller, I find this
instance:

drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");

I'm unsure which device pointer we want here, but I suspect this also
needs to be the one that has the device node in order to make the lookup
of the phy structure by device node work right. Can you clarify how
this works today?

We probably also need to add the of_node of the host controller device
to struct usb_hcd in order to make usb_of_get_child_node() work
in the case where the hcd itself is not device that is listed
in DT. It might be a good idea to use 'struct fwnode_handle' for that,
so we can in the future also allow ACPI platforms to specify 

> Note, we would NOT be passing device pointers are platform_data, we
> would have dwc3.ko figure out if it should use self or its parent device
> for dma.

Ok, sounds good.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06 10:38                                               ` Arnd Bergmann
@ 2016-09-07  6:33                                                 ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  6:33 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Tue, Sep 06, 2016 at 12:38:29PM +0200, Arnd Bergmann wrote:
> On Tuesday, September 6, 2016 2:35:29 PM CEST Peter Chen wrote:
> > On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> > > On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> 
> > > 
> > > Most of these are probably never used with any nonstandard
> > > DMA settings (IOMMU, cache coherency, offset, ...).
> > > 
> > > One thing we could possibly do is to go through these and
> > > replace the hardcoded dma mask setup with of_dma_configure()
> > > in all cases in which we actually use DT for probing, which
> > > should cover the interesting cases.
> > > 
> > 
> > One case I am going to work is to let USB chipidea driver support iommu,
> > the chipidea core device is no of_node, and created by
> > platform_add_device on the runtime. Using of_dma_configure with parent
> > of_node is a solution from my point, like [1].
> > 
> > https://lkml.org/lkml/2016/2/22/7
> 
> Right, that should make it work with iommu as well. However, it does
> not solve the other issue I mentioned above, with boards that have
> USB devices hardwired to a chipidea host controller that need
> configuration from DT. For that, we still need to come up with another
> way to associate the DT hierarchy in the host bridge node with
> the Linux platform_device.
> 

Why? The DMA configuration is for host controller, not for USB device.
No matter there is hardwired or hotplug devices, the DMA configuration
for host controller are both inherited from glue layer platform devices,
current implementation is at function ci_hdrc_add_device,
drivers/usb/chipidea/core.c.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  6:33                                                 ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  6:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2016 at 12:38:29PM +0200, Arnd Bergmann wrote:
> On Tuesday, September 6, 2016 2:35:29 PM CEST Peter Chen wrote:
> > On Mon, Sep 05, 2016 at 05:39:27PM +0200, Arnd Bergmann wrote:
> > > On Friday, September 2, 2016 5:16:31 PM CEST Leo Li wrote:
> 
> > > 
> > > Most of these are probably never used with any nonstandard
> > > DMA settings (IOMMU, cache coherency, offset, ...).
> > > 
> > > One thing we could possibly do is to go through these and
> > > replace the hardcoded dma mask setup with of_dma_configure()
> > > in all cases in which we actually use DT for probing, which
> > > should cover the interesting cases.
> > > 
> > 
> > One case I am going to work is to let USB chipidea driver support iommu,
> > the chipidea core device is no of_node, and created by
> > platform_add_device on the runtime. Using of_dma_configure with parent
> > of_node is a solution from my point, like [1].
> > 
> > https://lkml.org/lkml/2016/2/22/7
> 
> Right, that should make it work with iommu as well. However, it does
> not solve the other issue I mentioned above, with boards that have
> USB devices hardwired to a chipidea host controller that need
> configuration from DT. For that, we still need to come up with another
> way to associate the DT hierarchy in the host bridge node with
> the Linux platform_device.
> 

Why? The DMA configuration is for host controller, not for USB device.
No matter there is hardwired or hotplug devices, the DMA configuration
for host controller are both inherited from glue layer platform devices,
current implementation is at function ci_hdrc_add_device,
drivers/usb/chipidea/core.c.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06 13:27                                                     ` Arnd Bergmann
@ 2016-09-07  6:51                                                       ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07  6:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2026 bytes --]

Arnd Bergmann <arnd@arndb.de> writes:

> On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
>> Hi,
>> 
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
>> >> 
>> >> this only solves the problem for DT devices. Legacy devices and
>> >> PCI-based systems will still suffer from the same problem. At least for
>> >> dwc3, I will only be taking patches that solve the problem for all
>> >> users, not a subset of them.
>> >
>> > I don't think legacy devices are a worry, because they wouldn't
>> > have this problem. For the PCI case, you are right that it cannot
>> > work, in particular for machines that have complex IOMMU setup.
>> >
>> > Some architectures (at least arm64 and sparc) check the bus_type of
>> > a device in order to find the correct set of dma_map_ops for that
>> > device, so there is no real way to handle this as long as you
>> > pass a platform_device into an API that expects a pci_device.
>> 
>> Then I guess we're left with adding a "struct device *dma_dev" to struct
>> dwc3 and trying to figure out if we should use parent or self. Does
>> anybody see any problems with that?
>
> I think we actually need the device pointer in the usb_hcd structure,
> so it can be passed in these API calls from the USB core

that's for host side. I'm concerned about peripheral side

> as these are all called on behalf of the host controller node.
> Looking for more instances of hcd->self.controller, I find this
> instance:
>
> drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
> drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");
>
> I'm unsure which device pointer we want here, but I suspect this also
> needs to be the one that has the device node in order to make the lookup
> of the phy structure by device node work right. Can you clarify how
> this works today?

sounds correct to me.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  6:51                                                       ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07  6:51 UTC (permalink / raw)
  To: linux-arm-kernel

Arnd Bergmann <arnd@arndb.de> writes:

> On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
>> Hi,
>> 
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
>> >> 
>> >> this only solves the problem for DT devices. Legacy devices and
>> >> PCI-based systems will still suffer from the same problem. At least for
>> >> dwc3, I will only be taking patches that solve the problem for all
>> >> users, not a subset of them.
>> >
>> > I don't think legacy devices are a worry, because they wouldn't
>> > have this problem. For the PCI case, you are right that it cannot
>> > work, in particular for machines that have complex IOMMU setup.
>> >
>> > Some architectures (at least arm64 and sparc) check the bus_type of
>> > a device in order to find the correct set of dma_map_ops for that
>> > device, so there is no real way to handle this as long as you
>> > pass a platform_device into an API that expects a pci_device.
>> 
>> Then I guess we're left with adding a "struct device *dma_dev" to struct
>> dwc3 and trying to figure out if we should use parent or self. Does
>> anybody see any problems with that?
>
> I think we actually need the device pointer in the usb_hcd structure,
> so it can be passed in these API calls from the USB core

that's for host side. I'm concerned about peripheral side

> as these are all called on behalf of the host controller node.
> Looking for more instances of hcd->self.controller, I find this
> instance:
>
> drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
> drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");
>
> I'm unsure which device pointer we want here, but I suspect this also
> needs to be the one that has the device node in order to make the lookup
> of the phy structure by device node work right. Can you clarify how
> this works today?

sounds correct to me.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160907/751dcd92/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-02 15:51                                               ` Arnd Bergmann
@ 2016-09-07  7:17                                                 ` Roger Quadros
  -1 siblings, 0 replies; 182+ messages in thread
From: Roger Quadros @ 2016-09-07  7:17 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Alan Stern, Felipe Balbi, Grygorii Strashko, Stuart Yoder,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori,
	Russell King - ARM Linux, lkml, Scott Wood, David Fisher,
	Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman

Hi Arnd,

On 02/09/16 18:51, Arnd Bergmann wrote:
> On Friday, September 2, 2016 10:21:23 AM CEST Alan Stern wrote:
>> On Fri, 2 Sep 2016, Felipe Balbi wrote:
>>
>>> Hi,
>>>
>>> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>>>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>>>>
>>>>>> Hi Felipe and Arnd,
>>>>>>
>>>>>> It has been a while since the last response to this discussion, but we
>>>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>>>> is valid to create child platform device for abstraction purpose?  If
>>>>>> yes, can this child device do DMA by itself?
>>>>>
>>>>> I'd say it's no problem for a driver to create child devices in order
>>>>> to represent different aspects of a device, but you should not rely on
>>>>> those devices working when used with the dma-mapping interfaces.
>>>>
>>>> That's absolutely right.  Consider the USB model - only the USB host
>>>> controller can perform DMA, not the USB devices themselves.  All DMA
>>>> mappings need to be mapped using the USB host controller device struct
>>>> not the USB device struct.
>>>>
>>>> The same _should_ be true everywhere else: the struct device representing
>>>> the device performing DMA must be the one used to map the transfer.
>>>
>>> How do we fix dwc3 in dual-role, then?
>>>
>>> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
>>> and use dwc3.ko's parent device (which will be the PCI device or OF
>>> device). But for host side dwc3, the problem is slightly more complex
>>> because we're using xhci-plat.ko by just instantiating a xhci-platform
>>> device so xhci-plat can probe.
>>>
>>> xhci core has no means to know if its own device or the parent of its
>>> parent should be used for DMA. Any ideas?
>>
>> In theory, you can store a flag somewhere in the platform device,
>> something that would tell xhci-hcd that it has to use the parent's
>> parent for DMA purposes.
>>
>> I know it would be somewhat of a hack, but ought to work.
> 
> Speaking of that flag, I suppose we need the same logic to know where
> to look for USB devices attached to a dwc3 host when we need to describe
> them in DT. By default we look for child device nodes under the
> node of the HCD device node, but that would be wrong here too.

I didn't get this part. Information about USB devices attached to a USB host
is never provided in DT because they are always dynamically created via
usb_new_device(), whether they are hard-wired on the board or hot-plugged.

These USB devices inherit their DMA masks in the usb_alloc_dev() routine
whereas each interface within the USB device inherits its DMA mask in
usb_set_configuration().

There is a bug  in the USB core because of which the ISB device and interfaces
do not inherit dma_pfn_offset correctly for which I've sent a patch
https://lkml.org/lkml/2016/8/17/275

cheers,
-roger

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  7:17                                                 ` Roger Quadros
  0 siblings, 0 replies; 182+ messages in thread
From: Roger Quadros @ 2016-09-07  7:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On 02/09/16 18:51, Arnd Bergmann wrote:
> On Friday, September 2, 2016 10:21:23 AM CEST Alan Stern wrote:
>> On Fri, 2 Sep 2016, Felipe Balbi wrote:
>>
>>> Hi,
>>>
>>> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>>>> On Fri, Sep 02, 2016 at 12:43:39PM +0200, Arnd Bergmann wrote:
>>>>> On Thursday, September 1, 2016 5:14:28 PM CEST Leo Li wrote:
>>>>>>
>>>>>> Hi Felipe and Arnd,
>>>>>>
>>>>>> It has been a while since the last response to this discussion, but we
>>>>>> haven't reached an agreement yet!  Can we get to a conclusion on if it
>>>>>> is valid to create child platform device for abstraction purpose?  If
>>>>>> yes, can this child device do DMA by itself?
>>>>>
>>>>> I'd say it's no problem for a driver to create child devices in order
>>>>> to represent different aspects of a device, but you should not rely on
>>>>> those devices working when used with the dma-mapping interfaces.
>>>>
>>>> That's absolutely right.  Consider the USB model - only the USB host
>>>> controller can perform DMA, not the USB devices themselves.  All DMA
>>>> mappings need to be mapped using the USB host controller device struct
>>>> not the USB device struct.
>>>>
>>>> The same _should_ be true everywhere else: the struct device representing
>>>> the device performing DMA must be the one used to map the transfer.
>>>
>>> How do we fix dwc3 in dual-role, then?
>>>
>>> Peripheral-side dwc3 is easy, we just require a glue-layer to be present
>>> and use dwc3.ko's parent device (which will be the PCI device or OF
>>> device). But for host side dwc3, the problem is slightly more complex
>>> because we're using xhci-plat.ko by just instantiating a xhci-platform
>>> device so xhci-plat can probe.
>>>
>>> xhci core has no means to know if its own device or the parent of its
>>> parent should be used for DMA. Any ideas?
>>
>> In theory, you can store a flag somewhere in the platform device,
>> something that would tell xhci-hcd that it has to use the parent's
>> parent for DMA purposes.
>>
>> I know it would be somewhat of a hack, but ought to work.
> 
> Speaking of that flag, I suppose we need the same logic to know where
> to look for USB devices attached to a dwc3 host when we need to describe
> them in DT. By default we look for child device nodes under the
> node of the HCD device node, but that would be wrong here too.

I didn't get this part. Information about USB devices attached to a USB host
is never provided in DT because they are always dynamically created via
usb_new_device(), whether they are hard-wired on the board or hot-plugged.

These USB devices inherit their DMA masks in the usb_alloc_dev() routine
whereas each interface within the USB device inherits its DMA mask in
usb_set_configuration().

There is a bug  in the USB core because of which the ISB device and interfaces
do not inherit dma_pfn_offset correctly for which I've sent a patch
https://lkml.org/lkml/2016/8/17/275

cheers,
-roger

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-06 13:27                                                     ` Arnd Bergmann
@ 2016-09-07  7:44                                                       ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  7:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Tue, Sep 06, 2016 at 03:27:43PM +0200, Arnd Bergmann wrote:
> On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> > >> 
> > >> this only solves the problem for DT devices. Legacy devices and
> > >> PCI-based systems will still suffer from the same problem. At least for
> > >> dwc3, I will only be taking patches that solve the problem for all
> > >> users, not a subset of them.
> > >
> > > I don't think legacy devices are a worry, because they wouldn't
> > > have this problem. For the PCI case, you are right that it cannot
> > > work, in particular for machines that have complex IOMMU setup.
> > >
> > > Some architectures (at least arm64 and sparc) check the bus_type of
> > > a device in order to find the correct set of dma_map_ops for that
> > > device, so there is no real way to handle this as long as you
> > > pass a platform_device into an API that expects a pci_device.
> > 
> > Then I guess we're left with adding a "struct device *dma_dev" to struct
> > dwc3 and trying to figure out if we should use parent or self. Does
> > anybody see any problems with that?
> 
> I think we actually need the device pointer in the usb_hcd structure,
> so it can be passed in these API calls from the USB core
> 
> drivers/usb/core/buffer.c:      return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
> drivers/usb/core/buffer.c:      dma_free_coherent(hcd->self.controller, size, addr, dma);
> drivers/usb/core/buffer.c:          (!hcd->self.controller->dma_mask &&
> drivers/usb/core/buffer.c:              hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
> drivers/usb/core/hcd.c:                 urb->setup_dma = dma_map_single(
> drivers/usb/core/hcd.c:                 if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/hcd.c:                         n = dma_map_sg(
> drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_page(
> drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_single(
> drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/usb.c:         urb->transfer_dma = dma_map_single(controller,
> drivers/usb/core/usb.c: return dma_map_sg(controller, sg, nents,
> drivers/usb/core/usb.c:         dma_sync_single_for_cpu(controller,
> drivers/usb/core/usb.c:                 dma_sync_single_for_cpu(controller,
> drivers/usb/core/usb.c: dma_sync_sg_for_cpu(controller, sg, n_hw_ents,
> 
> as these are all called on behalf of the host controller node.

The USB HCD core uses the struct device pointer passed by usb_create_hcd
which is called by each host controller driver, the host controller driver
needs to make sure the information (DMA configurations, of_node, etc)
in struct device are correct before calling usb_create_hcd.

> Looking for more instances of hcd->self.controller, I find this
> instance:
> 
> drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
> drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");
> 
> I'm unsure which device pointer we want here, but I suspect this also
> needs to be the one that has the device node in order to make the lookup
> of the phy structure by device node work right. Can you clarify how
> this works today?
> 

The above codes are only called when the host controller driver does not
the code which try to get USB PHY. Once the PHY drivers is probed, the
above code can work no matter DT or non-DT.

But by looking at the code, I am wondering how dwc3 host get its USB PHY at
xhci-platform.c, it seems there is no of_node at xhci-hcd for dwc3.

> We probably also need to add the of_node of the host controller device
> to struct usb_hcd in order to make usb_of_get_child_node() work
> in the case where the hcd itself is not device that is listed
> in DT.

The pre-condition of DT function at USB HCD core works is the host
controller device has of_node, since it is the root node for USB tree
described at DT. If the host controller device is not at DT, it needs
to try to get its of_node, the chipidea driver gets it through its
parent node [1]

> It might be a good idea to use 'struct fwnode_handle' for that,
> so we can in the future also allow ACPI platforms to specify 
> 
> > Note, we would NOT be passing device pointers are platform_data, we
> > would have dwc3.ko figure out if it should use self or its parent device
> > for dma.
> 
> Ok, sounds good.
> 
> 	Arnd

[1] https://lkml.org/lkml/2016/8/8/119

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  7:44                                                       ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  7:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 06, 2016 at 03:27:43PM +0200, Arnd Bergmann wrote:
> On Tuesday, September 6, 2016 1:50:48 PM CEST Felipe Balbi wrote:
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > > On Tuesday, September 6, 2016 9:40:19 AM CEST Felipe Balbi wrote:
> > >> 
> > >> this only solves the problem for DT devices. Legacy devices and
> > >> PCI-based systems will still suffer from the same problem. At least for
> > >> dwc3, I will only be taking patches that solve the problem for all
> > >> users, not a subset of them.
> > >
> > > I don't think legacy devices are a worry, because they wouldn't
> > > have this problem. For the PCI case, you are right that it cannot
> > > work, in particular for machines that have complex IOMMU setup.
> > >
> > > Some architectures (at least arm64 and sparc) check the bus_type of
> > > a device in order to find the correct set of dma_map_ops for that
> > > device, so there is no real way to handle this as long as you
> > > pass a platform_device into an API that expects a pci_device.
> > 
> > Then I guess we're left with adding a "struct device *dma_dev" to struct
> > dwc3 and trying to figure out if we should use parent or self. Does
> > anybody see any problems with that?
> 
> I think we actually need the device pointer in the usb_hcd structure,
> so it can be passed in these API calls from the USB core
> 
> drivers/usb/core/buffer.c:      return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
> drivers/usb/core/buffer.c:      dma_free_coherent(hcd->self.controller, size, addr, dma);
> drivers/usb/core/buffer.c:          (!hcd->self.controller->dma_mask &&
> drivers/usb/core/buffer.c:              hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
> drivers/usb/core/hcd.c:                 urb->setup_dma = dma_map_single(
> drivers/usb/core/hcd.c:                 if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/hcd.c:                         n = dma_map_sg(
> drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_page(
> drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/hcd.c:                         urb->transfer_dma = dma_map_single(
> drivers/usb/core/hcd.c:                         if (dma_mapping_error(hcd->self.controller,
> drivers/usb/core/usb.c:         urb->transfer_dma = dma_map_single(controller,
> drivers/usb/core/usb.c: return dma_map_sg(controller, sg, nents,
> drivers/usb/core/usb.c:         dma_sync_single_for_cpu(controller,
> drivers/usb/core/usb.c:                 dma_sync_single_for_cpu(controller,
> drivers/usb/core/usb.c: dma_sync_sg_for_cpu(controller, sg, n_hw_ents,
> 
> as these are all called on behalf of the host controller node.

The USB HCD core uses the struct device pointer passed by usb_create_hcd
which is called by each host controller driver, the host controller driver
needs to make sure the information (DMA configurations, of_node, etc)
in struct device are correct before calling usb_create_hcd.

> Looking for more instances of hcd->self.controller, I find this
> instance:
> 
> drivers/usb/core/hcd.c:         struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
> drivers/usb/core/hcd.c:         struct phy *phy = phy_get(hcd->self.controller, "usb");
> 
> I'm unsure which device pointer we want here, but I suspect this also
> needs to be the one that has the device node in order to make the lookup
> of the phy structure by device node work right. Can you clarify how
> this works today?
> 

The above codes are only called when the host controller driver does not
the code which try to get USB PHY. Once the PHY drivers is probed, the
above code can work no matter DT or non-DT.

But by looking at the code, I am wondering how dwc3 host get its USB PHY at
xhci-platform.c, it seems there is no of_node at xhci-hcd for dwc3.

> We probably also need to add the of_node of the host controller device
> to struct usb_hcd in order to make usb_of_get_child_node() work
> in the case where the hcd itself is not device that is listed
> in DT.

The pre-condition of DT function at USB HCD core works is the host
controller device has of_node, since it is the root node for USB tree
described at DT. If the host controller device is not at DT, it needs
to try to get its of_node, the chipidea driver gets it through its
parent node [1]

> It might be a good idea to use 'struct fwnode_handle' for that,
> so we can in the future also allow ACPI platforms to specify 
> 
> > Note, we would NOT be passing device pointers are platform_data, we
> > would have dwc3.ko figure out if it should use self or its parent device
> > for dma.
> 
> Ok, sounds good.
> 
> 	Arnd

[1] https://lkml.org/lkml/2016/8/8/119

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  7:17                                                 ` Roger Quadros
@ 2016-09-07  8:29                                                   ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:29 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-arm-kernel, Alan Stern, Felipe Balbi, Grygorii Strashko,
	Stuart Yoder, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, Russell King - ARM Linux, lkml, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman

On Wednesday, September 7, 2016 10:17:31 AM CEST Roger Quadros wrote:
> > 
> > Speaking of that flag, I suppose we need the same logic to know where
> > to look for USB devices attached to a dwc3 host when we need to describe
> > them in DT. By default we look for child device nodes under the
> > node of the HCD device node, but that would be wrong here too.
> 
> I didn't get this part. Information about USB devices attached to a USB host
> is never provided in DT because they are always dynamically created via
> usb_new_device(), whether they are hard-wired on the board or hot-plugged.
> 
> These USB devices inherit their DMA masks in the usb_alloc_dev() routine
> whereas each interface within the USB device inherits its DMA mask in
> usb_set_configuration().

We had talked about adding support for this for at least six years (probably
much more), but Peter Chen finally added it this year in commit 69bec72598
("USB: core: let USB device know device node").

The main use for it is to let you specify a MAC address for on-board
ethernet devices that lack an EPROM, but any other information can be
added that way too.

> There is a bug  in the USB core because of which the ISB device and interfaces
> do not inherit dma_pfn_offset correctly for which I've sent a patch
> https://lkml.org/lkml/2016/8/17/275

I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
also set the dma_pfn_offset, but what exactly is this used for in USB
devices?

As I understand it, the dma_mask/dma_pfn_offset etc is used for the DMA
mapping interface, but that can't really be used on USB devices, which
I assume use usb_alloc_coherent() and the URB interfaces for passing data
between a USB driver and the HCD. My knowledge of USB device drivers
is a bit lacking, so it's possible I'm misunderstanding things here.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  8:29                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 10:17:31 AM CEST Roger Quadros wrote:
> > 
> > Speaking of that flag, I suppose we need the same logic to know where
> > to look for USB devices attached to a dwc3 host when we need to describe
> > them in DT. By default we look for child device nodes under the
> > node of the HCD device node, but that would be wrong here too.
> 
> I didn't get this part. Information about USB devices attached to a USB host
> is never provided in DT because they are always dynamically created via
> usb_new_device(), whether they are hard-wired on the board or hot-plugged.
> 
> These USB devices inherit their DMA masks in the usb_alloc_dev() routine
> whereas each interface within the USB device inherits its DMA mask in
> usb_set_configuration().

We had talked about adding support for this for at least six years (probably
much more), but Peter Chen finally added it this year in commit 69bec72598
("USB: core: let USB device know device node").

The main use for it is to let you specify a MAC address for on-board
ethernet devices that lack an EPROM, but any other information can be
added that way too.

> There is a bug  in the USB core because of which the ISB device and interfaces
> do not inherit dma_pfn_offset correctly for which I've sent a patch
> https://lkml.org/lkml/2016/8/17/275

I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
also set the dma_pfn_offset, but what exactly is this used for in USB
devices?

As I understand it, the dma_mask/dma_pfn_offset etc is used for the DMA
mapping interface, but that can't really be used on USB devices, which
I assume use usb_alloc_coherent() and the URB interfaces for passing data
between a USB driver and the HCD. My knowledge of USB device drivers
is a bit lacking, so it's possible I'm misunderstanding things here.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  6:33                                                 ` Peter Chen
@ 2016-09-07  8:48                                                   ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:48 UTC (permalink / raw)
  To: Peter Chen
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Wednesday, September 7, 2016 2:33:13 PM CEST Peter Chen wrote:
> > 
> > Right, that should make it work with iommu as well. However, it does
> > not solve the other issue I mentioned above, with boards that have
> > USB devices hardwired to a chipidea host controller that need
> > configuration from DT. For that, we still need to come up with another
> > way to associate the DT hierarchy in the host bridge node with
> > the Linux platform_device.
> > 
> 
> Why? The DMA configuration is for host controller, not for USB device.
> No matter there is hardwired or hotplug devices, the DMA configuration
> for host controller are both inherited from glue layer platform devices,
> current implementation is at function ci_hdrc_add_device,
> drivers/usb/chipidea/core.c.

I wasn't referring to DMA configuration there, but only to how we
set the of_node pointer in register_root_hub, which you added in
dc5878abf49 ("usb: core: move root hub's device node assignment after
it is added to bus") as:

	usb_dev->dev.of_node = parent_dev->of_node;

As I understand, parent_dev (aka hcd->self.controller) here
refers to the device that you add in ci_hdrc_add_device(),
which does not have an of_node pointer, so we actually
want parent_dev->parent->of_node.

I'm sure you understand that code better than me, so let me
know what my mistake is if this indeed works correctly.



Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
I think we should replace 

        pdev->dev.dma_mask = dev->dma_mask;
        pdev->dev.dma_parms = dev->dma_parms;
        dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);

with of_dma_configure(), which has the chance to configure more than
just those three, as the dma API might look into different aspects:

- iommu specific configuration
- cache coherency information
- bus type
- dma offset
- dma_map_ops pointer

We try to handle everything in of_dma_configure() at configuration
time, and that would be the place to add anything else that we might
need in the future.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  8:48                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 2:33:13 PM CEST Peter Chen wrote:
> > 
> > Right, that should make it work with iommu as well. However, it does
> > not solve the other issue I mentioned above, with boards that have
> > USB devices hardwired to a chipidea host controller that need
> > configuration from DT. For that, we still need to come up with another
> > way to associate the DT hierarchy in the host bridge node with
> > the Linux platform_device.
> > 
> 
> Why? The DMA configuration is for host controller, not for USB device.
> No matter there is hardwired or hotplug devices, the DMA configuration
> for host controller are both inherited from glue layer platform devices,
> current implementation is at function ci_hdrc_add_device,
> drivers/usb/chipidea/core.c.

I wasn't referring to DMA configuration there, but only to how we
set the of_node pointer in register_root_hub, which you added in
dc5878abf49 ("usb: core: move root hub's device node assignment after
it is added to bus") as:

	usb_dev->dev.of_node = parent_dev->of_node;

As I understand, parent_dev (aka hcd->self.controller) here
refers to the device that you add in ci_hdrc_add_device(),
which does not have an of_node pointer, so we actually
want parent_dev->parent->of_node.

I'm sure you understand that code better than me, so let me
know what my mistake is if this indeed works correctly.



Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
I think we should replace 

        pdev->dev.dma_mask = dev->dma_mask;
        pdev->dev.dma_parms = dev->dma_parms;
        dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);

with of_dma_configure(), which has the chance to configure more than
just those three, as the dma API might look into different aspects:

- iommu specific configuration
- cache coherency information
- bus type
- dma offset
- dma_map_ops pointer

We try to handle everything in of_dma_configure() at configuration
time, and that would be the place to add anything else that we might
need in the future.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  7:44                                                       ` Peter Chen
@ 2016-09-07  8:52                                                         ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:52 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> 
> The pre-condition of DT function at USB HCD core works is the host
> controller device has of_node, since it is the root node for USB tree
> described at DT. If the host controller device is not at DT, it needs
> to try to get its of_node, the chipidea driver gets it through its
> parent node [1]

> 
> [1] https://lkml.org/lkml/2016/8/8/119
> 

Ah, this is what I was referring to in the other mail.

However, the way you set the of_node might be dangerous too:
We should generally not have two platform_device structures with
the same of_node pointer, most importantly it may cause the
child device to be bound to the same driver as the parent
device since the probing is done by compatible string.

As you tested it successfully, it must work at the moment on your
machine, but it could easily break depending on deferred probing
or module load order.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  8:52                                                         ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> 
> The pre-condition of DT function at USB HCD core works is the host
> controller device has of_node, since it is the root node for USB tree
> described at DT. If the host controller device is not at DT, it needs
> to try to get its of_node, the chipidea driver gets it through its
> parent node [1]

> 
> [1] https://lkml.org/lkml/2016/8/8/119
> 

Ah, this is what I was referring to in the other mail.

However, the way you set the of_node might be dangerous too:
We should generally not have two platform_device structures with
the same of_node pointer, most importantly it may cause the
child device to be bound to the same driver as the parent
device since the probing is done by compatible string.

As you tested it successfully, it must work at the moment on your
machine, but it could easily break depending on deferred probing
or module load order.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  8:52                                                         ` Arnd Bergmann
@ 2016-09-07  9:29                                                           ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  9:29 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> > 
> > The pre-condition of DT function at USB HCD core works is the host
> > controller device has of_node, since it is the root node for USB tree
> > described at DT. If the host controller device is not at DT, it needs
> > to try to get its of_node, the chipidea driver gets it through its
> > parent node [1]
> 
> > 
> > [1] https://lkml.org/lkml/2016/8/8/119
> > 
> 
> Ah, this is what I was referring to in the other mail.
> 
> However, the way you set the of_node might be dangerous too:
> We should generally not have two platform_device structures with
> the same of_node pointer, most importantly it may cause the
> child device to be bound to the same driver as the parent
> device since the probing is done by compatible string.
> 
> As you tested it successfully, it must work at the moment on your
> machine, but it could easily break depending on deferred probing
> or module load order.
> 

Currently, I work around above problems by setting core device of_node
as NULL at both probe error path and platform driver .remove routine.

I admit it is not a good way, but if we only have of_node at device's
life periods after probe, it seems ok currently. It is hard to create
of_node dynamically when create device, and keep some contents
of parent's of_node, and some are not.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  9:29                                                           ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  9:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> > 
> > The pre-condition of DT function at USB HCD core works is the host
> > controller device has of_node, since it is the root node for USB tree
> > described at DT. If the host controller device is not at DT, it needs
> > to try to get its of_node, the chipidea driver gets it through its
> > parent node [1]
> 
> > 
> > [1] https://lkml.org/lkml/2016/8/8/119
> > 
> 
> Ah, this is what I was referring to in the other mail.
> 
> However, the way you set the of_node might be dangerous too:
> We should generally not have two platform_device structures with
> the same of_node pointer, most importantly it may cause the
> child device to be bound to the same driver as the parent
> device since the probing is done by compatible string.
> 
> As you tested it successfully, it must work at the moment on your
> machine, but it could easily break depending on deferred probing
> or module load order.
> 

Currently, I work around above problems by setting core device of_node
as NULL at both probe error path and platform driver .remove routine.

I admit it is not a good way, but if we only have of_node at device's
life periods after probe, it seems ok currently. It is hard to create
of_node dynamically when create device, and keep some contents
of parent's of_node, and some are not.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  9:29                                                           ` Peter Chen
@ 2016-09-07  9:35                                                             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-09-07  9:35 UTC (permalink / raw)
  To: Peter Chen
  Cc: Arnd Bergmann, Felipe Balbi, Leo Li, Grygorii Strashko,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Wed, Sep 07, 2016 at 05:29:01PM +0800, Peter Chen wrote:
> On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
> > On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> > > 
> > > The pre-condition of DT function at USB HCD core works is the host
> > > controller device has of_node, since it is the root node for USB tree
> > > described at DT. If the host controller device is not at DT, it needs
> > > to try to get its of_node, the chipidea driver gets it through its
> > > parent node [1]
> > 
> > > 
> > > [1] https://lkml.org/lkml/2016/8/8/119
> > > 
> > 
> > Ah, this is what I was referring to in the other mail.
> > 
> > However, the way you set the of_node might be dangerous too:
> > We should generally not have two platform_device structures with
> > the same of_node pointer, most importantly it may cause the
> > child device to be bound to the same driver as the parent
> > device since the probing is done by compatible string.
> > 
> > As you tested it successfully, it must work at the moment on your
> > machine, but it could easily break depending on deferred probing
> > or module load order.
> > 
> 
> Currently, I work around above problems by setting core device of_node
> as NULL at both probe error path and platform driver .remove routine.
> 
> I admit it is not a good way, but if we only have of_node at device's
> life periods after probe, it seems ok currently. It is hard to create
> of_node dynamically when create device, and keep some contents
> of parent's of_node, and some are not.

How about turning dwc3 into a library which can be used by a range of
platform devices?  Wouldn't that solve all the current problems, and
completely avoid the need to copy resources from one platform device
to another?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  9:35                                                             ` Russell King - ARM Linux
  0 siblings, 0 replies; 182+ messages in thread
From: Russell King - ARM Linux @ 2016-09-07  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2016 at 05:29:01PM +0800, Peter Chen wrote:
> On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
> > On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
> > > 
> > > The pre-condition of DT function at USB HCD core works is the host
> > > controller device has of_node, since it is the root node for USB tree
> > > described at DT. If the host controller device is not at DT, it needs
> > > to try to get its of_node, the chipidea driver gets it through its
> > > parent node [1]
> > 
> > > 
> > > [1] https://lkml.org/lkml/2016/8/8/119
> > > 
> > 
> > Ah, this is what I was referring to in the other mail.
> > 
> > However, the way you set the of_node might be dangerous too:
> > We should generally not have two platform_device structures with
> > the same of_node pointer, most importantly it may cause the
> > child device to be bound to the same driver as the parent
> > device since the probing is done by compatible string.
> > 
> > As you tested it successfully, it must work at the moment on your
> > machine, but it could easily break depending on deferred probing
> > or module load order.
> > 
> 
> Currently, I work around above problems by setting core device of_node
> as NULL at both probe error path and platform driver .remove routine.
> 
> I admit it is not a good way, but if we only have of_node at device's
> life periods after probe, it seems ok currently. It is hard to create
> of_node dynamically when create device, and keep some contents
> of parent's of_node, and some are not.

How about turning dwc3 into a library which can be used by a range of
platform devices?  Wouldn't that solve all the current problems, and
completely avoid the need to copy resources from one platform device
to another?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  8:48                                                   ` Arnd Bergmann
@ 2016-09-07  9:55                                                     ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  9:55 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Leo Li, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Wed, Sep 07, 2016 at 10:48:06AM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 2:33:13 PM CEST Peter Chen wrote:
> > > 
> > > Right, that should make it work with iommu as well. However, it does
> > > not solve the other issue I mentioned above, with boards that have
> > > USB devices hardwired to a chipidea host controller that need
> > > configuration from DT. For that, we still need to come up with another
> > > way to associate the DT hierarchy in the host bridge node with
> > > the Linux platform_device.
> > > 
> > 
> > Why? The DMA configuration is for host controller, not for USB device.
> > No matter there is hardwired or hotplug devices, the DMA configuration
> > for host controller are both inherited from glue layer platform devices,
> > current implementation is at function ci_hdrc_add_device,
> > drivers/usb/chipidea/core.c.
> 
> I wasn't referring to DMA configuration there, but only to how we
> set the of_node pointer in register_root_hub, which you added in
> dc5878abf49 ("usb: core: move root hub's device node assignment after
> it is added to bus") as:
> 
> 	usb_dev->dev.of_node = parent_dev->of_node;
> 
> As I understand, parent_dev (aka hcd->self.controller) here
> refers to the device that you add in ci_hdrc_add_device(),
> which does not have an of_node pointer, so we actually
> want parent_dev->parent->of_node.

For platform devices, like chipidea and dwc3, it is correct, since
they don't have of_node. If the host controller has of_node, it
is controller's of_node. In order to let USB HCD core life be easy,
we need to let hcd->self.controller own of_node when it is added
to HCD core, no matter it has from the dts or get it dynamically.

> 
> I'm sure you understand that code better than me, so let me
> know what my mistake is if this indeed works correctly.
> 

Your understanding is correct, just some have of_node from dts, some
(chipidea/dwc3) need to have assignment at its driver.

> 
> 
> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> I think we should replace 
> 
>         pdev->dev.dma_mask = dev->dma_mask;
>         pdev->dev.dma_parms = dev->dma_parms;
>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> 
> with of_dma_configure(), which has the chance to configure more than
> just those three, as the dma API might look into different aspects:
> 
> - iommu specific configuration
> - cache coherency information
> - bus type
> - dma offset
> - dma_map_ops pointer
> 
> We try to handle everything in of_dma_configure() at configuration
> time, and that would be the place to add anything else that we might
> need in the future.
> 

Yes, I agree with you, but just like Felipe mentioned, we also need to
consider PCI device, can we do something like gpiod_get_index does? Are
there any similar APIs like of_dma_configure for ACPI?

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07  9:55                                                     ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-07  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2016 at 10:48:06AM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 2:33:13 PM CEST Peter Chen wrote:
> > > 
> > > Right, that should make it work with iommu as well. However, it does
> > > not solve the other issue I mentioned above, with boards that have
> > > USB devices hardwired to a chipidea host controller that need
> > > configuration from DT. For that, we still need to come up with another
> > > way to associate the DT hierarchy in the host bridge node with
> > > the Linux platform_device.
> > > 
> > 
> > Why? The DMA configuration is for host controller, not for USB device.
> > No matter there is hardwired or hotplug devices, the DMA configuration
> > for host controller are both inherited from glue layer platform devices,
> > current implementation is at function ci_hdrc_add_device,
> > drivers/usb/chipidea/core.c.
> 
> I wasn't referring to DMA configuration there, but only to how we
> set the of_node pointer in register_root_hub, which you added in
> dc5878abf49 ("usb: core: move root hub's device node assignment after
> it is added to bus") as:
> 
> 	usb_dev->dev.of_node = parent_dev->of_node;
> 
> As I understand, parent_dev (aka hcd->self.controller) here
> refers to the device that you add in ci_hdrc_add_device(),
> which does not have an of_node pointer, so we actually
> want parent_dev->parent->of_node.

For platform devices, like chipidea and dwc3, it is correct, since
they don't have of_node. If the host controller has of_node, it
is controller's of_node. In order to let USB HCD core life be easy,
we need to let hcd->self.controller own of_node when it is added
to HCD core, no matter it has from the dts or get it dynamically.

> 
> I'm sure you understand that code better than me, so let me
> know what my mistake is if this indeed works correctly.
> 

Your understanding is correct, just some have of_node from dts, some
(chipidea/dwc3) need to have assignment at its driver.

> 
> 
> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> I think we should replace 
> 
>         pdev->dev.dma_mask = dev->dma_mask;
>         pdev->dev.dma_parms = dev->dma_parms;
>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> 
> with of_dma_configure(), which has the chance to configure more than
> just those three, as the dma API might look into different aspects:
> 
> - iommu specific configuration
> - cache coherency information
> - bus type
> - dma offset
> - dma_map_ops pointer
> 
> We try to handle everything in of_dma_configure() at configuration
> time, and that would be the place to add anything else that we might
> need in the future.
> 

Yes, I agree with you, but just like Felipe mentioned, we also need to
consider PCI device, can we do something like gpiod_get_index does? Are
there any similar APIs like of_dma_configure for ACPI?

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  9:35                                                             ` Russell King - ARM Linux
@ 2016-09-07 10:18                                                               ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:18 UTC (permalink / raw)
  To: Russell King - ARM Linux, Peter Chen
  Cc: Arnd Bergmann, Leo Li, Grygorii Strashko, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2423 bytes --]


Hi,

Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> On Wed, Sep 07, 2016 at 05:29:01PM +0800, Peter Chen wrote:
>> On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
>> > On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
>> > > 
>> > > The pre-condition of DT function at USB HCD core works is the host
>> > > controller device has of_node, since it is the root node for USB tree
>> > > described at DT. If the host controller device is not at DT, it needs
>> > > to try to get its of_node, the chipidea driver gets it through its
>> > > parent node [1]
>> > 
>> > > 
>> > > [1] https://lkml.org/lkml/2016/8/8/119
>> > > 
>> > 
>> > Ah, this is what I was referring to in the other mail.
>> > 
>> > However, the way you set the of_node might be dangerous too:
>> > We should generally not have two platform_device structures with
>> > the same of_node pointer, most importantly it may cause the
>> > child device to be bound to the same driver as the parent
>> > device since the probing is done by compatible string.
>> > 
>> > As you tested it successfully, it must work at the moment on your
>> > machine, but it could easily break depending on deferred probing
>> > or module load order.
>> > 
>> 
>> Currently, I work around above problems by setting core device of_node
>> as NULL at both probe error path and platform driver .remove routine.
>> 
>> I admit it is not a good way, but if we only have of_node at device's
>> life periods after probe, it seems ok currently. It is hard to create
>> of_node dynamically when create device, and keep some contents
>> of parent's of_node, and some are not.
>
> How about turning dwc3 into a library which can be used by a range of
> platform devices?  Wouldn't that solve all the current problems, and
> completely avoid the need to copy resources from one platform device
> to another?

This will break all existing DTs out there. Also, there are other
benefits from keeping current design, these have been discussed before
but here's a short summary:

. PM callbacks are kept simple
. We avoid abuse of internal dwc3 functions
. It's a lot less work to "port" dwc3 to "your SoC"
. We prevent another MUSB (drivers/usb/musb/)

And few others. Sure, they are rather subjective benefits, but it has
worked well so far. Also, breaking DT ABI is kind of a big deal.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 10:18                                                               ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:18 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> On Wed, Sep 07, 2016 at 05:29:01PM +0800, Peter Chen wrote:
>> On Wed, Sep 07, 2016 at 10:52:46AM +0200, Arnd Bergmann wrote:
>> > On Wednesday, September 7, 2016 3:44:28 PM CEST Peter Chen wrote:
>> > > 
>> > > The pre-condition of DT function at USB HCD core works is the host
>> > > controller device has of_node, since it is the root node for USB tree
>> > > described at DT. If the host controller device is not at DT, it needs
>> > > to try to get its of_node, the chipidea driver gets it through its
>> > > parent node [1]
>> > 
>> > > 
>> > > [1] https://lkml.org/lkml/2016/8/8/119
>> > > 
>> > 
>> > Ah, this is what I was referring to in the other mail.
>> > 
>> > However, the way you set the of_node might be dangerous too:
>> > We should generally not have two platform_device structures with
>> > the same of_node pointer, most importantly it may cause the
>> > child device to be bound to the same driver as the parent
>> > device since the probing is done by compatible string.
>> > 
>> > As you tested it successfully, it must work at the moment on your
>> > machine, but it could easily break depending on deferred probing
>> > or module load order.
>> > 
>> 
>> Currently, I work around above problems by setting core device of_node
>> as NULL at both probe error path and platform driver .remove routine.
>> 
>> I admit it is not a good way, but if we only have of_node at device's
>> life periods after probe, it seems ok currently. It is hard to create
>> of_node dynamically when create device, and keep some contents
>> of parent's of_node, and some are not.
>
> How about turning dwc3 into a library which can be used by a range of
> platform devices?  Wouldn't that solve all the current problems, and
> completely avoid the need to copy resources from one platform device
> to another?

This will break all existing DTs out there. Also, there are other
benefits from keeping current design, these have been discussed before
but here's a short summary:

. PM callbacks are kept simple
. We avoid abuse of internal dwc3 functions
. It's a lot less work to "port" dwc3 to "your SoC"
. We prevent another MUSB (drivers/usb/musb/)

And few others. Sure, they are rather subjective benefits, but it has
worked well so far. Also, breaking DT ABI is kind of a big deal.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160907/7405dd65/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  8:48                                                   ` Arnd Bergmann
@ 2016-09-07 10:24                                                     ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:24 UTC (permalink / raw)
  To: Arnd Bergmann, Peter Chen
  Cc: Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1296 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:

[...]

> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> I think we should replace 
>
>         pdev->dev.dma_mask = dev->dma_mask;
>         pdev->dev.dma_parms = dev->dma_parms;
>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>
> with of_dma_configure(), which has the chance to configure more than
> just those three, as the dma API might look into different aspects:
>
> - iommu specific configuration
> - cache coherency information
> - bus type
> - dma offset
> - dma_map_ops pointer
>
> We try to handle everything in of_dma_configure() at configuration
> time, and that would be the place to add anything else that we might
> need in the future.

There are a couple problems with this:

1) won't work for PCI-based systems.

DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
platform (FPGA that appears like a PCI card to host PC)


2) not very robust solution

of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
that's not created by DT. The only reason why this works at all is
because of the default 32-bit dma mask thing :-) So, how is it any
different than copying 32-bit dma mask from parent?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 10:24                                                     ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:24 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:

[...]

> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> I think we should replace 
>
>         pdev->dev.dma_mask = dev->dma_mask;
>         pdev->dev.dma_parms = dev->dma_parms;
>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>
> with of_dma_configure(), which has the chance to configure more than
> just those three, as the dma API might look into different aspects:
>
> - iommu specific configuration
> - cache coherency information
> - bus type
> - dma offset
> - dma_map_ops pointer
>
> We try to handle everything in of_dma_configure() at configuration
> time, and that would be the place to add anything else that we might
> need in the future.

There are a couple problems with this:

1) won't work for PCI-based systems.

DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
platform (FPGA that appears like a PCI card to host PC)


2) not very robust solution

of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
that's not created by DT. The only reason why this works at all is
because of the default 32-bit dma mask thing :-) So, how is it any
different than copying 32-bit dma mask from parent?

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160907/f2ae3b10/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  9:55                                                     ` Peter Chen
@ 2016-09-07 10:33                                                       ` Robin Murphy
  -1 siblings, 0 replies; 182+ messages in thread
From: Robin Murphy @ 2016-09-07 10:33 UTC (permalink / raw)
  To: Peter Chen, Arnd Bergmann
  Cc: Felipe Balbi, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen, Leo Li,
	Greg Kroah-Hartman, Alan Stern, linux-arm-kernel,
	Lorenzo Pieralisi

On 07/09/16 10:55, Peter Chen wrote:
[...]
>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>> I think we should replace 
>>
>>         pdev->dev.dma_mask = dev->dma_mask;
>>         pdev->dev.dma_parms = dev->dma_parms;
>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>>
>> with of_dma_configure(), which has the chance to configure more than
>> just those three, as the dma API might look into different aspects:
>>
>> - iommu specific configuration
>> - cache coherency information
>> - bus type
>> - dma offset
>> - dma_map_ops pointer
>>
>> We try to handle everything in of_dma_configure() at configuration
>> time, and that would be the place to add anything else that we might
>> need in the future.
>>
> 
> Yes, I agree with you, but just like Felipe mentioned, we also need to
> consider PCI device, can we do something like gpiod_get_index does? Are
> there any similar APIs like of_dma_configure for ACPI?

Not yet, but Lorenzo has one in progress[1], primarily for the sake of
abstracting away the IOMMU configuration.

Robin.

[1]:http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1209911.html

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 10:33                                                       ` Robin Murphy
  0 siblings, 0 replies; 182+ messages in thread
From: Robin Murphy @ 2016-09-07 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/09/16 10:55, Peter Chen wrote:
[...]
>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>> I think we should replace 
>>
>>         pdev->dev.dma_mask = dev->dma_mask;
>>         pdev->dev.dma_parms = dev->dma_parms;
>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>>
>> with of_dma_configure(), which has the chance to configure more than
>> just those three, as the dma API might look into different aspects:
>>
>> - iommu specific configuration
>> - cache coherency information
>> - bus type
>> - dma offset
>> - dma_map_ops pointer
>>
>> We try to handle everything in of_dma_configure() at configuration
>> time, and that would be the place to add anything else that we might
>> need in the future.
>>
> 
> Yes, I agree with you, but just like Felipe mentioned, we also need to
> consider PCI device, can we do something like gpiod_get_index does? Are
> there any similar APIs like of_dma_configure for ACPI?

Not yet, but Lorenzo has one in progress[1], primarily for the sake of
abstracting away the IOMMU configuration.

Robin.

[1]:http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1209911.html

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 10:33                                                       ` Robin Murphy
@ 2016-09-07 10:47                                                         ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:47 UTC (permalink / raw)
  To: Robin Murphy, Peter Chen, Arnd Bergmann
  Cc: Grygorii Strashko, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Leo Li,
	Greg Kroah-Hartman, Alan Stern, linux-arm-kernel,
	Lorenzo Pieralisi

[-- Attachment #1: Type: text/plain, Size: 1499 bytes --]


Hi,

Robin Murphy <robin.murphy@arm.com> writes:
> On 07/09/16 10:55, Peter Chen wrote:
> [...]
>>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>>> I think we should replace 
>>>
>>>         pdev->dev.dma_mask = dev->dma_mask;
>>>         pdev->dev.dma_parms = dev->dma_parms;
>>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>>>
>>> with of_dma_configure(), which has the chance to configure more than
>>> just those three, as the dma API might look into different aspects:
>>>
>>> - iommu specific configuration
>>> - cache coherency information
>>> - bus type
>>> - dma offset
>>> - dma_map_ops pointer
>>>
>>> We try to handle everything in of_dma_configure() at configuration
>>> time, and that would be the place to add anything else that we might
>>> need in the future.
>>>
>> 
>> Yes, I agree with you, but just like Felipe mentioned, we also need to
>> consider PCI device, can we do something like gpiod_get_index does? Are
>> there any similar APIs like of_dma_configure for ACPI?
>
> Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> abstracting away the IOMMU configuration.
>
> Robin.
>
> [1]:http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1209911.html

not exported for drivers to use. If Lorenzo is trying to making a
matching API for ACPI systems, then it needs to follow what
of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 10:47                                                         ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-07 10:47 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Robin Murphy <robin.murphy@arm.com> writes:
> On 07/09/16 10:55, Peter Chen wrote:
> [...]
>>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>>> I think we should replace 
>>>
>>>         pdev->dev.dma_mask = dev->dma_mask;
>>>         pdev->dev.dma_parms = dev->dma_parms;
>>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>>>
>>> with of_dma_configure(), which has the chance to configure more than
>>> just those three, as the dma API might look into different aspects:
>>>
>>> - iommu specific configuration
>>> - cache coherency information
>>> - bus type
>>> - dma offset
>>> - dma_map_ops pointer
>>>
>>> We try to handle everything in of_dma_configure() at configuration
>>> time, and that would be the place to add anything else that we might
>>> need in the future.
>>>
>> 
>> Yes, I agree with you, but just like Felipe mentioned, we also need to
>> consider PCI device, can we do something like gpiod_get_index does? Are
>> there any similar APIs like of_dma_configure for ACPI?
>
> Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> abstracting away the IOMMU configuration.
>
> Robin.
>
> [1]:http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1209911.html

not exported for drivers to use. If Lorenzo is trying to making a
matching API for ACPI systems, then it needs to follow what
of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160907/7e2c94c2/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07  8:29                                                   ` Arnd Bergmann
@ 2016-09-07 13:04                                                     ` Roger Quadros
  -1 siblings, 0 replies; 182+ messages in thread
From: Roger Quadros @ 2016-09-07 13:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Alan Stern, Felipe Balbi, Grygorii Strashko,
	Stuart Yoder, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, Russell King - ARM Linux, lkml, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman

On 07/09/16 11:29, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 10:17:31 AM CEST Roger Quadros wrote:
>>>
>>> Speaking of that flag, I suppose we need the same logic to know where
>>> to look for USB devices attached to a dwc3 host when we need to describe
>>> them in DT. By default we look for child device nodes under the
>>> node of the HCD device node, but that would be wrong here too.
>>
>> I didn't get this part. Information about USB devices attached to a USB host
>> is never provided in DT because they are always dynamically created via
>> usb_new_device(), whether they are hard-wired on the board or hot-plugged.
>>
>> These USB devices inherit their DMA masks in the usb_alloc_dev() routine
>> whereas each interface within the USB device inherits its DMA mask in
>> usb_set_configuration().
> 
> We had talked about adding support for this for at least six years (probably
> much more), but Peter Chen finally added it this year in commit 69bec72598
> ("USB: core: let USB device know device node").

OK. Thanks for this pointer.
> 
> The main use for it is to let you specify a MAC address for on-board
> ethernet devices that lack an EPROM, but any other information can be
> added that way too.
> 
>> There is a bug  in the USB core because of which the ISB device and interfaces
>> do not inherit dma_pfn_offset correctly for which I've sent a patch
>> https://lkml.org/lkml/2016/8/17/275
> 
> I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
> also set the dma_pfn_offset, but what exactly is this used for in USB
> devices?

Consider the mass storage device case.
USB storage driver creates a scsi host for the mass storage interface in
drivers/usb/storage/usb.c
The scsi host parent device is nothing but the the USB interface device.

Now, __scsi_init_queue() calls scsi_calculate_bounce_limit() to find out
and set the block layer bounce limit.

scsi_calculate_bounce_limit() uses dma_max_pfn(host_dev) to get the bounce_limit.

host_dev is nothing but the device representing the mass storage interface.

If that device doesn't have the right dma_pfn_offset, then dma_max_pfn()
is messed up and the bounce buffer limit is wrong.

> 
> As I understand it, the dma_mask/dma_pfn_offset etc is used for the DMA
> mapping interface, but that can't really be used on USB devices, which
> I assume use usb_alloc_coherent() and the URB interfaces for passing data
> between a USB driver and the HCD. My knowledge of USB device drivers
> is a bit lacking, so it's possible I'm misunderstanding things here.
> 

cheers,
-roger

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 13:04                                                     ` Roger Quadros
  0 siblings, 0 replies; 182+ messages in thread
From: Roger Quadros @ 2016-09-07 13:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/09/16 11:29, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 10:17:31 AM CEST Roger Quadros wrote:
>>>
>>> Speaking of that flag, I suppose we need the same logic to know where
>>> to look for USB devices attached to a dwc3 host when we need to describe
>>> them in DT. By default we look for child device nodes under the
>>> node of the HCD device node, but that would be wrong here too.
>>
>> I didn't get this part. Information about USB devices attached to a USB host
>> is never provided in DT because they are always dynamically created via
>> usb_new_device(), whether they are hard-wired on the board or hot-plugged.
>>
>> These USB devices inherit their DMA masks in the usb_alloc_dev() routine
>> whereas each interface within the USB device inherits its DMA mask in
>> usb_set_configuration().
> 
> We had talked about adding support for this for at least six years (probably
> much more), but Peter Chen finally added it this year in commit 69bec72598
> ("USB: core: let USB device know device node").

OK. Thanks for this pointer.
> 
> The main use for it is to let you specify a MAC address for on-board
> ethernet devices that lack an EPROM, but any other information can be
> added that way too.
> 
>> There is a bug  in the USB core because of which the ISB device and interfaces
>> do not inherit dma_pfn_offset correctly for which I've sent a patch
>> https://lkml.org/lkml/2016/8/17/275
> 
> I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
> also set the dma_pfn_offset, but what exactly is this used for in USB
> devices?

Consider the mass storage device case.
USB storage driver creates a scsi host for the mass storage interface in
drivers/usb/storage/usb.c
The scsi host parent device is nothing but the the USB interface device.

Now, __scsi_init_queue() calls scsi_calculate_bounce_limit() to find out
and set the block layer bounce limit.

scsi_calculate_bounce_limit() uses dma_max_pfn(host_dev) to get the bounce_limit.

host_dev is nothing but the device representing the mass storage interface.

If that device doesn't have the right dma_pfn_offset, then dma_max_pfn()
is messed up and the bounce buffer limit is wrong.

> 
> As I understand it, the dma_mask/dma_pfn_offset etc is used for the DMA
> mapping interface, but that can't really be used on USB devices, which
> I assume use usb_alloc_coherent() and the URB interfaces for passing data
> between a USB driver and the HCD. My knowledge of USB device drivers
> is a bit lacking, so it's possible I'm misunderstanding things here.
> 

cheers,
-roger

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 13:04                                                     ` Roger Quadros
@ 2016-09-07 14:38                                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 14:38 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-arm-kernel, Alan Stern, Felipe Balbi, Grygorii Strashko,
	Stuart Yoder, Catalin Marinas, Yoshihiro Shimoda, linux-usb,
	Sekhar Nori, Russell King - ARM Linux, lkml, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman

On Wednesday, September 7, 2016 4:04:52 PM CEST Roger Quadros wrote:
> > The main use for it is to let you specify a MAC address for on-board
> > ethernet devices that lack an EPROM, but any other information can be
> > added that way too.
> > 
> >> There is a bug  in the USB core because of which the ISB device and interfaces
> >> do not inherit dma_pfn_offset correctly for which I've sent a patch
> >> https://lkml.org/lkml/2016/8/17/275
> > 
> > I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
> > also set the dma_pfn_offset, but what exactly is this used for in USB
> > devices?
> 
> Consider the mass storage device case.
> USB storage driver creates a scsi host for the mass storage interface in
> drivers/usb/storage/usb.c
> The scsi host parent device is nothing but the the USB interface device.
> 
> Now, __scsi_init_queue() calls scsi_calculate_bounce_limit() to find out
> and set the block layer bounce limit.
> 
> scsi_calculate_bounce_limit() uses dma_max_pfn(host_dev) to get the bounce_limit.
> 
> host_dev is nothing but the device representing the mass storage interface.
> 
> If that device doesn't have the right dma_pfn_offset, then dma_max_pfn()
> is messed up and the bounce buffer limit is wrong.

I see. The same thing probably happens in the network and mmc subsystems,
which have similar code.

This shows the inconsistencies we have in the handling for bounce buffers
in the kernel, which are sometimes handled by subsystems but sometimes
rely on swiotlb instead. I don't have any better idea than your patch
here, but maybe we should add a comment explaining that next to the
code.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 14:38                                                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 4:04:52 PM CEST Roger Quadros wrote:
> > The main use for it is to let you specify a MAC address for on-board
> > ethernet devices that lack an EPROM, but any other information can be
> > added that way too.
> > 
> >> There is a bug  in the USB core because of which the ISB device and interfaces
> >> do not inherit dma_pfn_offset correctly for which I've sent a patch
> >> https://lkml.org/lkml/2016/8/17/275
> > 
> > I'm a bit skeptical about this. Clearly if we set the dma_mask, we should
> > also set the dma_pfn_offset, but what exactly is this used for in USB
> > devices?
> 
> Consider the mass storage device case.
> USB storage driver creates a scsi host for the mass storage interface in
> drivers/usb/storage/usb.c
> The scsi host parent device is nothing but the the USB interface device.
> 
> Now, __scsi_init_queue() calls scsi_calculate_bounce_limit() to find out
> and set the block layer bounce limit.
> 
> scsi_calculate_bounce_limit() uses dma_max_pfn(host_dev) to get the bounce_limit.
> 
> host_dev is nothing but the device representing the mass storage interface.
> 
> If that device doesn't have the right dma_pfn_offset, then dma_max_pfn()
> is messed up and the bounce buffer limit is wrong.

I see. The same thing probably happens in the network and mmc subsystems,
which have similar code.

This shows the inconsistencies we have in the handling for bounce buffers
in the kernel, which are sometimes handled by subsystems but sometimes
rely on swiotlb instead. I don't have any better idea than your patch
here, but maybe we should add a comment explaining that next to the
code.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 10:24                                                     ` Felipe Balbi
@ 2016-09-07 15:24                                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 15:24 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> 
> [...]
> 
> > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > I think we should replace 
> >
> >         pdev->dev.dma_mask = dev->dma_mask;
> >         pdev->dev.dma_parms = dev->dma_parms;
> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> >
> > with of_dma_configure(), which has the chance to configure more than
> > just those three, as the dma API might look into different aspects:
> >
> > - iommu specific configuration
> > - cache coherency information
> > - bus type
> > - dma offset
> > - dma_map_ops pointer
> >
> > We try to handle everything in of_dma_configure() at configuration
> > time, and that would be the place to add anything else that we might
> > need in the future.
> 
> There are a couple problems with this:
> 
> 1) won't work for PCI-based systems.
> 
> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
> platform (FPGA that appears like a PCI card to host PC)

Right, I was specifically talking about the code in chipidea here,
which I think is never used on the PCI bus, and how the current
code is broken. We can probably do better than of_dma_configure()
(see below), but it would be an improvement.

> 2) not very robust solution
> 
> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
> that's not created by DT. The only reason why this works at all is
> because of the default 32-bit dma mask thing :-) So, how is it any
> different than copying 32-bit dma mask from parent?

The idea here is that you pass in the parent of_node along with the child
device pointer, so it would behave exactly like the parent already does.
The difference is that it also handles all the other attributes besides the mask.

However, to summarize the discussion so far, I agree that
of_dma_configure() is not the solution to these problems, and I think
we can do much better:

Splitting the usb_bus->controller field into the Linux-internal device
(used for the sysfs hierarchy, for printks and for power management)
and a new pointer (used for DMA, DT enumeration and phy lookup) probably
covers all that we really need.

I've prototyped it below, with the dwc3, xhci and chipidea changes
together with the core changes. I've surely made mistakes there and
don't expect it to work out of the box, but this should give an
idea of how I think this can all be solved in the least invasive
way.

I noticed that the gadget interface already has a way to handle the
DMA allocation by device, so I added that in as well.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

 drivers/usb/chipidea/core.c    |  4 ----
 drivers/usb/chipidea/host.c    |  3 ++-
 drivers/usb/chipidea/udc.c     |  8 ++++----
 drivers/usb/core/buffer.c      | 12 ++++++------
 drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++-------------------
 drivers/usb/core/usb.c         | 16 ++++++++--------
 drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
 drivers/usb/dwc3/core.h        |  1 +
 drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
 drivers/usb/dwc3/dwc3-st.c     |  1 -
 drivers/usb/dwc3/ep0.c         |  8 ++++----
 drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
 drivers/usb/dwc3/host.c        | 13 ++++---------
 drivers/usb/host/ehci-fsl.c    |  4 ++--
 drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
 include/linux/usb.h            |  1 +
 include/linux/usb/hcd.h        |  3 +++

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 69426e644d17..dff69837b349 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -833,10 +833,6 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
 	}
 
 	pdev->dev.parent = dev;
-	pdev->dev.dma_mask = dev->dma_mask;
-	pdev->dev.dma_parms = dev->dma_parms;
-	dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
-
 	ret = platform_device_add_resources(pdev, res, nres);
 	if (ret)
 		goto err;
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 053bac9d983c..40d29c4d7772 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -113,7 +113,8 @@ static int host_start(struct ci_hdrc *ci)
 	if (usb_disabled())
 		return -ENODEV;
 
-	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
+	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
+			       ci->dev, dev_name(ci->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 0f692fcda638..4cbfff7934c6 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -424,7 +424,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 
 	hwreq->req.status = -EALREADY;
 
-	ret = usb_gadget_map_request(&ci->gadget, &hwreq->req, hwep->dir);
+	ret = usb_gadget_map_request_by_dev(&ci->dev->parent, &hwreq->req, hwep->dir);
 	if (ret)
 		return ret;
 
@@ -604,7 +604,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 		list_del_init(&node->td);
 	}
 
-	usb_gadget_unmap_request(&hwep->ci->gadget, &hwreq->req, hwep->dir);
+	usb_gadget_unmap_request_by_dev(&hwep->ci->dev->parent, &hwreq->req, hwep->dir);
 
 	hwreq->req.actual += actual;
 
@@ -1898,13 +1898,13 @@ static int udc_start(struct ci_hdrc *ci)
 	INIT_LIST_HEAD(&ci->gadget.ep_list);
 
 	/* alloc resources */
-	ci->qh_pool = dma_pool_create("ci_hw_qh", dev,
+	ci->qh_pool = dma_pool_create("ci_hw_qh", dev->parent,
 				       sizeof(struct ci_hw_qh),
 				       64, CI_HDRC_PAGE_SIZE);
 	if (ci->qh_pool == NULL)
 		return -ENOMEM;
 
-	ci->td_pool = dma_pool_create("ci_hw_td", dev,
+	ci->td_pool = dma_pool_create("ci_hw_td", dev->parent,
 				       sizeof(struct ci_hw_td),
 				       64, CI_HDRC_PAGE_SIZE);
 	if (ci->td_pool == NULL) {
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 98e39f91723a..1e41ef7f3c1f 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -63,7 +63,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 	int		i, size;
 
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!hcd->self.controller->dma_mask &&
+	    (!hcd->self.sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM)))
 		return 0;
 
@@ -72,7 +72,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 		if (!size)
 			continue;
 		snprintf(name, sizeof(name), "buffer-%d", size);
-		hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
+		hcd->pool[i] = dma_pool_create(name, hcd->self.sysdev,
 				size, size, 0);
 		if (!hcd->pool[i]) {
 			hcd_buffer_destroy(hcd);
@@ -127,7 +127,7 @@ void *hcd_buffer_alloc(
 
 	/* some USB hosts just use PIO */
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!bus->controller->dma_mask &&
+	    (!bus->sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
 		*dma = ~(dma_addr_t) 0;
 		return kmalloc(size, mem_flags);
@@ -137,7 +137,7 @@ void *hcd_buffer_alloc(
 		if (size <= pool_max[i])
 			return dma_pool_alloc(hcd->pool[i], mem_flags, dma);
 	}
-	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
+	return dma_alloc_coherent(hcd->self.sysdev, size, dma, mem_flags);
 }
 
 void hcd_buffer_free(
@@ -154,7 +154,7 @@ void hcd_buffer_free(
 		return;
 
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!bus->controller->dma_mask &&
+	    (!bus->sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
 		kfree(addr);
 		return;
@@ -166,5 +166,5 @@ void hcd_buffer_free(
 			return;
 		}
 	}
-	dma_free_coherent(hcd->self.controller, size, addr, dma);
+	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
 }
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 746c47d86cf5..70d48941f8f4 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1072,6 +1072,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
 static int register_root_hub(struct usb_hcd *hcd)
 {
 	struct device *parent_dev = hcd->self.controller;
+	struct device *sysdev = hcd->self.sysdev;
 	struct usb_device *usb_dev = hcd->self.root_hub;
 	const int devnum = 1;
 	int retval;
@@ -1118,7 +1119,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 		/* Did the HC die before the root hub was registered? */
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
-		usb_dev->dev.of_node = parent_dev->of_node;
+		usb_dev->dev.of_node = sysdev->of_node;
 	}
 	mutex_unlock(&usb_bus_idr_lock);
 
@@ -1464,19 +1465,19 @@ void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 	if (IS_ENABLED(CONFIG_HAS_DMA) &&
 	    (urb->transfer_flags & URB_DMA_MAP_SG))
-		dma_unmap_sg(hcd->self.controller,
+		dma_unmap_sg(hcd->self.sysdev,
 				urb->sg,
 				urb->num_sgs,
 				dir);
 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
 		 (urb->transfer_flags & URB_DMA_MAP_PAGE))
-		dma_unmap_page(hcd->self.controller,
+		dma_unmap_page(hcd->self.sysdev,
 				urb->transfer_dma,
 				urb->transfer_buffer_length,
 				dir);
 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
 		 (urb->transfer_flags & URB_DMA_MAP_SINGLE))
-		dma_unmap_single(hcd->self.controller,
+		dma_unmap_single(hcd->self.sysdev,
 				urb->transfer_dma,
 				urb->transfer_buffer_length,
 				dir);
@@ -1519,11 +1520,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 			return ret;
 		if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
 			urb->setup_dma = dma_map_single(
-					hcd->self.controller,
+					hcd->self.sysdev,
 					urb->setup_packet,
 					sizeof(struct usb_ctrlrequest),
 					DMA_TO_DEVICE);
-			if (dma_mapping_error(hcd->self.controller,
+			if (dma_mapping_error(hcd->self.sysdev,
 						urb->setup_dma))
 				return -EAGAIN;
 			urb->transfer_flags |= URB_SETUP_MAP_SINGLE;
@@ -1554,7 +1555,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 				}
 
 				n = dma_map_sg(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						urb->sg,
 						urb->num_sgs,
 						dir);
@@ -1569,12 +1570,12 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 			} else if (urb->sg) {
 				struct scatterlist *sg = urb->sg;
 				urb->transfer_dma = dma_map_page(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						sg_page(sg),
 						sg->offset,
 						urb->transfer_buffer_length,
 						dir);
-				if (dma_mapping_error(hcd->self.controller,
+				if (dma_mapping_error(hcd->self.sysdev,
 						urb->transfer_dma))
 					ret = -EAGAIN;
 				else
@@ -1584,11 +1585,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 				ret = -EAGAIN;
 			} else {
 				urb->transfer_dma = dma_map_single(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						urb->transfer_buffer,
 						urb->transfer_buffer_length,
 						dir);
-				if (dma_mapping_error(hcd->self.controller,
+				if (dma_mapping_error(hcd->self.sysdev,
 						urb->transfer_dma))
 					ret = -EAGAIN;
 				else
@@ -2510,8 +2511,8 @@ static void init_giveback_urb_bh(struct giveback_urb_bh *bh)
  * Return: On success, a pointer to the created and initialized HCD structure.
  * On failure (e.g. if memory is unavailable), %NULL.
  */
-struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
-		struct device *dev, const char *bus_name,
+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
+		struct device *sysdev, struct device *dev, const char *bus_name,
 		struct usb_hcd *primary_hcd)
 {
 	struct usb_hcd *hcd;
@@ -2552,8 +2553,9 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 
 	usb_bus_init(&hcd->self);
 	hcd->self.controller = dev;
+	hcd->self.sysdev = sysdev;
 	hcd->self.bus_name = bus_name;
-	hcd->self.uses_dma = (dev->dma_mask != NULL);
+	hcd->self.uses_dma = (sysdev->dma_mask != NULL);
 
 	init_timer(&hcd->rh_timer);
 	hcd->rh_timer.function = rh_timer_func;
@@ -2568,6 +2570,14 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 			"USB Host Controller";
 	return hcd;
 }
+EXPORT_SYMBOL_GPL(__usb_create_hcd);
+
+struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
+		struct device *dev, const char *bus_name,
+		struct usb_hcd *primary_hcd)
+{
+	return __usb_create_hcd(driver, dev, dev, bus_name, primary_hcd);
+}
 EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
 
 /**
@@ -2587,7 +2597,7 @@ EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
 struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
 		struct device *dev, const char *bus_name)
 {
-	return usb_create_shared_hcd(driver, dev, bus_name, NULL);
+	return __usb_create_hcd(driver, dev, dev, bus_name, NULL);
 }
 EXPORT_SYMBOL_GPL(usb_create_hcd);
 
@@ -2714,7 +2724,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	struct usb_device *rhdev;
 
 	if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
-		struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
+		struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
 
 		if (IS_ERR(phy)) {
 			retval = PTR_ERR(phy);
@@ -2732,7 +2742,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	}
 
 	if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
-		struct phy *phy = phy_get(hcd->self.controller, "usb");
+		struct phy *phy = phy_get(hcd->self.sysdev, "usb");
 
 		if (IS_ERR(phy)) {
 			retval = PTR_ERR(phy);
@@ -2780,7 +2790,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	 */
 	retval = hcd_buffer_create(hcd);
 	if (retval != 0) {
-		dev_dbg(hcd->self.controller, "pool alloc failed\n");
+		dev_dbg(hcd->self.sysdev, "pool alloc failed\n");
 		goto err_create_buf;
 	}
 
@@ -2790,7 +2800,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
 	rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
 	if (rhdev == NULL) {
-		dev_err(hcd->self.controller, "unable to allocate root hub\n");
+		dev_err(hcd->self.sysdev, "unable to allocate root hub\n");
 		retval = -ENOMEM;
 		goto err_allocate_root_hub;
 	}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 5e80697ef952..199f67ae8857 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -440,8 +440,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	dev->dev.bus = &usb_bus_type;
 	dev->dev.type = &usb_device_type;
 	dev->dev.groups = usb_device_groups;
-	dev->dev.dma_mask = bus->controller->dma_mask;
-	set_dev_node(&dev->dev, dev_to_node(bus->controller));
+	dev->dev.dma_mask = bus->sysdev->dma_mask;
+	set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
 	dev->state = USB_STATE_ATTACHED;
 	dev->lpm_disable_count = 1;
 	atomic_set(&dev->urbnum, 0);
@@ -789,7 +789,7 @@ struct urb *usb_buffer_map(struct urb *urb)
 	if (!urb
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return NULL;
 
 	if (controller->dma_mask) {
@@ -827,7 +827,7 @@ void usb_buffer_dmasync(struct urb *urb)
 			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return;
 
 	if (controller->dma_mask) {
@@ -861,7 +861,7 @@ void usb_buffer_unmap(struct urb *urb)
 			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return;
 
 	if (controller->dma_mask) {
@@ -911,7 +911,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return -EINVAL;
 
@@ -947,7 +947,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return;
 
@@ -975,7 +975,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return;
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 35d092456bec..08db66c64c66 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/pci.h>
 #include <linux/pm_runtime.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
 		struct dwc3_event_buffer *evt)
 {
-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
+	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
 }
 
 /**
@@ -200,7 +201,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 
 	evt->dwc	= dwc;
 	evt->length	= length;
-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
+	evt->buf	= dma_alloc_coherent(dwc->sysdev, length,
 			&evt->dma, GFP_KERNEL);
 	if (!evt->buf)
 		return ERR_PTR(-ENOMEM);
@@ -319,11 +320,11 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
 	if (!WARN_ON(dwc->scratchbuf))
 		return 0;
 
-	scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
+	scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
 			dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
 			DMA_BIDIRECTIONAL);
-	if (dma_mapping_error(dwc->dev, scratch_addr)) {
-		dev_err(dwc->dev, "failed to map scratch buffer\n");
+	if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
+		dev_err(dwc->sysdev, "failed to map scratch buffer\n");
 		ret = -EFAULT;
 		goto err0;
 	}
@@ -347,7 +348,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
 	return 0;
 
 err1:
-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 
 err0:
@@ -366,7 +367,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
 	if (!WARN_ON(dwc->scratchbuf))
 		return;
 
-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 	kfree(dwc->scratchbuf);
 }
@@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
 	dwc->mem = mem;
 	dwc->dev = dev;
+#ifdef CONFIG_PCI
+	/* TODO: or some other way of detecting this? */
+	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
+		dwc->sysdev = dwc->dev->parent;
+	else
+#endif
+		dwc->sysdev = dwc->dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -949,12 +957,6 @@ static int dwc3_probe(struct platform_device *pdev)
 
 	spin_lock_init(&dwc->lock);
 
-	if (!dev->dma_mask) {
-		dev->dma_mask = dev->parent->dma_mask;
-		dev->dma_parms = dev->parent->dma_parms;
-		dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
-	}
-
 	pm_runtime_set_active(dev);
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 45d6de5107c7..2fbc92143ab9 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -823,6 +823,7 @@ struct dwc3 {
 	spinlock_t		lock;
 
 	struct device		*dev;
+	struct device		*sysdev;
 
 	struct platform_device	*xhci;
 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index 2f1fb7e7aa54..e27899bb5706 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/usb_phy_generic.h>
@@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
 	if (!exynos)
 		return -ENOMEM;
 
-	/*
-	 * Right now device-tree probed devices don't get dma_mask set.
-	 * Since shared usb code relies on it, set it here for now.
-	 * Once we move to full device tree support this will vanish off.
-	 */
-	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
 	platform_set_drvdata(pdev, exynos);
 
 	exynos->dev	= dev;
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index 89a2f712fdfe..4d7439cb8cd8 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
 	dwc3_data->dev = dev;
 	dwc3_data->regmap = regmap;
 
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index ae4c5e89c134..9cda9ee91b9d 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -974,8 +974,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 		u32	transfer_size = 0;
 		u32	maxpacket;
 
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-				dep->number);
+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+				&req->request, dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
 			return;
@@ -1002,8 +1002,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 				dwc->ep0_bounce_addr, transfer_size,
 				DWC3_TRBCTL_CONTROL_DATA, false);
 	} else {
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-				dep->number);
+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+				&req->request, dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
 			return;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 122e64df2f4d..77d62ce4547f 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -192,8 +192,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (dwc->ep0_bounced && dep->number == 0)
 		dwc->ep0_bounced = false;
 	else
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
-				req->direction);
+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
+				&req->request, req->direction);
 
 	trace_dwc3_gadget_giveback(req);
 
@@ -371,7 +371,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 	if (dep->trb_pool)
 		return 0;
 
-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
+	dep->trb_pool = dma_alloc_coherent(dwc->sysdev,
 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			&dep->trb_pool_dma, GFP_KERNEL);
 	if (!dep->trb_pool) {
@@ -387,7 +387,7 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
 	struct dwc3		*dwc = dep->dwc;
 
-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+	dma_free_coherent(dwc->sysdev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			dep->trb_pool, dep->trb_pool_dma);
 
 	dep->trb_pool = NULL;
@@ -1027,8 +1027,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
 		 * here and stop, unmap, free and del each of the linked
 		 * requests instead of what we do now.
 		 */
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
-				req->direction);
+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
+				&req->request, req->direction);
 		list_del(&req->list);
 		return ret;
 	}
@@ -1113,8 +1113,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * This will also avoid Host cancelling URBs due to too
 	 * many NAKs.
 	 */
-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-			dep->direction);
+	ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+		&req->request, dep->direction);
 	if (ret)
 		return ret;
 
@@ -2953,7 +2953,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 
 	dwc->irq_gadget = irq;
 
-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dwc->ctrl_req = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			&dwc->ctrl_req_addr, GFP_KERNEL);
 	if (!dwc->ctrl_req) {
 		dev_err(dwc->dev, "failed to allocate ctrl request\n");
@@ -2961,7 +2961,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err0;
 	}
 
-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+	dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2,
 			&dwc->ep0_trb_addr, GFP_KERNEL);
 	if (!dwc->ep0_trb) {
 		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
@@ -2975,7 +2975,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err2;
 	}
 
-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
+	dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev,
 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
 			GFP_KERNEL);
 	if (!dwc->ep0_bounce) {
@@ -3047,18 +3047,18 @@ err5:
 
 err4:
 	dwc3_gadget_free_endpoints(dwc);
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
 	kfree(dwc->setup_buf);
 
 err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 
 err0:
@@ -3073,16 +3073,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
 	dwc3_gadget_free_endpoints(dwc);
 
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 	kfree(dwc->setup_buf);
 	kfree(dwc->zlp_buf);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 }
 
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index f6533c68fed1..3c078e85fa98 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -72,12 +72,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 		return -ENOMEM;
 	}
 
-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
-
 	xhci->dev.parent	= dwc->dev;
-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
-
 	dwc->xhci = xhci;
 
 	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
@@ -112,9 +107,9 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err2:
 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
-			  dev_name(&xhci->dev));
+			  dev_name(dwc->dev));
 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
-			  dev_name(&xhci->dev));
+			  dev_name(dwc->dev));
 err1:
 	platform_device_put(xhci);
 	return ret;
@@ -123,8 +118,8 @@ err1:
 void dwc3_host_exit(struct dwc3 *dwc)
 {
 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
-			  dev_name(&dwc->xhci->dev));
+			  dev_name(dwc->dev));
 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
-			  dev_name(&dwc->xhci->dev));
+			  dev_name(dwc->dev));
 	platform_device_unregister(dwc->xhci);
 }
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9f5ffb629973..b2419950221f 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
 	}
 	irq = res->start;
 
-	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
-				dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
+				&pdev->dev, dev_name(&pdev->dev), NULL);
 	if (!hcd) {
 		retval = -ENOMEM;
 		goto err1;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ed56bf9ed885..c1d69e14432d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/usb/phy.h>
@@ -139,6 +140,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	const struct hc_driver	*driver;
+	struct device		*sysdev;
 	struct xhci_hcd		*xhci;
 	struct resource         *res;
 	struct usb_hcd		*hcd;
@@ -155,22 +157,38 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
+	/*
+	 * sysdev must point to a device that is known to the system firmware
+	 * or PCI hardware. We handle these three cases here:
+	 * 1. xhci_plat comes from firmware
+	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
+	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
+	 */
+	sysdev = &pdev->dev;
+	if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node)
+		sysdev = sysdev->parent;
+#ifdef CONFIG_PCI
+	else if (sysdev->parent && sysdev->parent->parent &&
+		 sysdev->parent->parent->bus == &pci_bus_type)
+		sysdev = sysdev->parent->parent;
+#endif
+
 	/* Try to set 64-bit DMA first */
-	if (WARN_ON(!pdev->dev.dma_mask))
+	if (WARN_ON(!sysdev->dma_mask))
 		/* Platform did not initialize dma_mask */
-		ret = dma_coerce_mask_and_coherent(&pdev->dev,
+		ret = dma_coerce_mask_and_coherent(sysdev,
 						   DMA_BIT_MASK(64));
 	else
-		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
 
 	/* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
 	if (ret) {
-		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
 		if (ret)
 			return ret;
 	}
 
-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, dev_name(&pdev->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
@@ -220,13 +238,13 @@ static int xhci_plat_probe(struct platform_device *pdev)
 		goto disable_clk;
 	}
 
-	if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
+	if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
 		xhci->quirks |= XHCI_LPM_SUPPORT;
 
 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
 		xhci->shared_hcd->can_do_streams = 1;
 
-	hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
 	if (IS_ERR(hcd->usb_phy)) {
 		ret = PTR_ERR(hcd->usb_phy);
 		if (ret == -EPROBE_DEFER)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index eba1f10e8cfd..f3f5d8a396e4 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -354,6 +354,7 @@ struct usb_devmap {
  */
 struct usb_bus {
 	struct device *controller;	/* host/master side hardware */
+	struct device *sysdev;		/* as seen from firmware or bus */
 	int busnum;			/* Bus number (in order of reg) */
 	const char *bus_name;		/* stable id (PCI slot_name etc) */
 	u8 uses_dma;			/* Does the host controller use DMA? */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 66fc13705ab7..3860560a61bb 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -437,6 +437,9 @@ extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
 		struct usb_host_interface *new_alt);
 extern int usb_hcd_get_frame_number(struct usb_device *udev);
 
+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
+		struct device *sysdev, struct device *dev, const char *bus_name,
+		struct usb_hcd *primary_hcd);
 extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
 		struct device *dev, const char *bus_name);
 extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 15:24                                                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
> 
> [...]
> 
> > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > I think we should replace 
> >
> >         pdev->dev.dma_mask = dev->dma_mask;
> >         pdev->dev.dma_parms = dev->dma_parms;
> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> >
> > with of_dma_configure(), which has the chance to configure more than
> > just those three, as the dma API might look into different aspects:
> >
> > - iommu specific configuration
> > - cache coherency information
> > - bus type
> > - dma offset
> > - dma_map_ops pointer
> >
> > We try to handle everything in of_dma_configure() at configuration
> > time, and that would be the place to add anything else that we might
> > need in the future.
> 
> There are a couple problems with this:
> 
> 1) won't work for PCI-based systems.
> 
> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
> platform (FPGA that appears like a PCI card to host PC)

Right, I was specifically talking about the code in chipidea here,
which I think is never used on the PCI bus, and how the current
code is broken. We can probably do better than of_dma_configure()
(see below), but it would be an improvement.

> 2) not very robust solution
> 
> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
> that's not created by DT. The only reason why this works at all is
> because of the default 32-bit dma mask thing :-) So, how is it any
> different than copying 32-bit dma mask from parent?

The idea here is that you pass in the parent of_node along with the child
device pointer, so it would behave exactly like the parent already does.
The difference is that it also handles all the other attributes besides the mask.

However, to summarize the discussion so far, I agree that
of_dma_configure() is not the solution to these problems, and I think
we can do much better:

Splitting the usb_bus->controller field into the Linux-internal device
(used for the sysfs hierarchy, for printks and for power management)
and a new pointer (used for DMA, DT enumeration and phy lookup) probably
covers all that we really need.

I've prototyped it below, with the dwc3, xhci and chipidea changes
together with the core changes. I've surely made mistakes there and
don't expect it to work out of the box, but this should give an
idea of how I think this can all be solved in the least invasive
way.

I noticed that the gadget interface already has a way to handle the
DMA allocation by device, so I added that in as well.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

 drivers/usb/chipidea/core.c    |  4 ----
 drivers/usb/chipidea/host.c    |  3 ++-
 drivers/usb/chipidea/udc.c     |  8 ++++----
 drivers/usb/core/buffer.c      | 12 ++++++------
 drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++-------------------
 drivers/usb/core/usb.c         | 16 ++++++++--------
 drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
 drivers/usb/dwc3/core.h        |  1 +
 drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
 drivers/usb/dwc3/dwc3-st.c     |  1 -
 drivers/usb/dwc3/ep0.c         |  8 ++++----
 drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
 drivers/usb/dwc3/host.c        | 13 ++++---------
 drivers/usb/host/ehci-fsl.c    |  4 ++--
 drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
 include/linux/usb.h            |  1 +
 include/linux/usb/hcd.h        |  3 +++

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 69426e644d17..dff69837b349 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -833,10 +833,6 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
 	}
 
 	pdev->dev.parent = dev;
-	pdev->dev.dma_mask = dev->dma_mask;
-	pdev->dev.dma_parms = dev->dma_parms;
-	dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
-
 	ret = platform_device_add_resources(pdev, res, nres);
 	if (ret)
 		goto err;
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 053bac9d983c..40d29c4d7772 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -113,7 +113,8 @@ static int host_start(struct ci_hdrc *ci)
 	if (usb_disabled())
 		return -ENODEV;
 
-	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
+	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
+			       ci->dev, dev_name(ci->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 0f692fcda638..4cbfff7934c6 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -424,7 +424,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 
 	hwreq->req.status = -EALREADY;
 
-	ret = usb_gadget_map_request(&ci->gadget, &hwreq->req, hwep->dir);
+	ret = usb_gadget_map_request_by_dev(&ci->dev->parent, &hwreq->req, hwep->dir);
 	if (ret)
 		return ret;
 
@@ -604,7 +604,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 		list_del_init(&node->td);
 	}
 
-	usb_gadget_unmap_request(&hwep->ci->gadget, &hwreq->req, hwep->dir);
+	usb_gadget_unmap_request_by_dev(&hwep->ci->dev->parent, &hwreq->req, hwep->dir);
 
 	hwreq->req.actual += actual;
 
@@ -1898,13 +1898,13 @@ static int udc_start(struct ci_hdrc *ci)
 	INIT_LIST_HEAD(&ci->gadget.ep_list);
 
 	/* alloc resources */
-	ci->qh_pool = dma_pool_create("ci_hw_qh", dev,
+	ci->qh_pool = dma_pool_create("ci_hw_qh", dev->parent,
 				       sizeof(struct ci_hw_qh),
 				       64, CI_HDRC_PAGE_SIZE);
 	if (ci->qh_pool == NULL)
 		return -ENOMEM;
 
-	ci->td_pool = dma_pool_create("ci_hw_td", dev,
+	ci->td_pool = dma_pool_create("ci_hw_td", dev->parent,
 				       sizeof(struct ci_hw_td),
 				       64, CI_HDRC_PAGE_SIZE);
 	if (ci->td_pool == NULL) {
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 98e39f91723a..1e41ef7f3c1f 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -63,7 +63,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 	int		i, size;
 
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!hcd->self.controller->dma_mask &&
+	    (!hcd->self.sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM)))
 		return 0;
 
@@ -72,7 +72,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
 		if (!size)
 			continue;
 		snprintf(name, sizeof(name), "buffer-%d", size);
-		hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
+		hcd->pool[i] = dma_pool_create(name, hcd->self.sysdev,
 				size, size, 0);
 		if (!hcd->pool[i]) {
 			hcd_buffer_destroy(hcd);
@@ -127,7 +127,7 @@ void *hcd_buffer_alloc(
 
 	/* some USB hosts just use PIO */
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!bus->controller->dma_mask &&
+	    (!bus->sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
 		*dma = ~(dma_addr_t) 0;
 		return kmalloc(size, mem_flags);
@@ -137,7 +137,7 @@ void *hcd_buffer_alloc(
 		if (size <= pool_max[i])
 			return dma_pool_alloc(hcd->pool[i], mem_flags, dma);
 	}
-	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
+	return dma_alloc_coherent(hcd->self.sysdev, size, dma, mem_flags);
 }
 
 void hcd_buffer_free(
@@ -154,7 +154,7 @@ void hcd_buffer_free(
 		return;
 
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
-	    (!bus->controller->dma_mask &&
+	    (!bus->sysdev->dma_mask &&
 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
 		kfree(addr);
 		return;
@@ -166,5 +166,5 @@ void hcd_buffer_free(
 			return;
 		}
 	}
-	dma_free_coherent(hcd->self.controller, size, addr, dma);
+	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
 }
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 746c47d86cf5..70d48941f8f4 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1072,6 +1072,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
 static int register_root_hub(struct usb_hcd *hcd)
 {
 	struct device *parent_dev = hcd->self.controller;
+	struct device *sysdev = hcd->self.sysdev;
 	struct usb_device *usb_dev = hcd->self.root_hub;
 	const int devnum = 1;
 	int retval;
@@ -1118,7 +1119,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 		/* Did the HC die before the root hub was registered? */
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
-		usb_dev->dev.of_node = parent_dev->of_node;
+		usb_dev->dev.of_node = sysdev->of_node;
 	}
 	mutex_unlock(&usb_bus_idr_lock);
 
@@ -1464,19 +1465,19 @@ void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 	if (IS_ENABLED(CONFIG_HAS_DMA) &&
 	    (urb->transfer_flags & URB_DMA_MAP_SG))
-		dma_unmap_sg(hcd->self.controller,
+		dma_unmap_sg(hcd->self.sysdev,
 				urb->sg,
 				urb->num_sgs,
 				dir);
 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
 		 (urb->transfer_flags & URB_DMA_MAP_PAGE))
-		dma_unmap_page(hcd->self.controller,
+		dma_unmap_page(hcd->self.sysdev,
 				urb->transfer_dma,
 				urb->transfer_buffer_length,
 				dir);
 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
 		 (urb->transfer_flags & URB_DMA_MAP_SINGLE))
-		dma_unmap_single(hcd->self.controller,
+		dma_unmap_single(hcd->self.sysdev,
 				urb->transfer_dma,
 				urb->transfer_buffer_length,
 				dir);
@@ -1519,11 +1520,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 			return ret;
 		if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
 			urb->setup_dma = dma_map_single(
-					hcd->self.controller,
+					hcd->self.sysdev,
 					urb->setup_packet,
 					sizeof(struct usb_ctrlrequest),
 					DMA_TO_DEVICE);
-			if (dma_mapping_error(hcd->self.controller,
+			if (dma_mapping_error(hcd->self.sysdev,
 						urb->setup_dma))
 				return -EAGAIN;
 			urb->transfer_flags |= URB_SETUP_MAP_SINGLE;
@@ -1554,7 +1555,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 				}
 
 				n = dma_map_sg(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						urb->sg,
 						urb->num_sgs,
 						dir);
@@ -1569,12 +1570,12 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 			} else if (urb->sg) {
 				struct scatterlist *sg = urb->sg;
 				urb->transfer_dma = dma_map_page(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						sg_page(sg),
 						sg->offset,
 						urb->transfer_buffer_length,
 						dir);
-				if (dma_mapping_error(hcd->self.controller,
+				if (dma_mapping_error(hcd->self.sysdev,
 						urb->transfer_dma))
 					ret = -EAGAIN;
 				else
@@ -1584,11 +1585,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 				ret = -EAGAIN;
 			} else {
 				urb->transfer_dma = dma_map_single(
-						hcd->self.controller,
+						hcd->self.sysdev,
 						urb->transfer_buffer,
 						urb->transfer_buffer_length,
 						dir);
-				if (dma_mapping_error(hcd->self.controller,
+				if (dma_mapping_error(hcd->self.sysdev,
 						urb->transfer_dma))
 					ret = -EAGAIN;
 				else
@@ -2510,8 +2511,8 @@ static void init_giveback_urb_bh(struct giveback_urb_bh *bh)
  * Return: On success, a pointer to the created and initialized HCD structure.
  * On failure (e.g. if memory is unavailable), %NULL.
  */
-struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
-		struct device *dev, const char *bus_name,
+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
+		struct device *sysdev, struct device *dev, const char *bus_name,
 		struct usb_hcd *primary_hcd)
 {
 	struct usb_hcd *hcd;
@@ -2552,8 +2553,9 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 
 	usb_bus_init(&hcd->self);
 	hcd->self.controller = dev;
+	hcd->self.sysdev = sysdev;
 	hcd->self.bus_name = bus_name;
-	hcd->self.uses_dma = (dev->dma_mask != NULL);
+	hcd->self.uses_dma = (sysdev->dma_mask != NULL);
 
 	init_timer(&hcd->rh_timer);
 	hcd->rh_timer.function = rh_timer_func;
@@ -2568,6 +2570,14 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 			"USB Host Controller";
 	return hcd;
 }
+EXPORT_SYMBOL_GPL(__usb_create_hcd);
+
+struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
+		struct device *dev, const char *bus_name,
+		struct usb_hcd *primary_hcd)
+{
+	return __usb_create_hcd(driver, dev, dev, bus_name, primary_hcd);
+}
 EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
 
 /**
@@ -2587,7 +2597,7 @@ EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
 struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
 		struct device *dev, const char *bus_name)
 {
-	return usb_create_shared_hcd(driver, dev, bus_name, NULL);
+	return __usb_create_hcd(driver, dev, dev, bus_name, NULL);
 }
 EXPORT_SYMBOL_GPL(usb_create_hcd);
 
@@ -2714,7 +2724,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	struct usb_device *rhdev;
 
 	if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
-		struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
+		struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
 
 		if (IS_ERR(phy)) {
 			retval = PTR_ERR(phy);
@@ -2732,7 +2742,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	}
 
 	if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
-		struct phy *phy = phy_get(hcd->self.controller, "usb");
+		struct phy *phy = phy_get(hcd->self.sysdev, "usb");
 
 		if (IS_ERR(phy)) {
 			retval = PTR_ERR(phy);
@@ -2780,7 +2790,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	 */
 	retval = hcd_buffer_create(hcd);
 	if (retval != 0) {
-		dev_dbg(hcd->self.controller, "pool alloc failed\n");
+		dev_dbg(hcd->self.sysdev, "pool alloc failed\n");
 		goto err_create_buf;
 	}
 
@@ -2790,7 +2800,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
 	rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
 	if (rhdev == NULL) {
-		dev_err(hcd->self.controller, "unable to allocate root hub\n");
+		dev_err(hcd->self.sysdev, "unable to allocate root hub\n");
 		retval = -ENOMEM;
 		goto err_allocate_root_hub;
 	}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 5e80697ef952..199f67ae8857 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -440,8 +440,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	dev->dev.bus = &usb_bus_type;
 	dev->dev.type = &usb_device_type;
 	dev->dev.groups = usb_device_groups;
-	dev->dev.dma_mask = bus->controller->dma_mask;
-	set_dev_node(&dev->dev, dev_to_node(bus->controller));
+	dev->dev.dma_mask = bus->sysdev->dma_mask;
+	set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
 	dev->state = USB_STATE_ATTACHED;
 	dev->lpm_disable_count = 1;
 	atomic_set(&dev->urbnum, 0);
@@ -789,7 +789,7 @@ struct urb *usb_buffer_map(struct urb *urb)
 	if (!urb
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return NULL;
 
 	if (controller->dma_mask) {
@@ -827,7 +827,7 @@ void usb_buffer_dmasync(struct urb *urb)
 			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return;
 
 	if (controller->dma_mask) {
@@ -861,7 +861,7 @@ void usb_buffer_unmap(struct urb *urb)
 			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->sysdev))
 		return;
 
 	if (controller->dma_mask) {
@@ -911,7 +911,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return -EINVAL;
 
@@ -947,7 +947,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return;
 
@@ -975,7 +975,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in,
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller)
+			|| !(controller = bus->sysdev)
 			|| !controller->dma_mask)
 		return;
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 35d092456bec..08db66c64c66 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/pci.h>
 #include <linux/pm_runtime.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
 		struct dwc3_event_buffer *evt)
 {
-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
+	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
 }
 
 /**
@@ -200,7 +201,7 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 
 	evt->dwc	= dwc;
 	evt->length	= length;
-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
+	evt->buf	= dma_alloc_coherent(dwc->sysdev, length,
 			&evt->dma, GFP_KERNEL);
 	if (!evt->buf)
 		return ERR_PTR(-ENOMEM);
@@ -319,11 +320,11 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
 	if (!WARN_ON(dwc->scratchbuf))
 		return 0;
 
-	scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
+	scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
 			dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
 			DMA_BIDIRECTIONAL);
-	if (dma_mapping_error(dwc->dev, scratch_addr)) {
-		dev_err(dwc->dev, "failed to map scratch buffer\n");
+	if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
+		dev_err(dwc->sysdev, "failed to map scratch buffer\n");
 		ret = -EFAULT;
 		goto err0;
 	}
@@ -347,7 +348,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
 	return 0;
 
 err1:
-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 
 err0:
@@ -366,7 +367,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
 	if (!WARN_ON(dwc->scratchbuf))
 		return;
 
-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 	kfree(dwc->scratchbuf);
 }
@@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
 	dwc->mem = mem;
 	dwc->dev = dev;
+#ifdef CONFIG_PCI
+	/* TODO: or some other way of detecting this? */
+	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
+		dwc->sysdev = dwc->dev->parent;
+	else
+#endif
+		dwc->sysdev = dwc->dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -949,12 +957,6 @@ static int dwc3_probe(struct platform_device *pdev)
 
 	spin_lock_init(&dwc->lock);
 
-	if (!dev->dma_mask) {
-		dev->dma_mask = dev->parent->dma_mask;
-		dev->dma_parms = dev->parent->dma_parms;
-		dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
-	}
-
 	pm_runtime_set_active(dev);
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 45d6de5107c7..2fbc92143ab9 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -823,6 +823,7 @@ struct dwc3 {
 	spinlock_t		lock;
 
 	struct device		*dev;
+	struct device		*sysdev;
 
 	struct platform_device	*xhci;
 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
index 2f1fb7e7aa54..e27899bb5706 100644
--- a/drivers/usb/dwc3/dwc3-exynos.c
+++ b/drivers/usb/dwc3/dwc3-exynos.c
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/usb_phy_generic.h>
@@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
 	if (!exynos)
 		return -ENOMEM;
 
-	/*
-	 * Right now device-tree probed devices don't get dma_mask set.
-	 * Since shared usb code relies on it, set it here for now.
-	 * Once we move to full device tree support this will vanish off.
-	 */
-	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-
 	platform_set_drvdata(pdev, exynos);
 
 	exynos->dev	= dev;
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index 89a2f712fdfe..4d7439cb8cd8 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
 	dwc3_data->dev = dev;
 	dwc3_data->regmap = regmap;
 
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index ae4c5e89c134..9cda9ee91b9d 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -974,8 +974,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 		u32	transfer_size = 0;
 		u32	maxpacket;
 
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-				dep->number);
+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+				&req->request, dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
 			return;
@@ -1002,8 +1002,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 				dwc->ep0_bounce_addr, transfer_size,
 				DWC3_TRBCTL_CONTROL_DATA, false);
 	} else {
-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-				dep->number);
+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+				&req->request, dep->number);
 		if (ret) {
 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
 			return;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 122e64df2f4d..77d62ce4547f 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -192,8 +192,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (dwc->ep0_bounced && dep->number == 0)
 		dwc->ep0_bounced = false;
 	else
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
-				req->direction);
+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
+				&req->request, req->direction);
 
 	trace_dwc3_gadget_giveback(req);
 
@@ -371,7 +371,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 	if (dep->trb_pool)
 		return 0;
 
-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
+	dep->trb_pool = dma_alloc_coherent(dwc->sysdev,
 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			&dep->trb_pool_dma, GFP_KERNEL);
 	if (!dep->trb_pool) {
@@ -387,7 +387,7 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
 	struct dwc3		*dwc = dep->dwc;
 
-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+	dma_free_coherent(dwc->sysdev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
 			dep->trb_pool, dep->trb_pool_dma);
 
 	dep->trb_pool = NULL;
@@ -1027,8 +1027,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
 		 * here and stop, unmap, free and del each of the linked
 		 * requests instead of what we do now.
 		 */
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
-				req->direction);
+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
+				&req->request, req->direction);
 		list_del(&req->list);
 		return ret;
 	}
@@ -1113,8 +1113,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * This will also avoid Host cancelling URBs due to too
 	 * many NAKs.
 	 */
-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
-			dep->direction);
+	ret = usb_gadget_map_request_by_dev(dwc->sysdev,
+		&req->request, dep->direction);
 	if (ret)
 		return ret;
 
@@ -2953,7 +2953,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 
 	dwc->irq_gadget = irq;
 
-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dwc->ctrl_req = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			&dwc->ctrl_req_addr, GFP_KERNEL);
 	if (!dwc->ctrl_req) {
 		dev_err(dwc->dev, "failed to allocate ctrl request\n");
@@ -2961,7 +2961,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err0;
 	}
 
-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+	dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2,
 			&dwc->ep0_trb_addr, GFP_KERNEL);
 	if (!dwc->ep0_trb) {
 		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
@@ -2975,7 +2975,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 		goto err2;
 	}
 
-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
+	dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev,
 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
 			GFP_KERNEL);
 	if (!dwc->ep0_bounce) {
@@ -3047,18 +3047,18 @@ err5:
 
 err4:
 	dwc3_gadget_free_endpoints(dwc);
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
 	kfree(dwc->setup_buf);
 
 err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 
 err0:
@@ -3073,16 +3073,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
 	dwc3_gadget_free_endpoints(dwc);
 
-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 	kfree(dwc->setup_buf);
 	kfree(dwc->zlp_buf);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
 			dwc->ep0_trb, dwc->ep0_trb_addr);
 
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
 			dwc->ctrl_req, dwc->ctrl_req_addr);
 }
 
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index f6533c68fed1..3c078e85fa98 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -72,12 +72,7 @@ int dwc3_host_init(struct dwc3 *dwc)
 		return -ENOMEM;
 	}
 
-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
-
 	xhci->dev.parent	= dwc->dev;
-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
-
 	dwc->xhci = xhci;
 
 	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
@@ -112,9 +107,9 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err2:
 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
-			  dev_name(&xhci->dev));
+			  dev_name(dwc->dev));
 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
-			  dev_name(&xhci->dev));
+			  dev_name(dwc->dev));
 err1:
 	platform_device_put(xhci);
 	return ret;
@@ -123,8 +118,8 @@ err1:
 void dwc3_host_exit(struct dwc3 *dwc)
 {
 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
-			  dev_name(&dwc->xhci->dev));
+			  dev_name(dwc->dev));
 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
-			  dev_name(&dwc->xhci->dev));
+			  dev_name(dwc->dev));
 	platform_device_unregister(dwc->xhci);
 }
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9f5ffb629973..b2419950221f 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
 	}
 	irq = res->start;
 
-	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
-				dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
+				&pdev->dev, dev_name(&pdev->dev), NULL);
 	if (!hcd) {
 		retval = -ENOMEM;
 		goto err1;
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ed56bf9ed885..c1d69e14432d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/usb/phy.h>
@@ -139,6 +140,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	const struct hc_driver	*driver;
+	struct device		*sysdev;
 	struct xhci_hcd		*xhci;
 	struct resource         *res;
 	struct usb_hcd		*hcd;
@@ -155,22 +157,38 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
+	/*
+	 * sysdev must point to a device that is known to the system firmware
+	 * or PCI hardware. We handle these three cases here:
+	 * 1. xhci_plat comes from firmware
+	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
+	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
+	 */
+	sysdev = &pdev->dev;
+	if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node)
+		sysdev = sysdev->parent;
+#ifdef CONFIG_PCI
+	else if (sysdev->parent && sysdev->parent->parent &&
+		 sysdev->parent->parent->bus == &pci_bus_type)
+		sysdev = sysdev->parent->parent;
+#endif
+
 	/* Try to set 64-bit DMA first */
-	if (WARN_ON(!pdev->dev.dma_mask))
+	if (WARN_ON(!sysdev->dma_mask))
 		/* Platform did not initialize dma_mask */
-		ret = dma_coerce_mask_and_coherent(&pdev->dev,
+		ret = dma_coerce_mask_and_coherent(sysdev,
 						   DMA_BIT_MASK(64));
 	else
-		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
 
 	/* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
 	if (ret) {
-		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
 		if (ret)
 			return ret;
 	}
 
-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, dev_name(&pdev->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
@@ -220,13 +238,13 @@ static int xhci_plat_probe(struct platform_device *pdev)
 		goto disable_clk;
 	}
 
-	if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
+	if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
 		xhci->quirks |= XHCI_LPM_SUPPORT;
 
 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
 		xhci->shared_hcd->can_do_streams = 1;
 
-	hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
 	if (IS_ERR(hcd->usb_phy)) {
 		ret = PTR_ERR(hcd->usb_phy);
 		if (ret == -EPROBE_DEFER)
diff --git a/include/linux/usb.h b/include/linux/usb.h
index eba1f10e8cfd..f3f5d8a396e4 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -354,6 +354,7 @@ struct usb_devmap {
  */
 struct usb_bus {
 	struct device *controller;	/* host/master side hardware */
+	struct device *sysdev;		/* as seen from firmware or bus */
 	int busnum;			/* Bus number (in order of reg) */
 	const char *bus_name;		/* stable id (PCI slot_name etc) */
 	u8 uses_dma;			/* Does the host controller use DMA? */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 66fc13705ab7..3860560a61bb 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -437,6 +437,9 @@ extern int usb_hcd_alloc_bandwidth(struct usb_device *udev,
 		struct usb_host_interface *new_alt);
 extern int usb_hcd_get_frame_number(struct usb_device *udev);
 
+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
+		struct device *sysdev, struct device *dev, const char *bus_name,
+		struct usb_hcd *primary_hcd);
 extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
 		struct device *dev, const char *bus_name);
 extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 15:24                                                       ` Arnd Bergmann
@ 2016-09-07 16:08                                                         ` Alan Stern
  -1 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-09-07 16:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Peter Chen, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Greg Kroah-Hartman,
	linux-arm-kernel

On Wed, 7 Sep 2016, Arnd Bergmann wrote:

> However, to summarize the discussion so far, I agree that
> of_dma_configure() is not the solution to these problems, and I think
> we can do much better:
> 
> Splitting the usb_bus->controller field into the Linux-internal device
> (used for the sysfs hierarchy, for printks and for power management)
> and a new pointer (used for DMA, DT enumeration and phy lookup) probably
> covers all that we really need.
> 
> I've prototyped it below, with the dwc3, xhci and chipidea changes
> together with the core changes. I've surely made mistakes there and
> don't expect it to work out of the box, but this should give an
> idea of how I think this can all be solved in the least invasive
> way.
> 
> I noticed that the gadget interface already has a way to handle the
> DMA allocation by device, so I added that in as well.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> 
>  drivers/usb/chipidea/core.c    |  4 ----
>  drivers/usb/chipidea/host.c    |  3 ++-
>  drivers/usb/chipidea/udc.c     |  8 ++++----
>  drivers/usb/core/buffer.c      | 12 ++++++------
>  drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++-------------------
>  drivers/usb/core/usb.c         | 16 ++++++++--------
>  drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
>  drivers/usb/dwc3/core.h        |  1 +
>  drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
>  drivers/usb/dwc3/dwc3-st.c     |  1 -
>  drivers/usb/dwc3/ep0.c         |  8 ++++----
>  drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
>  drivers/usb/dwc3/host.c        | 13 ++++---------
>  drivers/usb/host/ehci-fsl.c    |  4 ++--

How did this driver end up in the patch?

>  drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
>  include/linux/usb.h            |  1 +
>  include/linux/usb/hcd.h        |  3 +++

> diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
> index 9f5ffb629973..b2419950221f 100644
> --- a/drivers/usb/host/ehci-fsl.c
> +++ b/drivers/usb/host/ehci-fsl.c
> @@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
>  	}
>  	irq = res->start;
>  
> -	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
> -				dev_name(&pdev->dev));
> +	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
> +				&pdev->dev, dev_name(&pdev->dev), NULL);

Based on the

	if (of_device_is_compatible(dev->parent->of_node,
				    "fsl,mpc5121-usb2-dr")) {

lines in the driver?

>  	if (!hcd) {
>  		retval = -ENOMEM;
>  		goto err1;

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 16:08                                                         ` Alan Stern
  0 siblings, 0 replies; 182+ messages in thread
From: Alan Stern @ 2016-09-07 16:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 7 Sep 2016, Arnd Bergmann wrote:

> However, to summarize the discussion so far, I agree that
> of_dma_configure() is not the solution to these problems, and I think
> we can do much better:
> 
> Splitting the usb_bus->controller field into the Linux-internal device
> (used for the sysfs hierarchy, for printks and for power management)
> and a new pointer (used for DMA, DT enumeration and phy lookup) probably
> covers all that we really need.
> 
> I've prototyped it below, with the dwc3, xhci and chipidea changes
> together with the core changes. I've surely made mistakes there and
> don't expect it to work out of the box, but this should give an
> idea of how I think this can all be solved in the least invasive
> way.
> 
> I noticed that the gadget interface already has a way to handle the
> DMA allocation by device, so I added that in as well.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> 
>  drivers/usb/chipidea/core.c    |  4 ----
>  drivers/usb/chipidea/host.c    |  3 ++-
>  drivers/usb/chipidea/udc.c     |  8 ++++----
>  drivers/usb/core/buffer.c      | 12 ++++++------
>  drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++-------------------
>  drivers/usb/core/usb.c         | 16 ++++++++--------
>  drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
>  drivers/usb/dwc3/core.h        |  1 +
>  drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
>  drivers/usb/dwc3/dwc3-st.c     |  1 -
>  drivers/usb/dwc3/ep0.c         |  8 ++++----
>  drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
>  drivers/usb/dwc3/host.c        | 13 ++++---------
>  drivers/usb/host/ehci-fsl.c    |  4 ++--

How did this driver end up in the patch?

>  drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
>  include/linux/usb.h            |  1 +
>  include/linux/usb/hcd.h        |  3 +++

> diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
> index 9f5ffb629973..b2419950221f 100644
> --- a/drivers/usb/host/ehci-fsl.c
> +++ b/drivers/usb/host/ehci-fsl.c
> @@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
>  	}
>  	irq = res->start;
>  
> -	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
> -				dev_name(&pdev->dev));
> +	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
> +				&pdev->dev, dev_name(&pdev->dev), NULL);

Based on the

	if (of_device_is_compatible(dev->parent->of_node,
				    "fsl,mpc5121-usb2-dr")) {

lines in the driver?

>  	if (!hcd) {
>  		retval = -ENOMEM;
>  		goto err1;

Alan Stern

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 16:08                                                         ` Alan Stern
@ 2016-09-07 19:45                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 19:45 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Alan Stern, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman,
	Peter Chen

On Wednesday, September 7, 2016 12:08:20 PM CEST Alan Stern wrote:
> On Wed, 7 Sep 2016, Arnd Bergmann wrote:
> 
> >  drivers/usb/host/ehci-fsl.c    |  4 ++--
> 
> How did this driver end up in the patch?
>
> > diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
> > index 9f5ffb629973..b2419950221f 100644
> > --- a/drivers/usb/host/ehci-fsl.c
> > +++ b/drivers/usb/host/ehci-fsl.c
> > @@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
> >  	}
> >  	irq = res->start;
> >  
> > -	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
> > -				dev_name(&pdev->dev));
> > +	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
> > +				&pdev->dev, dev_name(&pdev->dev), NULL);
> 
> Based on the
> 
> 	if (of_device_is_compatible(dev->parent->of_node,
> 				    "fsl,mpc5121-usb2-dr")) {
> 
> lines in the driver?

No, based on the "fsl-ehci" name, which is only used as a child
of the drivers/usb/host/fsl-mph-dr-of.c dual-role driver.

I looked for drivers that call platform_device_add() and manipulate
the dma_mask of that child.

Sorry for missing this one when I did the description. I believe
it is correct though. The DMA settings on powerpc are probably correct
in this case, but the existing code doesn't allow you to describe
on-board USB devices with additional properties as children of
the dual-role device node.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-07 19:45                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-07 19:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 7, 2016 12:08:20 PM CEST Alan Stern wrote:
> On Wed, 7 Sep 2016, Arnd Bergmann wrote:
> 
> >  drivers/usb/host/ehci-fsl.c    |  4 ++--
> 
> How did this driver end up in the patch?
>
> > diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
> > index 9f5ffb629973..b2419950221f 100644
> > --- a/drivers/usb/host/ehci-fsl.c
> > +++ b/drivers/usb/host/ehci-fsl.c
> > @@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
> >  	}
> >  	irq = res->start;
> >  
> > -	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
> > -				dev_name(&pdev->dev));
> > +	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
> > +				&pdev->dev, dev_name(&pdev->dev), NULL);
> 
> Based on the
> 
> 	if (of_device_is_compatible(dev->parent->of_node,
> 				    "fsl,mpc5121-usb2-dr")) {
> 
> lines in the driver?

No, based on the "fsl-ehci" name, which is only used as a child
of the drivers/usb/host/fsl-mph-dr-of.c dual-role driver.

I looked for drivers that call platform_device_add() and manipulate
the dma_mask of that child.

Sorry for missing this one when I did the description. I believe
it is correct though. The DMA settings on powerpc are probably correct
in this case, but the existing code doesn't allow you to describe
on-board USB devices with additional properties as children of
the dual-role device node.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 15:24                                                       ` Arnd Bergmann
@ 2016-09-08  1:15                                                         ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-08  1:15 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Wed, Sep 07, 2016 at 05:24:08PM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > 
> > [...]
> > 
> > > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > > I think we should replace 
> > >
> > >         pdev->dev.dma_mask = dev->dma_mask;
> > >         pdev->dev.dma_parms = dev->dma_parms;
> > >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> > >
> > > with of_dma_configure(), which has the chance to configure more than
> > > just those three, as the dma API might look into different aspects:
> > >
> > > - iommu specific configuration
> > > - cache coherency information
> > > - bus type
> > > - dma offset
> > > - dma_map_ops pointer
> > >
> > > We try to handle everything in of_dma_configure() at configuration
> > > time, and that would be the place to add anything else that we might
> > > need in the future.
> > 
> > There are a couple problems with this:
> > 
> > 1) won't work for PCI-based systems.
> > 
> > DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
> > platform (FPGA that appears like a PCI card to host PC)
> 
> Right, I was specifically talking about the code in chipidea here,
> which I think is never used on the PCI bus, and how the current
> code is broken. We can probably do better than of_dma_configure()
> (see below), but it would be an improvement.

Chipidea is also used at PCI bus too, see drivers/usb/chipidea/ci_hdrc_pci.c

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  1:15                                                         ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-08  1:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2016 at 05:24:08PM +0200, Arnd Bergmann wrote:
> On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Arnd Bergmann <arnd@arndb.de> writes:
> > 
> > [...]
> > 
> > > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > > I think we should replace 
> > >
> > >         pdev->dev.dma_mask = dev->dma_mask;
> > >         pdev->dev.dma_parms = dev->dma_parms;
> > >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> > >
> > > with of_dma_configure(), which has the chance to configure more than
> > > just those three, as the dma API might look into different aspects:
> > >
> > > - iommu specific configuration
> > > - cache coherency information
> > > - bus type
> > > - dma offset
> > > - dma_map_ops pointer
> > >
> > > We try to handle everything in of_dma_configure() at configuration
> > > time, and that would be the place to add anything else that we might
> > > need in the future.
> > 
> > There are a couple problems with this:
> > 
> > 1) won't work for PCI-based systems.
> > 
> > DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
> > platform (FPGA that appears like a PCI card to host PC)
> 
> Right, I was specifically talking about the code in chipidea here,
> which I think is never used on the PCI bus, and how the current
> code is broken. We can probably do better than of_dma_configure()
> (see below), but it would be an improvement.

Chipidea is also used at PCI bus too, see drivers/usb/chipidea/ci_hdrc_pci.c

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  1:15                                                         ` Peter Chen
@ 2016-09-08  8:02                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:02 UTC (permalink / raw)
  To: Peter Chen
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Thursday, September 8, 2016 9:15:36 AM CEST Peter Chen wrote:
> > 
> > Right, I was specifically talking about the code in chipidea here,
> > which I think is never used on the PCI bus, and how the current
> > code is broken. We can probably do better than of_dma_configure()
> > (see below), but it would be an improvement.
> 
> Chipidea is also used at PCI bus too, see drivers/usb/chipidea/ci_hdrc_pci.c
> 

Ok, I see.

The experimental patch I posted should actually handle this just fine,
as it simply assumes that dev->parent is the device used for the DMA
API in chipidea, and I think this holds true for both the PCI and the
DT based uses of this driver.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  8:02                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 9:15:36 AM CEST Peter Chen wrote:
> > 
> > Right, I was specifically talking about the code in chipidea here,
> > which I think is never used on the PCI bus, and how the current
> > code is broken. We can probably do better than of_dma_configure()
> > (see below), but it would be an improvement.
> 
> Chipidea is also used at PCI bus too, see drivers/usb/chipidea/ci_hdrc_pci.c
> 

Ok, I see.

The experimental patch I posted should actually handle this just fine,
as it simply assumes that dev->parent is the device used for the DMA
API in chipidea, and I think this holds true for both the PCI and the
DT based uses of this driver.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 15:24                                                       ` Arnd Bergmann
@ 2016-09-08  8:03                                                         ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  8:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 6170 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> 
>> [...]
>> 
>> > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>> > I think we should replace 
>> >
>> >         pdev->dev.dma_mask = dev->dma_mask;
>> >         pdev->dev.dma_parms = dev->dma_parms;
>> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>> >
>> > with of_dma_configure(), which has the chance to configure more than
>> > just those three, as the dma API might look into different aspects:
>> >
>> > - iommu specific configuration
>> > - cache coherency information
>> > - bus type
>> > - dma offset
>> > - dma_map_ops pointer
>> >
>> > We try to handle everything in of_dma_configure() at configuration
>> > time, and that would be the place to add anything else that we might
>> > need in the future.
>> 
>> There are a couple problems with this:
>> 
>> 1) won't work for PCI-based systems.
>> 
>> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
>> platform (FPGA that appears like a PCI card to host PC)
>
> Right, I was specifically talking about the code in chipidea here,
> which I think is never used on the PCI bus, and how the current

just look at the history of the file, you'll see that an Intel employee
was a maintainer of chipidea driver. Also:

$ git ls-files drivers/usb/chipidea/ | grep pci
drivers/usb/chipidea/ci_hdrc_pci.c

> code is broken. We can probably do better than of_dma_configure()
> (see below), but it would be an improvement.
>
>> 2) not very robust solution
>> 
>> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
>> that's not created by DT. The only reason why this works at all is
>> because of the default 32-bit dma mask thing :-) So, how is it any
>> different than copying 32-bit dma mask from parent?
>
> The idea here is that you pass in the parent of_node along with the child
> device pointer, so it would behave exactly like the parent already does.
> The difference is that it also handles all the other attributes besides the mask.

Now we're talking :-) I like that. We just need a matching API for
ACPI/PCI-based systems.

> However, to summarize the discussion so far, I agree that
> of_dma_configure() is not the solution to these problems, and I think
> we can do much better:
>
> Splitting the usb_bus->controller field into the Linux-internal device
> (used for the sysfs hierarchy, for printks and for power management)
> and a new pointer (used for DMA, DT enumeration and phy lookup) probably
> covers all that we really need.
>
> I've prototyped it below, with the dwc3, xhci and chipidea changes
> together with the core changes. I've surely made mistakes there and
> don't expect it to work out of the box, but this should give an
> idea of how I think this can all be solved in the least invasive
> way.
>
> I noticed that the gadget interface already has a way to handle the
> DMA allocation by device, so I added that in as well.

yeah, I wanna use that :-)

> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 35d092456bec..08db66c64c66 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -25,6 +25,7 @@
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
>  #include <linux/platform_device.h>
> +#include <linux/pci.h>

actually, we don't want the core to know what it's attached to.

>  #include <linux/pm_runtime.h>
>  #include <linux/interrupt.h>
>  #include <linux/ioport.h>
> @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
>  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>  		struct dwc3_event_buffer *evt)
>  {
> -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);

how about "dma_dev" instead? Is this used for anything other than DMA?

> @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
>  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
>  	dwc->mem = mem;
>  	dwc->dev = dev;
> +#ifdef CONFIG_PCI
> +	/* TODO: or some other way of detecting this? */
> +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
> +		dwc->sysdev = dwc->dev->parent;
> +	else
> +#endif
> +		dwc->sysdev = dwc->dev;

Well, we can remove this ifdef and *always* use the parent. We will just
require that dwc3 users provide a glue layer. In that case, your check
becomes:

	if (dwc->dev->parent)
        	dwc->sysdev = dwc->dev->parent;
	else
        	dev_info(dwc->dev, "Please provide a glue layer!\n");

> diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
> index 2f1fb7e7aa54..e27899bb5706 100644
> --- a/drivers/usb/dwc3/dwc3-exynos.c
> +++ b/drivers/usb/dwc3/dwc3-exynos.c
> @@ -20,7 +20,6 @@
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> -#include <linux/dma-mapping.h>
>  #include <linux/clk.h>
>  #include <linux/usb/otg.h>
>  #include <linux/usb/usb_phy_generic.h>
> @@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
>  	if (!exynos)
>  		return -ENOMEM;
>  
> -	/*
> -	 * Right now device-tree probed devices don't get dma_mask set.
> -	 * Since shared usb code relies on it, set it here for now.
> -	 * Once we move to full device tree support this will vanish off.
> -	 */
> -	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> -	if (ret)
> -		return ret;

this is a separate patch, right?

> diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
> index 89a2f712fdfe..4d7439cb8cd8 100644
> --- a/drivers/usb/dwc3/dwc3-st.c
> +++ b/drivers/usb/dwc3/dwc3-st.c
> @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
>  	if (IS_ERR(regmap))
>  		return PTR_ERR(regmap);
>  
> -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);

so is this.

All in all, I like where you're going with this, we just need a matching
acpi_dma_configure() and problems will be sorted out.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  8:03                                                         ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  8:03 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> 
>> [...]
>> 
>> > Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
>> > I think we should replace 
>> >
>> >         pdev->dev.dma_mask = dev->dma_mask;
>> >         pdev->dev.dma_parms = dev->dma_parms;
>> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>> >
>> > with of_dma_configure(), which has the chance to configure more than
>> > just those three, as the dma API might look into different aspects:
>> >
>> > - iommu specific configuration
>> > - cache coherency information
>> > - bus type
>> > - dma offset
>> > - dma_map_ops pointer
>> >
>> > We try to handle everything in of_dma_configure() at configuration
>> > time, and that would be the place to add anything else that we might
>> > need in the future.
>> 
>> There are a couple problems with this:
>> 
>> 1) won't work for PCI-based systems.
>> 
>> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
>> platform (FPGA that appears like a PCI card to host PC)
>
> Right, I was specifically talking about the code in chipidea here,
> which I think is never used on the PCI bus, and how the current

just look at the history of the file, you'll see that an Intel employee
was a maintainer of chipidea driver. Also:

$ git ls-files drivers/usb/chipidea/ | grep pci
drivers/usb/chipidea/ci_hdrc_pci.c

> code is broken. We can probably do better than of_dma_configure()
> (see below), but it would be an improvement.
>
>> 2) not very robust solution
>> 
>> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat because
>> that's not created by DT. The only reason why this works at all is
>> because of the default 32-bit dma mask thing :-) So, how is it any
>> different than copying 32-bit dma mask from parent?
>
> The idea here is that you pass in the parent of_node along with the child
> device pointer, so it would behave exactly like the parent already does.
> The difference is that it also handles all the other attributes besides the mask.

Now we're talking :-) I like that. We just need a matching API for
ACPI/PCI-based systems.

> However, to summarize the discussion so far, I agree that
> of_dma_configure() is not the solution to these problems, and I think
> we can do much better:
>
> Splitting the usb_bus->controller field into the Linux-internal device
> (used for the sysfs hierarchy, for printks and for power management)
> and a new pointer (used for DMA, DT enumeration and phy lookup) probably
> covers all that we really need.
>
> I've prototyped it below, with the dwc3, xhci and chipidea changes
> together with the core changes. I've surely made mistakes there and
> don't expect it to work out of the box, but this should give an
> idea of how I think this can all be solved in the least invasive
> way.
>
> I noticed that the gadget interface already has a way to handle the
> DMA allocation by device, so I added that in as well.

yeah, I wanna use that :-)

> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 35d092456bec..08db66c64c66 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -25,6 +25,7 @@
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
>  #include <linux/platform_device.h>
> +#include <linux/pci.h>

actually, we don't want the core to know what it's attached to.

>  #include <linux/pm_runtime.h>
>  #include <linux/interrupt.h>
>  #include <linux/ioport.h>
> @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
>  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>  		struct dwc3_event_buffer *evt)
>  {
> -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);

how about "dma_dev" instead? Is this used for anything other than DMA?

> @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
>  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
>  	dwc->mem = mem;
>  	dwc->dev = dev;
> +#ifdef CONFIG_PCI
> +	/* TODO: or some other way of detecting this? */
> +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
> +		dwc->sysdev = dwc->dev->parent;
> +	else
> +#endif
> +		dwc->sysdev = dwc->dev;

Well, we can remove this ifdef and *always* use the parent. We will just
require that dwc3 users provide a glue layer. In that case, your check
becomes:

	if (dwc->dev->parent)
        	dwc->sysdev = dwc->dev->parent;
	else
        	dev_info(dwc->dev, "Please provide a glue layer!\n");

> diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
> index 2f1fb7e7aa54..e27899bb5706 100644
> --- a/drivers/usb/dwc3/dwc3-exynos.c
> +++ b/drivers/usb/dwc3/dwc3-exynos.c
> @@ -20,7 +20,6 @@
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> -#include <linux/dma-mapping.h>
>  #include <linux/clk.h>
>  #include <linux/usb/otg.h>
>  #include <linux/usb/usb_phy_generic.h>
> @@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
>  	if (!exynos)
>  		return -ENOMEM;
>  
> -	/*
> -	 * Right now device-tree probed devices don't get dma_mask set.
> -	 * Since shared usb code relies on it, set it here for now.
> -	 * Once we move to full device tree support this will vanish off.
> -	 */
> -	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> -	if (ret)
> -		return ret;

this is a separate patch, right?

> diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
> index 89a2f712fdfe..4d7439cb8cd8 100644
> --- a/drivers/usb/dwc3/dwc3-st.c
> +++ b/drivers/usb/dwc3/dwc3-st.c
> @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
>  	if (IS_ERR(regmap))
>  		return PTR_ERR(regmap);
>  
> -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);

so is this.

All in all, I like where you're going with this, we just need a matching
acpi_dma_configure() and problems will be sorted out.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/031d1e45/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  8:03                                                         ` Felipe Balbi
@ 2016-09-08  8:26                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:26 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 11:03:10 AM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> >> Arnd Bergmann <arnd@arndb.de> writes:
> just look at the history of the file, you'll see that an Intel employee
> was a maintainer of chipidea driver. Also:
> 
> $ git ls-files drivers/usb/chipidea/ | grep pci
> drivers/usb/chipidea/ci_hdrc_pci.c

Right, Peter pointed that one out too.

> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index 35d092456bec..08db66c64c66 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c
> > @@ -25,6 +25,7 @@
> >  #include <linux/slab.h>
> >  #include <linux/spinlock.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/pci.h>
> 
> actually, we don't want the core to know what it's attached to.

Agreed. This was just a first draft and I couldn't come up with
a better way to detect the case in which the parent device is
probed from another HW bus and the child is not known to the
firmware.

> >  #include <linux/pm_runtime.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/ioport.h>
> > @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
> >  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
> >  		struct dwc3_event_buffer *evt)
> >  {
> > -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> > +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
> 
> how about "dma_dev" instead? Is this used for anything other than DMA?

The two other things we have discussed in this thread are:

- connecting of_node pointers to usb_device structures for children
  of sysdev->of_node. Note that this can happen even for PCI devices
  in case you have a USB ethernet device hardwired to a PCI-USB bridge
  and put the mac address in DT.

- finding the PHY device for a HCD

There might be others. Basically sysdev here is what the USB core code
can use for looking up any kind of properties provided by the firmware.

> > @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
> >  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
> >  	dwc->mem = mem;
> >  	dwc->dev = dev;
> > +#ifdef CONFIG_PCI
> > +	/* TODO: or some other way of detecting this? */
> > +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
> > +		dwc->sysdev = dwc->dev->parent;
> > +	else
> > +#endif
> > +		dwc->sysdev = dwc->dev;
> 
> Well, we can remove this ifdef and *always* use the parent. We will just
> require that dwc3 users provide a glue layer. In that case, your check
> becomes:
> 
> 	if (dwc->dev->parent)
>         	dwc->sysdev = dwc->dev->parent;
> 	else
>         	dev_info(dwc->dev, "Please provide a glue layer!\n");

If we do that, we have to put child devices of the dwc3 devices into
the platform glue, and it also breaks those dwc3 devices that don't
have a parent driver.

> > diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
> > index 2f1fb7e7aa54..e27899bb5706 100644
> > --- a/drivers/usb/dwc3/dwc3-exynos.c
> > +++ b/drivers/usb/dwc3/dwc3-exynos.c
> > @@ -20,7 +20,6 @@
> >  #include <linux/kernel.h>
> >  #include <linux/slab.h>
> >  #include <linux/platform_device.h>
> > -#include <linux/dma-mapping.h>
> >  #include <linux/clk.h>
> >  #include <linux/usb/otg.h>
> >  #include <linux/usb/usb_phy_generic.h>
> > @@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
> >  	if (!exynos)
> >  		return -ENOMEM;
> >  
> > -	/*
> > -	 * Right now device-tree probed devices don't get dma_mask set.
> > -	 * Since shared usb code relies on it, set it here for now.
> > -	 * Once we move to full device tree support this will vanish off.
> > -	 */
> > -	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> > -	if (ret)
> > -		return ret;
> 
> this is a separate patch, right?

Yes, this is probably just a cleanup that we can apply regardless.
We have not needed this in a long time.

> > diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
> > index 89a2f712fdfe..4d7439cb8cd8 100644
> > --- a/drivers/usb/dwc3/dwc3-st.c
> > +++ b/drivers/usb/dwc3/dwc3-st.c
> > @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
> >  	if (IS_ERR(regmap))
> >  		return PTR_ERR(regmap);
> >  
> > -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
> 
> so is this.
> 
> All in all, I like where you're going with this, we just need a matching
> acpi_dma_configure() and problems will be sorted out.

With this patch, I don't think we even need that any more, as the device
that we use the dma-mapping API is the one that already gets configured
correctly by the platform code for all cases: PCI, OF, ACPI and combinations
of those.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  8:26                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 11:03:10 AM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> >> Arnd Bergmann <arnd@arndb.de> writes:
> just look at the history of the file, you'll see that an Intel employee
> was a maintainer of chipidea driver. Also:
> 
> $ git ls-files drivers/usb/chipidea/ | grep pci
> drivers/usb/chipidea/ci_hdrc_pci.c

Right, Peter pointed that one out too.

> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index 35d092456bec..08db66c64c66 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c
> > @@ -25,6 +25,7 @@
> >  #include <linux/slab.h>
> >  #include <linux/spinlock.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/pci.h>
> 
> actually, we don't want the core to know what it's attached to.

Agreed. This was just a first draft and I couldn't come up with
a better way to detect the case in which the parent device is
probed from another HW bus and the child is not known to the
firmware.

> >  #include <linux/pm_runtime.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/ioport.h>
> > @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
> >  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
> >  		struct dwc3_event_buffer *evt)
> >  {
> > -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
> > +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
> 
> how about "dma_dev" instead? Is this used for anything other than DMA?

The two other things we have discussed in this thread are:

- connecting of_node pointers to usb_device structures for children
  of sysdev->of_node. Note that this can happen even for PCI devices
  in case you have a USB ethernet device hardwired to a PCI-USB bridge
  and put the mac address in DT.

- finding the PHY device for a HCD

There might be others. Basically sysdev here is what the USB core code
can use for looking up any kind of properties provided by the firmware.

> > @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
> >  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
> >  	dwc->mem = mem;
> >  	dwc->dev = dev;
> > +#ifdef CONFIG_PCI
> > +	/* TODO: or some other way of detecting this? */
> > +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
> > +		dwc->sysdev = dwc->dev->parent;
> > +	else
> > +#endif
> > +		dwc->sysdev = dwc->dev;
> 
> Well, we can remove this ifdef and *always* use the parent. We will just
> require that dwc3 users provide a glue layer. In that case, your check
> becomes:
> 
> 	if (dwc->dev->parent)
>         	dwc->sysdev = dwc->dev->parent;
> 	else
>         	dev_info(dwc->dev, "Please provide a glue layer!\n");

If we do that, we have to put child devices of the dwc3 devices into
the platform glue, and it also breaks those dwc3 devices that don't
have a parent driver.

> > diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
> > index 2f1fb7e7aa54..e27899bb5706 100644
> > --- a/drivers/usb/dwc3/dwc3-exynos.c
> > +++ b/drivers/usb/dwc3/dwc3-exynos.c
> > @@ -20,7 +20,6 @@
> >  #include <linux/kernel.h>
> >  #include <linux/slab.h>
> >  #include <linux/platform_device.h>
> > -#include <linux/dma-mapping.h>
> >  #include <linux/clk.h>
> >  #include <linux/usb/otg.h>
> >  #include <linux/usb/usb_phy_generic.h>
> > @@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
> >  	if (!exynos)
> >  		return -ENOMEM;
> >  
> > -	/*
> > -	 * Right now device-tree probed devices don't get dma_mask set.
> > -	 * Since shared usb code relies on it, set it here for now.
> > -	 * Once we move to full device tree support this will vanish off.
> > -	 */
> > -	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> > -	if (ret)
> > -		return ret;
> 
> this is a separate patch, right?

Yes, this is probably just a cleanup that we can apply regardless.
We have not needed this in a long time.

> > diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
> > index 89a2f712fdfe..4d7439cb8cd8 100644
> > --- a/drivers/usb/dwc3/dwc3-st.c
> > +++ b/drivers/usb/dwc3/dwc3-st.c
> > @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
> >  	if (IS_ERR(regmap))
> >  		return PTR_ERR(regmap);
> >  
> > -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
> 
> so is this.
> 
> All in all, I like where you're going with this, we just need a matching
> acpi_dma_configure() and problems will be sorted out.

With this patch, I don't think we even need that any more, as the device
that we use the dma-mapping API is the one that already gets configured
correctly by the platform code for all cases: PCI, OF, ACPI and combinations
of those.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  8:26                                                           ` Arnd Bergmann
@ 2016-09-08  8:29                                                             ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  8:29 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 2992 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> > @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
>> >  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>> >  		struct dwc3_event_buffer *evt)
>> >  {
>> > -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
>> > +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
>> 
>> how about "dma_dev" instead? Is this used for anything other than DMA?
>
> The two other things we have discussed in this thread are:
>
> - connecting of_node pointers to usb_device structures for children
>   of sysdev->of_node. Note that this can happen even for PCI devices
>   in case you have a USB ethernet device hardwired to a PCI-USB bridge
>   and put the mac address in DT.
>
> - finding the PHY device for a HCD
>
> There might be others. Basically sysdev here is what the USB core code
> can use for looking up any kind of properties provided by the firmware.

fair enough

>> > @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
>> >  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
>> >  	dwc->mem = mem;
>> >  	dwc->dev = dev;
>> > +#ifdef CONFIG_PCI
>> > +	/* TODO: or some other way of detecting this? */
>> > +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
>> > +		dwc->sysdev = dwc->dev->parent;
>> > +	else
>> > +#endif
>> > +		dwc->sysdev = dwc->dev;
>> 
>> Well, we can remove this ifdef and *always* use the parent. We will just
>> require that dwc3 users provide a glue layer. In that case, your check
>> becomes:
>> 
>> 	if (dwc->dev->parent)
>>         	dwc->sysdev = dwc->dev->parent;
>> 	else
>>         	dev_info(dwc->dev, "Please provide a glue layer!\n");
>
> If we do that, we have to put child devices of the dwc3 devices into
> the platform glue, and it also breaks those dwc3 devices that don't
> have a parent driver.

Well, this is easy to fix:

 	if (dwc->dev->parent) {
         	dwc->sysdev = dwc->dev->parent;
 	} else {
         	dev_info(dwc->dev, "Please provide a glue layer!\n");
		dwc->sysdev = dwc->dev;
	}

>> > diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
>> > index 89a2f712fdfe..4d7439cb8cd8 100644
>> > --- a/drivers/usb/dwc3/dwc3-st.c
>> > +++ b/drivers/usb/dwc3/dwc3-st.c
>> > @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
>> >  	if (IS_ERR(regmap))
>> >  		return PTR_ERR(regmap);
>> >  
>> > -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
>> 
>> so is this.
>> 
>> All in all, I like where you're going with this, we just need a matching
>> acpi_dma_configure() and problems will be sorted out.
>
> With this patch, I don't think we even need that any more, as the device
> that we use the dma-mapping API is the one that already gets configured
> correctly by the platform code for all cases: PCI, OF, ACPI and combinations
> of those.

sounds good to me

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  8:29                                                             ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  8:29 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> > @@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
>> >  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
>> >  		struct dwc3_event_buffer *evt)
>> >  {
>> > -	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
>> > +	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
>> 
>> how about "dma_dev" instead? Is this used for anything other than DMA?
>
> The two other things we have discussed in this thread are:
>
> - connecting of_node pointers to usb_device structures for children
>   of sysdev->of_node. Note that this can happen even for PCI devices
>   in case you have a USB ethernet device hardwired to a PCI-USB bridge
>   and put the mac address in DT.
>
> - finding the PHY device for a HCD
>
> There might be others. Basically sysdev here is what the USB core code
> can use for looking up any kind of properties provided by the firmware.

fair enough

>> > @@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
>> >  	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
>> >  	dwc->mem = mem;
>> >  	dwc->dev = dev;
>> > +#ifdef CONFIG_PCI
>> > +	/* TODO: or some other way of detecting this? */
>> > +	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
>> > +		dwc->sysdev = dwc->dev->parent;
>> > +	else
>> > +#endif
>> > +		dwc->sysdev = dwc->dev;
>> 
>> Well, we can remove this ifdef and *always* use the parent. We will just
>> require that dwc3 users provide a glue layer. In that case, your check
>> becomes:
>> 
>> 	if (dwc->dev->parent)
>>         	dwc->sysdev = dwc->dev->parent;
>> 	else
>>         	dev_info(dwc->dev, "Please provide a glue layer!\n");
>
> If we do that, we have to put child devices of the dwc3 devices into
> the platform glue, and it also breaks those dwc3 devices that don't
> have a parent driver.

Well, this is easy to fix:

 	if (dwc->dev->parent) {
         	dwc->sysdev = dwc->dev->parent;
 	} else {
         	dev_info(dwc->dev, "Please provide a glue layer!\n");
		dwc->sysdev = dwc->dev;
	}

>> > diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
>> > index 89a2f712fdfe..4d7439cb8cd8 100644
>> > --- a/drivers/usb/dwc3/dwc3-st.c
>> > +++ b/drivers/usb/dwc3/dwc3-st.c
>> > @@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
>> >  	if (IS_ERR(regmap))
>> >  		return PTR_ERR(regmap);
>> >  
>> > -	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
>> 
>> so is this.
>> 
>> All in all, I like where you're going with this, we just need a matching
>> acpi_dma_configure() and problems will be sorted out.
>
> With this patch, I don't think we even need that any more, as the device
> that we use the dma-mapping API is the one that already gets configured
> correctly by the platform code for all cases: PCI, OF, ACPI and combinations
> of those.

sounds good to me

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/4f027449/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  8:29                                                             ` Felipe Balbi
@ 2016-09-08  8:45                                                               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:45 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > If we do that, we have to put child devices of the dwc3 devices into
> > the platform glue, and it also breaks those dwc3 devices that don't
> > have a parent driver.
> 
> Well, this is easy to fix:
> 
>         if (dwc->dev->parent) {
>                 dwc->sysdev = dwc->dev->parent;
>         } else {
>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>                 dwc->sysdev = dwc->dev;
>         }

I don't understand. Do you mean we should have an extra level of
stacking and splitting "static struct platform_driver dwc3_driver"
in two so instead of

	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)

we do this?

	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)

That sounds a bit clumsy for the sake of consistency with PCI.
The advantage is that xhci can always use the grandparent device
as sysdev whenever it isn't probed through PCI or firmware
itself, but the purpose of the dwc3-glue is otherwise questionable.

How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
device when that is created from the PCI driver and checking for that
with the device property interface instead? If it's "snps,dwc3"
we use the device itself while for "snps,dwc3-pci", we use the parent?

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  8:45                                                               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08  8:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > If we do that, we have to put child devices of the dwc3 devices into
> > the platform glue, and it also breaks those dwc3 devices that don't
> > have a parent driver.
> 
> Well, this is easy to fix:
> 
>         if (dwc->dev->parent) {
>                 dwc->sysdev = dwc->dev->parent;
>         } else {
>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>                 dwc->sysdev = dwc->dev;
>         }

I don't understand. Do you mean we should have an extra level of
stacking and splitting "static struct platform_driver dwc3_driver"
in two so instead of

	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)

we do this?

	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)

That sounds a bit clumsy for the sake of consistency with PCI.
The advantage is that xhci can always use the grandparent device
as sysdev whenever it isn't probed through PCI or firmware
itself, but the purpose of the dwc3-glue is otherwise questionable.

How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
device when that is created from the PCI driver and checking for that
with the device property interface instead? If it's "snps,dwc3"
we use the device itself while for "snps,dwc3-pci", we use the parent?

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  8:45                                                               ` Arnd Bergmann
@ 2016-09-08  9:43                                                                 ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  9:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 1655 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>> > If we do that, we have to put child devices of the dwc3 devices into
>> > the platform glue, and it also breaks those dwc3 devices that don't
>> > have a parent driver.
>> 
>> Well, this is easy to fix:
>> 
>>         if (dwc->dev->parent) {
>>                 dwc->sysdev = dwc->dev->parent;
>>         } else {
>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>                 dwc->sysdev = dwc->dev;
>>         }
>
> I don't understand. Do you mean we should have an extra level of
> stacking and splitting "static struct platform_driver dwc3_driver"
> in two so instead of
>
> 	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>
> we do this?
>
> 	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)

no :-)

If we have a parent device, use that as sysdev, otherwise use self as
sysdev.

> That sounds a bit clumsy for the sake of consistency with PCI.
> The advantage is that xhci can always use the grandparent device
> as sysdev whenever it isn't probed through PCI or firmware
> itself, but the purpose of the dwc3-glue is otherwise questionable.
>
> How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> device when that is created from the PCI driver and checking for that
> with the device property interface instead? If it's "snps,dwc3"
> we use the device itself while for "snps,dwc3-pci", we use the parent?

Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08  9:43                                                                 ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08  9:43 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>> > If we do that, we have to put child devices of the dwc3 devices into
>> > the platform glue, and it also breaks those dwc3 devices that don't
>> > have a parent driver.
>> 
>> Well, this is easy to fix:
>> 
>>         if (dwc->dev->parent) {
>>                 dwc->sysdev = dwc->dev->parent;
>>         } else {
>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>                 dwc->sysdev = dwc->dev;
>>         }
>
> I don't understand. Do you mean we should have an extra level of
> stacking and splitting "static struct platform_driver dwc3_driver"
> in two so instead of
>
> 	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>
> we do this?
>
> 	"qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)

no :-)

If we have a parent device, use that as sysdev, otherwise use self as
sysdev.

> That sounds a bit clumsy for the sake of consistency with PCI.
> The advantage is that xhci can always use the grandparent device
> as sysdev whenever it isn't probed through PCI or firmware
> itself, but the purpose of the dwc3-glue is otherwise questionable.
>
> How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> device when that is created from the PCI driver and checking for that
> with the device property interface instead? If it's "snps,dwc3"
> we use the device itself while for "snps,dwc3-pci", we use the parent?

Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/9de6b544/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08  9:43                                                                 ` Felipe Balbi
@ 2016-09-08 10:17                                                                   ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 10:17 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> >> > If we do that, we have to put child devices of the dwc3 devices into
> >> > the platform glue, and it also breaks those dwc3 devices that don't
> >> > have a parent driver.
> >> 
> >> Well, this is easy to fix:
> >> 
> >>         if (dwc->dev->parent) {
> >>                 dwc->sysdev = dwc->dev->parent;
> >>         } else {
> >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> >>                 dwc->sysdev = dwc->dev;
> >>         }
> >
> > I don't understand. Do you mean we should have an extra level of
> > stacking and splitting "static struct platform_driver dwc3_driver"
> > in two so instead of
> >
> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> >
> > we do this?
> >
> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> 
> no 
> 
> If we have a parent device, use that as sysdev, otherwise use self as
> sysdev.

But there is often a parent device in DT, as the xhci device is
attached to some internal bus that gets turned into a platform_device
as well, so checking whether there is a parent will get the wrong
device node.

> > That sounds a bit clumsy for the sake of consistency with PCI.
> > The advantage is that xhci can always use the grandparent device
> > as sysdev whenever it isn't probed through PCI or firmware
> > itself, but the purpose of the dwc3-glue is otherwise questionable.
> >
> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > device when that is created from the PCI driver and checking for that
> > with the device property interface instead? If it's "snps,dwc3"
> > we use the device itself while for "snps,dwc3-pci", we use the parent?
> 
> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?

That would be incompatible with the USB binding, as the sysdev
is assumed to be a USB host controller with #address-cells=<1>
and #size-cells=<0> in order to hold the child devices, for
example:

/ {
     omap_dwc3_1: omap_dwc3_1@48880000 {
        compatible = "ti,dwc3";
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
        usb1: usb@48890000 {
                compatible = "snps,dwc3";
                reg = <0x48890000 0x17000>;
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "peripheral",
                                  "host",
                                  "otg";
                phys = <&usb2_phy1>, <&usb3_phy1>;
                phy-names = "usb2-phy", "usb3-phy";

                hub@1 {
                        compatible = "usb5e3,608";
                        reg = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;

                        ethernet@1 {
                                compatible = "usb424,ec00";
                                mac-address = [00 11 22 33 44 55];
                                reg = <1>;
                        };
                };
        };
};

It's also the node that contains the "phys" properties and
presumably other properties like "otg-rev", "maximum-speed"
etc.

If we make the sysdev point to the parent, then we can no longer
look up those properties and child devices from the USB core code
by looking at "sysdev->of_node".

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 10:17                                                                   ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> >> > If we do that, we have to put child devices of the dwc3 devices into
> >> > the platform glue, and it also breaks those dwc3 devices that don't
> >> > have a parent driver.
> >> 
> >> Well, this is easy to fix:
> >> 
> >>         if (dwc->dev->parent) {
> >>                 dwc->sysdev = dwc->dev->parent;
> >>         } else {
> >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> >>                 dwc->sysdev = dwc->dev;
> >>         }
> >
> > I don't understand. Do you mean we should have an extra level of
> > stacking and splitting "static struct platform_driver dwc3_driver"
> > in two so instead of
> >
> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> >
> > we do this?
> >
> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> 
> no 
> 
> If we have a parent device, use that as sysdev, otherwise use self as
> sysdev.

But there is often a parent device in DT, as the xhci device is
attached to some internal bus that gets turned into a platform_device
as well, so checking whether there is a parent will get the wrong
device node.

> > That sounds a bit clumsy for the sake of consistency with PCI.
> > The advantage is that xhci can always use the grandparent device
> > as sysdev whenever it isn't probed through PCI or firmware
> > itself, but the purpose of the dwc3-glue is otherwise questionable.
> >
> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > device when that is created from the PCI driver and checking for that
> > with the device property interface instead? If it's "snps,dwc3"
> > we use the device itself while for "snps,dwc3-pci", we use the parent?
> 
> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?

That would be incompatible with the USB binding, as the sysdev
is assumed to be a USB host controller with #address-cells=<1>
and #size-cells=<0> in order to hold the child devices, for
example:

/ {
     omap_dwc3_1: omap_dwc3_1 at 48880000 {
        compatible = "ti,dwc3";
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
        usb1: usb at 48890000 {
                compatible = "snps,dwc3";
                reg = <0x48890000 0x17000>;
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "peripheral",
                                  "host",
                                  "otg";
                phys = <&usb2_phy1>, <&usb3_phy1>;
                phy-names = "usb2-phy", "usb3-phy";

                hub at 1 {
                        compatible = "usb5e3,608";
                        reg = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;

                        ethernet at 1 {
                                compatible = "usb424,ec00";
                                mac-address = [00 11 22 33 44 55];
                                reg = <1>;
                        };
                };
        };
};

It's also the node that contains the "phys" properties and
presumably other properties like "otg-rev", "maximum-speed"
etc.

If we make the sysdev point to the parent, then we can no longer
look up those properties and child devices from the USB core code
by looking at "sysdev->of_node".

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 10:17                                                                   ` Arnd Bergmann
@ 2016-09-08 11:00                                                                     ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 5440 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>> >> > If we do that, we have to put child devices of the dwc3 devices into
>> >> > the platform glue, and it also breaks those dwc3 devices that don't
>> >> > have a parent driver.
>> >> 
>> >> Well, this is easy to fix:
>> >> 
>> >>         if (dwc->dev->parent) {
>> >>                 dwc->sysdev = dwc->dev->parent;
>> >>         } else {
>> >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>> >>                 dwc->sysdev = dwc->dev;
>> >>         }
>> >
>> > I don't understand. Do you mean we should have an extra level of
>> > stacking and splitting "static struct platform_driver dwc3_driver"
>> > in two so instead of
>> >
>> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>> >
>> > we do this?
>> >
>> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>> 
>> no 
>> 
>> If we have a parent device, use that as sysdev, otherwise use self as
>> sysdev.
>
> But there is often a parent device in DT, as the xhci device is
> attached to some internal bus that gets turned into a platform_device
> as well, so checking whether there is a parent will get the wrong
> device node.

oh, that makes things more interesting :-s

>> > That sounds a bit clumsy for the sake of consistency with PCI.
>> > The advantage is that xhci can always use the grandparent device
>> > as sysdev whenever it isn't probed through PCI or firmware
>> > itself, but the purpose of the dwc3-glue is otherwise questionable.
>> >
>> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>> > device when that is created from the PCI driver and checking for that
>> > with the device property interface instead? If it's "snps,dwc3"
>> > we use the device itself while for "snps,dwc3-pci", we use the parent?
>> 
>> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>
> That would be incompatible with the USB binding, as the sysdev
> is assumed to be a USB host controller with #address-cells=<1>
> and #size-cells=<0> in order to hold the child devices, for
> example:
>
> / {
>      omap_dwc3_1: omap_dwc3_1@48880000 {
>         compatible = "ti,dwc3";
>         #address-cells = <1>;
>         #size-cells = <1>;
>         ranges;
>         usb1: usb@48890000 {
>                 compatible = "snps,dwc3";
>                 reg = <0x48890000 0x17000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "peripheral",
>                                   "host",
>                                   "otg";
>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>                 phy-names = "usb2-phy", "usb3-phy";
>
>                 hub@1 {
>                         compatible = "usb5e3,608";
>                         reg = <1>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>
>                         ethernet@1 {
>                                 compatible = "usb424,ec00";
>                                 mac-address = [00 11 22 33 44 55];
>                                 reg = <1>;
>                         };
>                 };
>         };
> };
>
> It's also the node that contains the "phys" properties and
> presumably other properties like "otg-rev", "maximum-speed"
> etc.
>
> If we make the sysdev point to the parent, then we can no longer
> look up those properties and child devices from the USB core code
> by looking at "sysdev->of_node".

this also makes things more interesting. I can't of anything other than
having some type of flag passed via e.g. device_properties by dwc3-pci.c
:-s

It's quite a hack, though. I still think that inheriting DMA (or
manually initializing a child with parent's DMA bits and pieces) is the
best way to go. So we're back to of_dma_configure() and
acpi_dma_configure(), right?

But this needs to be done before dwc3_probe() executes. For dwc3-pci
that's easy, but for DT devices, seems like it should be in of
core. Below is, clearly, not enough but should show the idea:

diff --git a/drivers/of/device.c b/drivers/of/device.c
index fd5cfad7c403..a54610198946 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
         * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
         * setup the correct supported mask.
         */
-       if (!dev->coherent_dma_mask)
-               dev->coherent_dma_mask = DMA_BIT_MASK(32);
+       if (!dev->coherent_dma_mask) {
+               if (!dev->parent->coherent_dma_mask)
+                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
+               else
+                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
+       }
 
        /*
         * Set it to coherent_dma_mask by default if the architecture


-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 11:00                                                                     ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:00 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>> >> > If we do that, we have to put child devices of the dwc3 devices into
>> >> > the platform glue, and it also breaks those dwc3 devices that don't
>> >> > have a parent driver.
>> >> 
>> >> Well, this is easy to fix:
>> >> 
>> >>         if (dwc->dev->parent) {
>> >>                 dwc->sysdev = dwc->dev->parent;
>> >>         } else {
>> >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>> >>                 dwc->sysdev = dwc->dev;
>> >>         }
>> >
>> > I don't understand. Do you mean we should have an extra level of
>> > stacking and splitting "static struct platform_driver dwc3_driver"
>> > in two so instead of
>> >
>> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>> >
>> > we do this?
>> >
>> >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>> 
>> no 
>> 
>> If we have a parent device, use that as sysdev, otherwise use self as
>> sysdev.
>
> But there is often a parent device in DT, as the xhci device is
> attached to some internal bus that gets turned into a platform_device
> as well, so checking whether there is a parent will get the wrong
> device node.

oh, that makes things more interesting :-s

>> > That sounds a bit clumsy for the sake of consistency with PCI.
>> > The advantage is that xhci can always use the grandparent device
>> > as sysdev whenever it isn't probed through PCI or firmware
>> > itself, but the purpose of the dwc3-glue is otherwise questionable.
>> >
>> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>> > device when that is created from the PCI driver and checking for that
>> > with the device property interface instead? If it's "snps,dwc3"
>> > we use the device itself while for "snps,dwc3-pci", we use the parent?
>> 
>> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>
> That would be incompatible with the USB binding, as the sysdev
> is assumed to be a USB host controller with #address-cells=<1>
> and #size-cells=<0> in order to hold the child devices, for
> example:
>
> / {
>      omap_dwc3_1: omap_dwc3_1 at 48880000 {
>         compatible = "ti,dwc3";
>         #address-cells = <1>;
>         #size-cells = <1>;
>         ranges;
>         usb1: usb at 48890000 {
>                 compatible = "snps,dwc3";
>                 reg = <0x48890000 0x17000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "peripheral",
>                                   "host",
>                                   "otg";
>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>                 phy-names = "usb2-phy", "usb3-phy";
>
>                 hub at 1 {
>                         compatible = "usb5e3,608";
>                         reg = <1>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>
>                         ethernet at 1 {
>                                 compatible = "usb424,ec00";
>                                 mac-address = [00 11 22 33 44 55];
>                                 reg = <1>;
>                         };
>                 };
>         };
> };
>
> It's also the node that contains the "phys" properties and
> presumably other properties like "otg-rev", "maximum-speed"
> etc.
>
> If we make the sysdev point to the parent, then we can no longer
> look up those properties and child devices from the USB core code
> by looking at "sysdev->of_node".

this also makes things more interesting. I can't of anything other than
having some type of flag passed via e.g. device_properties by dwc3-pci.c
:-s

It's quite a hack, though. I still think that inheriting DMA (or
manually initializing a child with parent's DMA bits and pieces) is the
best way to go. So we're back to of_dma_configure() and
acpi_dma_configure(), right?

But this needs to be done before dwc3_probe() executes. For dwc3-pci
that's easy, but for DT devices, seems like it should be in of
core. Below is, clearly, not enough but should show the idea:

diff --git a/drivers/of/device.c b/drivers/of/device.c
index fd5cfad7c403..a54610198946 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
         * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
         * setup the correct supported mask.
         */
-       if (!dev->coherent_dma_mask)
-               dev->coherent_dma_mask = DMA_BIT_MASK(32);
+       if (!dev->coherent_dma_mask) {
+               if (!dev->parent->coherent_dma_mask)
+                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
+               else
+                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
+       }
 
        /*
         * Set it to coherent_dma_mask by default if the architecture


-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/db55c1fb/attachment.sig>

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:00                                                                     ` Felipe Balbi
@ 2016-09-08 11:11                                                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 11:11 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 2:00:13 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> >> Arnd Bergmann <arnd@arndb.de> writes:
> >> > That sounds a bit clumsy for the sake of consistency with PCI.
> >> > The advantage is that xhci can always use the grandparent device
> >> > as sysdev whenever it isn't probed through PCI or firmware
> >> > itself, but the purpose of the dwc3-glue is otherwise questionable.
> >> >
> >> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> >> > device when that is created from the PCI driver and checking for that
> >> > with the device property interface instead? If it's "snps,dwc3"
> >> > we use the device itself while for "snps,dwc3-pci", we use the parent?
> >> 
> >> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
> >
> > That would be incompatible with the USB binding, as the sysdev
> > is assumed to be a USB host controller with #address-cells=<1>
> > and #size-cells=<0> in order to hold the child devices, for
> > example:
> >
> > / {
> >      omap_dwc3_1: omap_dwc3_1@48880000 {
> >         compatible = "ti,dwc3";
> >         #address-cells = <1>;
> >         #size-cells = <1>;
> >         ranges;
> >         usb1: usb@48890000 {
> >                 compatible = "snps,dwc3";
> >                 reg = <0x48890000 0x17000>;
> >                 #address-cells = <1>;
> >                 #size-cells = <0>;
> >                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> >                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> >                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "peripheral",
> >                                   "host",
> >                                   "otg";
> >                 phys = <&usb2_phy1>, <&usb3_phy1>;
> >                 phy-names = "usb2-phy", "usb3-phy";
> >
> >                 hub@1 {
> >                         compatible = "usb5e3,608";
> >                         reg = <1>;
> >                         #address-cells = <1>;
> >                         #size-cells = <0>;
> >
> >                         ethernet@1 {
> >                                 compatible = "usb424,ec00";
> >                                 mac-address = [00 11 22 33 44 55];
> >                                 reg = <1>;
> >                         };
> >                 };
> >         };
> > };
> >
> > It's also the node that contains the "phys" properties and
> > presumably other properties like "otg-rev", "maximum-speed"
> > etc.
> >
> > If we make the sysdev point to the parent, then we can no longer
> > look up those properties and child devices from the USB core code
> > by looking at "sysdev->of_node".
> 
> this also makes things more interesting. I can't of anything other than
> having some type of flag passed via e.g. device_properties by dwc3-pci.c
> :-s

Ok.

> It's quite a hack, though. I still think that inheriting DMA (or
> manually initializing a child with parent's DMA bits and pieces) is the
> best way to go. So we're back to of_dma_configure() and
> acpi_dma_configure(), right?

That won't solve the problems with the DT properties or the
dma configuration for PCI devices though.

> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> that's easy, but for DT devices, seems like it should be in of
> core. Below is, clearly, not enough but should show the idea:
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..a54610198946 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>          * setup the correct supported mask.
>          */
> -       if (!dev->coherent_dma_mask)
> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +       if (!dev->coherent_dma_mask) {
> +               if (!dev->parent->coherent_dma_mask)
> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +               else
> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> +       }
>  

As the comment above that code says, the default 32-bit mask is intentional,
and you need the driver to ask for the mask it wants using
dma_set_mask_and_coherent(), while the platform code should be able to use
dev->of_node to figure out whether that mask is supported.

Just setting the initial mask to something else based on what the parent
supports will not do the right thing elsewhere.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 11:11                                                                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 2:00:13 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> >> Arnd Bergmann <arnd@arndb.de> writes:
> >> > That sounds a bit clumsy for the sake of consistency with PCI.
> >> > The advantage is that xhci can always use the grandparent device
> >> > as sysdev whenever it isn't probed through PCI or firmware
> >> > itself, but the purpose of the dwc3-glue is otherwise questionable.
> >> >
> >> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> >> > device when that is created from the PCI driver and checking for that
> >> > with the device property interface instead? If it's "snps,dwc3"
> >> > we use the device itself while for "snps,dwc3-pci", we use the parent?
> >> 
> >> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
> >
> > That would be incompatible with the USB binding, as the sysdev
> > is assumed to be a USB host controller with #address-cells=<1>
> > and #size-cells=<0> in order to hold the child devices, for
> > example:
> >
> > / {
> >      omap_dwc3_1: omap_dwc3_1 at 48880000 {
> >         compatible = "ti,dwc3";
> >         #address-cells = <1>;
> >         #size-cells = <1>;
> >         ranges;
> >         usb1: usb at 48890000 {
> >                 compatible = "snps,dwc3";
> >                 reg = <0x48890000 0x17000>;
> >                 #address-cells = <1>;
> >                 #size-cells = <0>;
> >                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> >                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> >                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> >                 interrupt-names = "peripheral",
> >                                   "host",
> >                                   "otg";
> >                 phys = <&usb2_phy1>, <&usb3_phy1>;
> >                 phy-names = "usb2-phy", "usb3-phy";
> >
> >                 hub at 1 {
> >                         compatible = "usb5e3,608";
> >                         reg = <1>;
> >                         #address-cells = <1>;
> >                         #size-cells = <0>;
> >
> >                         ethernet at 1 {
> >                                 compatible = "usb424,ec00";
> >                                 mac-address = [00 11 22 33 44 55];
> >                                 reg = <1>;
> >                         };
> >                 };
> >         };
> > };
> >
> > It's also the node that contains the "phys" properties and
> > presumably other properties like "otg-rev", "maximum-speed"
> > etc.
> >
> > If we make the sysdev point to the parent, then we can no longer
> > look up those properties and child devices from the USB core code
> > by looking at "sysdev->of_node".
> 
> this also makes things more interesting. I can't of anything other than
> having some type of flag passed via e.g. device_properties by dwc3-pci.c
> :-s

Ok.

> It's quite a hack, though. I still think that inheriting DMA (or
> manually initializing a child with parent's DMA bits and pieces) is the
> best way to go. So we're back to of_dma_configure() and
> acpi_dma_configure(), right?

That won't solve the problems with the DT properties or the
dma configuration for PCI devices though.

> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> that's easy, but for DT devices, seems like it should be in of
> core. Below is, clearly, not enough but should show the idea:
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..a54610198946 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>          * setup the correct supported mask.
>          */
> -       if (!dev->coherent_dma_mask)
> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +       if (!dev->coherent_dma_mask) {
> +               if (!dev->parent->coherent_dma_mask)
> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +               else
> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> +       }
>  

As the comment above that code says, the default 32-bit mask is intentional,
and you need the driver to ask for the mask it wants using
dma_set_mask_and_coherent(), while the platform code should be able to use
dev->of_node to figure out whether that mask is supported.

Just setting the initial mask to something else based on what the parent
supports will not do the right thing elsewhere.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:11                                                                       ` Arnd Bergmann
@ 2016-09-08 11:20                                                                         ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:20 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 5563 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 2:00:13 PM CEST Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>> >> Arnd Bergmann <arnd@arndb.de> writes:
>> >> > That sounds a bit clumsy for the sake of consistency with PCI.
>> >> > The advantage is that xhci can always use the grandparent device
>> >> > as sysdev whenever it isn't probed through PCI or firmware
>> >> > itself, but the purpose of the dwc3-glue is otherwise questionable.
>> >> >
>> >> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>> >> > device when that is created from the PCI driver and checking for that
>> >> > with the device property interface instead? If it's "snps,dwc3"
>> >> > we use the device itself while for "snps,dwc3-pci", we use the parent?
>> >> 
>> >> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>> >
>> > That would be incompatible with the USB binding, as the sysdev
>> > is assumed to be a USB host controller with #address-cells=<1>
>> > and #size-cells=<0> in order to hold the child devices, for
>> > example:
>> >
>> > / {
>> >      omap_dwc3_1: omap_dwc3_1@48880000 {
>> >         compatible = "ti,dwc3";
>> >         #address-cells = <1>;
>> >         #size-cells = <1>;
>> >         ranges;
>> >         usb1: usb@48890000 {
>> >                 compatible = "snps,dwc3";
>> >                 reg = <0x48890000 0x17000>;
>> >                 #address-cells = <1>;
>> >                 #size-cells = <0>;
>> >                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>> >                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>> >                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>> >                 interrupt-names = "peripheral",
>> >                                   "host",
>> >                                   "otg";
>> >                 phys = <&usb2_phy1>, <&usb3_phy1>;
>> >                 phy-names = "usb2-phy", "usb3-phy";
>> >
>> >                 hub@1 {
>> >                         compatible = "usb5e3,608";
>> >                         reg = <1>;
>> >                         #address-cells = <1>;
>> >                         #size-cells = <0>;
>> >
>> >                         ethernet@1 {
>> >                                 compatible = "usb424,ec00";
>> >                                 mac-address = [00 11 22 33 44 55];
>> >                                 reg = <1>;
>> >                         };
>> >                 };
>> >         };
>> > };
>> >
>> > It's also the node that contains the "phys" properties and
>> > presumably other properties like "otg-rev", "maximum-speed"
>> > etc.
>> >
>> > If we make the sysdev point to the parent, then we can no longer
>> > look up those properties and child devices from the USB core code
>> > by looking at "sysdev->of_node".
>> 
>> this also makes things more interesting. I can't of anything other than
>> having some type of flag passed via e.g. device_properties by dwc3-pci.c
>> :-s
>
> Ok.

man, I have been skipping words rather frequently when typing lately. I
meant "I can't THINK of anything other ...."

>> It's quite a hack, though. I still think that inheriting DMA (or
>> manually initializing a child with parent's DMA bits and pieces) is the
>> best way to go. So we're back to of_dma_configure() and
>> acpi_dma_configure(), right?
>
> That won't solve the problems with the DT properties or the
> dma configuration for PCI devices though.

acpi_dma_configure() is supposed to pass along DMA bits from PCI to
child devices, no?

>> But this needs to be done before dwc3_probe() executes. For dwc3-pci
>> that's easy, but for DT devices, seems like it should be in of
>> core. Below is, clearly, not enough but should show the idea:
>> 
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index fd5cfad7c403..a54610198946 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>>          * setup the correct supported mask.
>>          */
>> -       if (!dev->coherent_dma_mask)
>> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> +       if (!dev->coherent_dma_mask) {
>> +               if (!dev->parent->coherent_dma_mask)
>> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> +               else
>> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
>> +       }
>>  
>
> As the comment above that code says, the default 32-bit mask is intentional,
> and you need the driver to ask for the mask it wants using
> dma_set_mask_and_coherent(), while the platform code should be able to use
> dev->of_node to figure out whether that mask is supported.
>
> Just setting the initial mask to something else based on what the parent
> supports will not do the right thing elsewhere.

oh man, it gets more and more complex. Seems like either path we take
will cause problems somewhere :-s

If we make dwc3.ko a library which glue calls directly then all these
problems are solved but we break all current DTs and fall into the trap
of having another MUSB.

If we try to pass DMA bits from parent to child, then we have the fact
that DT ends up, in practice, always having a parent device.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 11:20                                                                         ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:20 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
> On Thursday, September 8, 2016 2:00:13 PM CEST Felipe Balbi wrote:
>> Arnd Bergmann <arnd@arndb.de> writes:
>> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>> >> Arnd Bergmann <arnd@arndb.de> writes:
>> >> > That sounds a bit clumsy for the sake of consistency with PCI.
>> >> > The advantage is that xhci can always use the grandparent device
>> >> > as sysdev whenever it isn't probed through PCI or firmware
>> >> > itself, but the purpose of the dwc3-glue is otherwise questionable.
>> >> >
>> >> > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>> >> > device when that is created from the PCI driver and checking for that
>> >> > with the device property interface instead? If it's "snps,dwc3"
>> >> > we use the device itself while for "snps,dwc3-pci", we use the parent?
>> >> 
>> >> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>> >
>> > That would be incompatible with the USB binding, as the sysdev
>> > is assumed to be a USB host controller with #address-cells=<1>
>> > and #size-cells=<0> in order to hold the child devices, for
>> > example:
>> >
>> > / {
>> >      omap_dwc3_1: omap_dwc3_1 at 48880000 {
>> >         compatible = "ti,dwc3";
>> >         #address-cells = <1>;
>> >         #size-cells = <1>;
>> >         ranges;
>> >         usb1: usb at 48890000 {
>> >                 compatible = "snps,dwc3";
>> >                 reg = <0x48890000 0x17000>;
>> >                 #address-cells = <1>;
>> >                 #size-cells = <0>;
>> >                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>> >                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>> >                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>> >                 interrupt-names = "peripheral",
>> >                                   "host",
>> >                                   "otg";
>> >                 phys = <&usb2_phy1>, <&usb3_phy1>;
>> >                 phy-names = "usb2-phy", "usb3-phy";
>> >
>> >                 hub at 1 {
>> >                         compatible = "usb5e3,608";
>> >                         reg = <1>;
>> >                         #address-cells = <1>;
>> >                         #size-cells = <0>;
>> >
>> >                         ethernet at 1 {
>> >                                 compatible = "usb424,ec00";
>> >                                 mac-address = [00 11 22 33 44 55];
>> >                                 reg = <1>;
>> >                         };
>> >                 };
>> >         };
>> > };
>> >
>> > It's also the node that contains the "phys" properties and
>> > presumably other properties like "otg-rev", "maximum-speed"
>> > etc.
>> >
>> > If we make the sysdev point to the parent, then we can no longer
>> > look up those properties and child devices from the USB core code
>> > by looking at "sysdev->of_node".
>> 
>> this also makes things more interesting. I can't of anything other than
>> having some type of flag passed via e.g. device_properties by dwc3-pci.c
>> :-s
>
> Ok.

man, I have been skipping words rather frequently when typing lately. I
meant "I can't THINK of anything other ...."

>> It's quite a hack, though. I still think that inheriting DMA (or
>> manually initializing a child with parent's DMA bits and pieces) is the
>> best way to go. So we're back to of_dma_configure() and
>> acpi_dma_configure(), right?
>
> That won't solve the problems with the DT properties or the
> dma configuration for PCI devices though.

acpi_dma_configure() is supposed to pass along DMA bits from PCI to
child devices, no?

>> But this needs to be done before dwc3_probe() executes. For dwc3-pci
>> that's easy, but for DT devices, seems like it should be in of
>> core. Below is, clearly, not enough but should show the idea:
>> 
>> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> index fd5cfad7c403..a54610198946 100644
>> --- a/drivers/of/device.c
>> +++ b/drivers/of/device.c
>> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>>          * setup the correct supported mask.
>>          */
>> -       if (!dev->coherent_dma_mask)
>> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> +       if (!dev->coherent_dma_mask) {
>> +               if (!dev->parent->coherent_dma_mask)
>> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> +               else
>> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
>> +       }
>>  
>
> As the comment above that code says, the default 32-bit mask is intentional,
> and you need the driver to ask for the mask it wants using
> dma_set_mask_and_coherent(), while the platform code should be able to use
> dev->of_node to figure out whether that mask is supported.
>
> Just setting the initial mask to something else based on what the parent
> supports will not do the right thing elsewhere.

oh man, it gets more and more complex. Seems like either path we take
will cause problems somewhere :-s

If we make dwc3.ko a library which glue calls directly then all these
problems are solved but we break all current DTs and fall into the trap
of having another MUSB.

If we try to pass DMA bits from parent to child, then we have the fact
that DT ends up, in practice, always having a parent device.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/1babda94/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:20                                                                         ` Felipe Balbi
@ 2016-09-08 11:39                                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 11:39 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 2:20:58 PM CEST Felipe Balbi wrote:
> >> It's quite a hack, though. I still think that inheriting DMA (or
> >> manually initializing a child with parent's DMA bits and pieces) is the
> >> best way to go. So we're back to of_dma_configure() and
> >> acpi_dma_configure(), right?
> >
> > That won't solve the problems with the DT properties or the
> > dma configuration for PCI devices though.
> 
> acpi_dma_configure() is supposed to pass along DMA bits from PCI to
> child devices, no?

I don't know, haven't looked at that code.

> >> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> >> that's easy, but for DT devices, seems like it should be in of
> >> core. Below is, clearly, not enough but should show the idea:
> >> 
> >> diff --git a/drivers/of/device.c b/drivers/of/device.c
> >> index fd5cfad7c403..a54610198946 100644
> >> --- a/drivers/of/device.c
> >> +++ b/drivers/of/device.c
> >> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
> >>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
> >>          * setup the correct supported mask.
> >>          */
> >> -       if (!dev->coherent_dma_mask)
> >> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> >> +       if (!dev->coherent_dma_mask) {
> >> +               if (!dev->parent->coherent_dma_mask)
> >> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> >> +               else
> >> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> >> +       }
> >>  
> >
> > As the comment above that code says, the default 32-bit mask is intentional,
> > and you need the driver to ask for the mask it wants using
> > dma_set_mask_and_coherent(), while the platform code should be able to use
> > dev->of_node to figure out whether that mask is supported.
> >
> > Just setting the initial mask to something else based on what the parent
> > supports will not do the right thing elsewhere.
> 
> oh man, it gets more and more complex. Seems like either path we take
> will cause problems somewhere 
> 
> If we make dwc3.ko a library which glue calls directly then all these
> problems are solved but we break all current DTs and fall into the trap
> of having another MUSB.

I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3
into a library without changing the DT representation. However the parts
that I think would change are

- The sysfs representation for dwc3-pci, as we would no longer have
  a parent-child relationship there.
- The power management handling might need a rework, since you currently
  rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
  power on and off
- turning dwc3 into a library probably implies also turning xhci into
  a library, in part for consistency.
- if we don't do the whole usb_bus->sysdev thing, we need to not just
  do this for dwc3 but also chipidea and maybe a couple of others.

There should not be any show-stoppers here, but it's a lot of work.

> If we try to pass DMA bits from parent to child, then we have the fact
> that DT ends up, in practice, always having a parent device.

I don't understand what you mean here, but I agree that the various ways
we discussed for copying the DMA flags from one 'struct device' to another
all turned out to be flawed in at least one way.

Do you see any problems with the patch I posted other than the ugliness
of the dwc3 and xhci drivers finding out which pointer to use for
usb_bus->sysdev? If we can solve this, we shouldn't need any new
of_dma_configure/acpi_dma_configure calls and we won't have to
turn the drivers into a library, so maybe let's try to come up with
better ideas for that sub-problem.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 11:39                                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 11:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 2:20:58 PM CEST Felipe Balbi wrote:
> >> It's quite a hack, though. I still think that inheriting DMA (or
> >> manually initializing a child with parent's DMA bits and pieces) is the
> >> best way to go. So we're back to of_dma_configure() and
> >> acpi_dma_configure(), right?
> >
> > That won't solve the problems with the DT properties or the
> > dma configuration for PCI devices though.
> 
> acpi_dma_configure() is supposed to pass along DMA bits from PCI to
> child devices, no?

I don't know, haven't looked at that code.

> >> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> >> that's easy, but for DT devices, seems like it should be in of
> >> core. Below is, clearly, not enough but should show the idea:
> >> 
> >> diff --git a/drivers/of/device.c b/drivers/of/device.c
> >> index fd5cfad7c403..a54610198946 100644
> >> --- a/drivers/of/device.c
> >> +++ b/drivers/of/device.c
> >> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
> >>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
> >>          * setup the correct supported mask.
> >>          */
> >> -       if (!dev->coherent_dma_mask)
> >> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> >> +       if (!dev->coherent_dma_mask) {
> >> +               if (!dev->parent->coherent_dma_mask)
> >> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> >> +               else
> >> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> >> +       }
> >>  
> >
> > As the comment above that code says, the default 32-bit mask is intentional,
> > and you need the driver to ask for the mask it wants using
> > dma_set_mask_and_coherent(), while the platform code should be able to use
> > dev->of_node to figure out whether that mask is supported.
> >
> > Just setting the initial mask to something else based on what the parent
> > supports will not do the right thing elsewhere.
> 
> oh man, it gets more and more complex. Seems like either path we take
> will cause problems somewhere 
> 
> If we make dwc3.ko a library which glue calls directly then all these
> problems are solved but we break all current DTs and fall into the trap
> of having another MUSB.

I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3
into a library without changing the DT representation. However the parts
that I think would change are

- The sysfs representation for dwc3-pci, as we would no longer have
  a parent-child relationship there.
- The power management handling might need a rework, since you currently
  rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
  power on and off
- turning dwc3 into a library probably implies also turning xhci into
  a library, in part for consistency.
- if we don't do the whole usb_bus->sysdev thing, we need to not just
  do this for dwc3 but also chipidea and maybe a couple of others.

There should not be any show-stoppers here, but it's a lot of work.

> If we try to pass DMA bits from parent to child, then we have the fact
> that DT ends up, in practice, always having a parent device.

I don't understand what you mean here, but I agree that the various ways
we discussed for copying the DMA flags from one 'struct device' to another
all turned out to be flawed in at least one way.

Do you see any problems with the patch I posted other than the ugliness
of the dwc3 and xhci drivers finding out which pointer to use for
usb_bus->sysdev? If we can solve this, we shouldn't need any new
of_dma_configure/acpi_dma_configure calls and we won't have to
turn the drivers into a library, so maybe let's try to come up with
better ideas for that sub-problem.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:39                                                                           ` Arnd Bergmann
@ 2016-09-08 11:52                                                                             ` Felipe Balbi
  -1 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 4536 bytes --]


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> >> But this needs to be done before dwc3_probe() executes. For dwc3-pci
>> >> that's easy, but for DT devices, seems like it should be in of
>> >> core. Below is, clearly, not enough but should show the idea:
>> >> 
>> >> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> >> index fd5cfad7c403..a54610198946 100644
>> >> --- a/drivers/of/device.c
>> >> +++ b/drivers/of/device.c
>> >> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>> >>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>> >>          * setup the correct supported mask.
>> >>          */
>> >> -       if (!dev->coherent_dma_mask)
>> >> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> >> +       if (!dev->coherent_dma_mask) {
>> >> +               if (!dev->parent->coherent_dma_mask)
>> >> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> >> +               else
>> >> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
>> >> +       }
>> >>  
>> >
>> > As the comment above that code says, the default 32-bit mask is intentional,
>> > and you need the driver to ask for the mask it wants using
>> > dma_set_mask_and_coherent(), while the platform code should be able to use
>> > dev->of_node to figure out whether that mask is supported.
>> >
>> > Just setting the initial mask to something else based on what the parent
>> > supports will not do the right thing elsewhere.
>> 
>> oh man, it gets more and more complex. Seems like either path we take
>> will cause problems somewhere 
>> 
>> If we make dwc3.ko a library which glue calls directly then all these
>> problems are solved but we break all current DTs and fall into the trap
>> of having another MUSB.
>
> I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3

well, at a minimum dwc3-{pci,exynos,st,omap,of-simple}.c would have to
look at possible children for their own quirks and properties.

> into a library without changing the DT representation. However the parts
> that I think would change are
>
> - The sysfs representation for dwc3-pci, as we would no longer have
>   a parent-child relationship there.

that's a no-brainer, I think

> - The power management handling might need a rework, since you currently
>   rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
>   power on and off

simple enough to do as well.

> - turning dwc3 into a library probably implies also turning xhci into
>   a library, in part for consistency.

yeah, I considered that too. We could still do it in parts, though.

> - if we don't do the whole usb_bus->sysdev thing, we need to not just
>   do this for dwc3 but also chipidea and maybe a couple of others.

MUSB comes to mind

> There should not be any show-stoppers here, but it's a lot of work.

I think the biggest work will making sure people don't abuse functions
just because they're now part of a single binary. Having them as
separate modules helped a lot reducing the maintenance overhead. There
was only one occasion where someone sent a glue layer which iterated
over its children to find struct dwc3 * from child's drvdata.

>> If we try to pass DMA bits from parent to child, then we have the fact
>> that DT ends up, in practice, always having a parent device.
>
> I don't understand what you mean here, but I agree that the various ways

well, we can't simply use what I pointed out a few emails back:

if (dwc->dev->parent)
	dwc->sysdev = dwc->dev->parent
else
	dwc->sysdev = dwc->dev

> we discussed for copying the DMA flags from one 'struct device' to another
> all turned out to be flawed in at least one way.
>
> Do you see any problems with the patch I posted other than the ugliness
> of the dwc3 and xhci drivers finding out which pointer to use for
> usb_bus->sysdev? If we can solve this, we shouldn't need any new
> of_dma_configure/acpi_dma_configure calls and we won't have to
> turn the drivers into a library, so maybe let's try to come up with
> better ideas for that sub-problem.

No big problems with that, no. Just the ifdef looking for a PCI bus in
the parent. How about passing a flag via device_properties? I don't
wanna change dwc3 core's device name with a platform_device_id because
there probably already are scripts relying on the names to enable
pm_runtime for example.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 11:52                                                                             ` Felipe Balbi
  0 siblings, 0 replies; 182+ messages in thread
From: Felipe Balbi @ 2016-09-08 11:52 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

Arnd Bergmann <arnd@arndb.de> writes:
>> >> But this needs to be done before dwc3_probe() executes. For dwc3-pci
>> >> that's easy, but for DT devices, seems like it should be in of
>> >> core. Below is, clearly, not enough but should show the idea:
>> >> 
>> >> diff --git a/drivers/of/device.c b/drivers/of/device.c
>> >> index fd5cfad7c403..a54610198946 100644
>> >> --- a/drivers/of/device.c
>> >> +++ b/drivers/of/device.c
>> >> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>> >>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>> >>          * setup the correct supported mask.
>> >>          */
>> >> -       if (!dev->coherent_dma_mask)
>> >> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> >> +       if (!dev->coherent_dma_mask) {
>> >> +               if (!dev->parent->coherent_dma_mask)
>> >> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
>> >> +               else
>> >> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
>> >> +       }
>> >>  
>> >
>> > As the comment above that code says, the default 32-bit mask is intentional,
>> > and you need the driver to ask for the mask it wants using
>> > dma_set_mask_and_coherent(), while the platform code should be able to use
>> > dev->of_node to figure out whether that mask is supported.
>> >
>> > Just setting the initial mask to something else based on what the parent
>> > supports will not do the right thing elsewhere.
>> 
>> oh man, it gets more and more complex. Seems like either path we take
>> will cause problems somewhere 
>> 
>> If we make dwc3.ko a library which glue calls directly then all these
>> problems are solved but we break all current DTs and fall into the trap
>> of having another MUSB.
>
> I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3

well, at a minimum dwc3-{pci,exynos,st,omap,of-simple}.c would have to
look at possible children for their own quirks and properties.

> into a library without changing the DT representation. However the parts
> that I think would change are
>
> - The sysfs representation for dwc3-pci, as we would no longer have
>   a parent-child relationship there.

that's a no-brainer, I think

> - The power management handling might need a rework, since you currently
>   rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
>   power on and off

simple enough to do as well.

> - turning dwc3 into a library probably implies also turning xhci into
>   a library, in part for consistency.

yeah, I considered that too. We could still do it in parts, though.

> - if we don't do the whole usb_bus->sysdev thing, we need to not just
>   do this for dwc3 but also chipidea and maybe a couple of others.

MUSB comes to mind

> There should not be any show-stoppers here, but it's a lot of work.

I think the biggest work will making sure people don't abuse functions
just because they're now part of a single binary. Having them as
separate modules helped a lot reducing the maintenance overhead. There
was only one occasion where someone sent a glue layer which iterated
over its children to find struct dwc3 * from child's drvdata.

>> If we try to pass DMA bits from parent to child, then we have the fact
>> that DT ends up, in practice, always having a parent device.
>
> I don't understand what you mean here, but I agree that the various ways

well, we can't simply use what I pointed out a few emails back:

if (dwc->dev->parent)
	dwc->sysdev = dwc->dev->parent
else
	dwc->sysdev = dwc->dev

> we discussed for copying the DMA flags from one 'struct device' to another
> all turned out to be flawed in at least one way.
>
> Do you see any problems with the patch I posted other than the ugliness
> of the dwc3 and xhci drivers finding out which pointer to use for
> usb_bus->sysdev? If we can solve this, we shouldn't need any new
> of_dma_configure/acpi_dma_configure calls and we won't have to
> turn the drivers into a library, so maybe let's try to come up with
> better ideas for that sub-problem.

No big problems with that, no. Just the ifdef looking for a PCI bus in
the parent. How about passing a flag via device_properties? I don't
wanna change dwc3 core's device name with a platform_device_id because
there probably already are scripts relying on the names to enable
pm_runtime for example.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160908/47b9c31c/attachment.sig>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:00                                                                     ` Felipe Balbi
@ 2016-09-08 12:02                                                                       ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-08 12:02 UTC (permalink / raw)
  To: Felipe Balbi, Arnd Bergmann
  Cc: Peter Chen, Leo Li, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel

On 09/08/2016 02:00 PM, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>>> Arnd Bergmann <arnd@arndb.de> writes:
>>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>>>>>> If we do that, we have to put child devices of the dwc3 devices into
>>>>>> the platform glue, and it also breaks those dwc3 devices that don't
>>>>>> have a parent driver.
>>>>>
>>>>> Well, this is easy to fix:
>>>>>
>>>>>         if (dwc->dev->parent) {
>>>>>                 dwc->sysdev = dwc->dev->parent;
>>>>>         } else {
>>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>>>>                 dwc->sysdev = dwc->dev;
>>>>>         }
>>>>
>>>> I don't understand. Do you mean we should have an extra level of
>>>> stacking and splitting "static struct platform_driver dwc3_driver"
>>>> in two so instead of
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>>>>
>>>> we do this?
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>>>
>>> no 
>>>
>>> If we have a parent device, use that as sysdev, otherwise use self as
>>> sysdev.
>>
>> But there is often a parent device in DT, as the xhci device is
>> attached to some internal bus that gets turned into a platform_device
>> as well, so checking whether there is a parent will get the wrong
>> device node.
> 
> oh, that makes things more interesting :-s
> 
>>>> That sounds a bit clumsy for the sake of consistency with PCI.
>>>> The advantage is that xhci can always use the grandparent device
>>>> as sysdev whenever it isn't probed through PCI or firmware
>>>> itself, but the purpose of the dwc3-glue is otherwise questionable.
>>>>
>>>> How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>>>> device when that is created from the PCI driver and checking for that
>>>> with the device property interface instead? If it's "snps,dwc3"
>>>> we use the device itself while for "snps,dwc3-pci", we use the parent?
>>>
>>> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>>
>> That would be incompatible with the USB binding, as the sysdev
>> is assumed to be a USB host controller with #address-cells=<1>
>> and #size-cells=<0> in order to hold the child devices, for
>> example:
>>
>> / {
>>      omap_dwc3_1: omap_dwc3_1@48880000 {
>>         compatible = "ti,dwc3";
>>         #address-cells = <1>;
>>         #size-cells = <1>;
>>         ranges;
>>         usb1: usb@48890000 {
>>                 compatible = "snps,dwc3";
>>                 reg = <0x48890000 0x17000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>>                 interrupt-names = "peripheral",
>>                                   "host",
>>                                   "otg";
>>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>>                 phy-names = "usb2-phy", "usb3-phy";
>>
>>                 hub@1 {
>>                         compatible = "usb5e3,608";
>>                         reg = <1>;
>>                         #address-cells = <1>;
>>                         #size-cells = <0>;
>>
>>                         ethernet@1 {
>>                                 compatible = "usb424,ec00";
>>                                 mac-address = [00 11 22 33 44 55];
>>                                 reg = <1>;
>>                         };
>>                 };
>>         };
>> };
>>
>> It's also the node that contains the "phys" properties and
>> presumably other properties like "otg-rev", "maximum-speed"
>> etc.
>>
>> If we make the sysdev point to the parent, then we can no longer
>> look up those properties and child devices from the USB core code
>> by looking at "sysdev->of_node".
> 
> this also makes things more interesting. I can't of anything other than
> having some type of flag passed via e.g. device_properties by dwc3-pci.c
> :-s
> 
> It's quite a hack, though. I still think that inheriting DMA (or
> manually initializing a child with parent's DMA bits and pieces) is the
> best way to go. So we're back to of_dma_configure() and
> acpi_dma_configure(), right?
> 
> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> that's easy, but for DT devices, seems like it should be in of
> core. Below is, clearly, not enough but should show the idea:
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..a54610198946 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>          * setup the correct supported mask.
>          */
> -       if (!dev->coherent_dma_mask)
> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +       if (!dev->coherent_dma_mask) {
> +               if (!dev->parent->coherent_dma_mask)
> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +               else
> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> +       }
>  
>         /*
>          * Set it to coherent_dma_mask by default if the architecture
> 
> 

I'd like to clarify few points here:
- the default  dma_mask = DMA_BIT_MASK(32); assigned here to keep
 backward compatibility with existing DT files at the moment when 
of_dma_configure() has been introduced and it satisfies most of the cases
- if HW require specific DMA configuration then "dma-ranges" property have to be
defined and of_dma_configure() will take care of it just few lines down.
including parent-child case - as it will try to find "dma-ranes" prop in parent node
when called for child dev.

Personally, I think Arnd's approach should work, if the problem of selecting of proper 
sysdev/dma_dev device will be solved.

Wouldn't it work if is_device_dma_capable() will be used?

For DT-case, the device DMA properties have to be configured from DT. So, now
there are 2 cases for dwc3:
1) dwc3-glue (of_dma)
   |- dwc3 (of_dma)
      |- xhci-plat (manual)
 better to use dwc3-glue as sysdev, but can use dwc3 also

2) (arch/arm/boot/dts/ls1021a.dtsi)
  |- dwc3 (of_dma)
      |- xhci-plat (manual)
 need to use dwc3 as sysdev
  

dwc3: probe()
	if (!&pdev->dev->of_node)
		 legacy case - hard-code DMA props
		dwc->sysdev = &pdev->dev;
	else
		dev = &pdev->dev;
		do {
			if (is_device_dma_capable(dev)) {
				dwc->sysdev = dev;
				break;
			}
		   dev = dev->parent;
		while (dev);
		^this cycle can be limited in depth (2 for PCI)
	
	if (!dwc->sysdev)
		oops;

xhci_plat_probe:
	do the same

Wouldn't above work for other cases PCI/ACPI?

	


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:02                                                                       ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-08 12:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/08/2016 02:00 PM, Felipe Balbi wrote:
> 
> Hi,
> 
> Arnd Bergmann <arnd@arndb.de> writes:
>> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>>> Arnd Bergmann <arnd@arndb.de> writes:
>>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>>>>>> If we do that, we have to put child devices of the dwc3 devices into
>>>>>> the platform glue, and it also breaks those dwc3 devices that don't
>>>>>> have a parent driver.
>>>>>
>>>>> Well, this is easy to fix:
>>>>>
>>>>>         if (dwc->dev->parent) {
>>>>>                 dwc->sysdev = dwc->dev->parent;
>>>>>         } else {
>>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>>>>                 dwc->sysdev = dwc->dev;
>>>>>         }
>>>>
>>>> I don't understand. Do you mean we should have an extra level of
>>>> stacking and splitting "static struct platform_driver dwc3_driver"
>>>> in two so instead of
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>>>>
>>>> we do this?
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>>>
>>> no 
>>>
>>> If we have a parent device, use that as sysdev, otherwise use self as
>>> sysdev.
>>
>> But there is often a parent device in DT, as the xhci device is
>> attached to some internal bus that gets turned into a platform_device
>> as well, so checking whether there is a parent will get the wrong
>> device node.
> 
> oh, that makes things more interesting :-s
> 
>>>> That sounds a bit clumsy for the sake of consistency with PCI.
>>>> The advantage is that xhci can always use the grandparent device
>>>> as sysdev whenever it isn't probed through PCI or firmware
>>>> itself, but the purpose of the dwc3-glue is otherwise questionable.
>>>>
>>>> How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
>>>> device when that is created from the PCI driver and checking for that
>>>> with the device property interface instead? If it's "snps,dwc3"
>>>> we use the device itself while for "snps,dwc3-pci", we use the parent?
>>>
>>> Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
>>
>> That would be incompatible with the USB binding, as the sysdev
>> is assumed to be a USB host controller with #address-cells=<1>
>> and #size-cells=<0> in order to hold the child devices, for
>> example:
>>
>> / {
>>      omap_dwc3_1: omap_dwc3_1 at 48880000 {
>>         compatible = "ti,dwc3";
>>         #address-cells = <1>;
>>         #size-cells = <1>;
>>         ranges;
>>         usb1: usb at 48890000 {
>>                 compatible = "snps,dwc3";
>>                 reg = <0x48890000 0x17000>;
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>>                 interrupt-names = "peripheral",
>>                                   "host",
>>                                   "otg";
>>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>>                 phy-names = "usb2-phy", "usb3-phy";
>>
>>                 hub at 1 {
>>                         compatible = "usb5e3,608";
>>                         reg = <1>;
>>                         #address-cells = <1>;
>>                         #size-cells = <0>;
>>
>>                         ethernet at 1 {
>>                                 compatible = "usb424,ec00";
>>                                 mac-address = [00 11 22 33 44 55];
>>                                 reg = <1>;
>>                         };
>>                 };
>>         };
>> };
>>
>> It's also the node that contains the "phys" properties and
>> presumably other properties like "otg-rev", "maximum-speed"
>> etc.
>>
>> If we make the sysdev point to the parent, then we can no longer
>> look up those properties and child devices from the USB core code
>> by looking at "sysdev->of_node".
> 
> this also makes things more interesting. I can't of anything other than
> having some type of flag passed via e.g. device_properties by dwc3-pci.c
> :-s
> 
> It's quite a hack, though. I still think that inheriting DMA (or
> manually initializing a child with parent's DMA bits and pieces) is the
> best way to go. So we're back to of_dma_configure() and
> acpi_dma_configure(), right?
> 
> But this needs to be done before dwc3_probe() executes. For dwc3-pci
> that's easy, but for DT devices, seems like it should be in of
> core. Below is, clearly, not enough but should show the idea:
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index fd5cfad7c403..a54610198946 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -94,8 +94,12 @@ void of_dma_configure(struct device *dev, struct device_node *np)
>          * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
>          * setup the correct supported mask.
>          */
> -       if (!dev->coherent_dma_mask)
> -               dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +       if (!dev->coherent_dma_mask) {
> +               if (!dev->parent->coherent_dma_mask)
> +                       dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +               else
> +                       dev->coherent_dma_mask = dev->parent->coherent_dma_mask;
> +       }
>  
>         /*
>          * Set it to coherent_dma_mask by default if the architecture
> 
> 

I'd like to clarify few points here:
- the default  dma_mask = DMA_BIT_MASK(32); assigned here to keep
 backward compatibility with existing DT files at the moment when 
of_dma_configure() has been introduced and it satisfies most of the cases
- if HW require specific DMA configuration then "dma-ranges" property have to be
defined and of_dma_configure() will take care of it just few lines down.
including parent-child case - as it will try to find "dma-ranes" prop in parent node
when called for child dev.

Personally, I think Arnd's approach should work, if the problem of selecting of proper 
sysdev/dma_dev device will be solved.

Wouldn't it work if is_device_dma_capable() will be used?

For DT-case, the device DMA properties have to be configured from DT. So, now
there are 2 cases for dwc3:
1) dwc3-glue (of_dma)
   |- dwc3 (of_dma)
      |- xhci-plat (manual)
 better to use dwc3-glue as sysdev, but can use dwc3 also

2) (arch/arm/boot/dts/ls1021a.dtsi)
  |- dwc3 (of_dma)
      |- xhci-plat (manual)
 need to use dwc3 as sysdev
  

dwc3: probe()
	if (!&pdev->dev->of_node)
		 legacy case - hard-code DMA props
		dwc->sysdev = &pdev->dev;
	else
		dev = &pdev->dev;
		do {
			if (is_device_dma_capable(dev)) {
				dwc->sysdev = dev;
				break;
			}
		   dev = dev->parent;
		while (dev);
		^this cycle can be limited in depth (2 for PCI)
	
	if (!dwc->sysdev)
		oops;

xhci_plat_probe:
	do the same

Wouldn't above work for other cases PCI/ACPI?

	


-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 12:02                                                                       ` Grygorii Strashko
@ 2016-09-08 12:14                                                                         ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:14 UTC (permalink / raw)
  To: Grygorii Strashko
  Cc: Felipe Balbi, Peter Chen, Leo Li, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 3:02:56 PM CEST Grygorii Strashko wrote:
> dwc3: probe()
>         if (!&pdev->dev->of_node)
>                  legacy case - hard-code DMA props
>                 dwc->sysdev = &pdev->dev;

The PCI case will fall into this too, as we almost never have an
->of_node pointer for a PCI device.

Do we actually have any legacy dwc3 users in Linux that are neither DT
nor PCI based? Maybe we can just skip that.

>         else
>                 dev = &pdev->dev;
>                 do {
>                         if (is_device_dma_capable(dev)) {
>                                 dwc->sysdev = dev;
>                                 break;
>                         }
>                    dev = dev->parent;
>                 while (dev);
>                 ^this cycle can be limited in depth (2 for PCI)

Right, this could work by itself and looks generic enough.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:14                                                                         ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 3:02:56 PM CEST Grygorii Strashko wrote:
> dwc3: probe()
>         if (!&pdev->dev->of_node)
>                  legacy case - hard-code DMA props
>                 dwc->sysdev = &pdev->dev;

The PCI case will fall into this too, as we almost never have an
->of_node pointer for a PCI device.

Do we actually have any legacy dwc3 users in Linux that are neither DT
nor PCI based? Maybe we can just skip that.

>         else
>                 dev = &pdev->dev;
>                 do {
>                         if (is_device_dma_capable(dev)) {
>                                 dwc->sysdev = dev;
>                                 break;
>                         }
>                    dev = dev->parent;
>                 while (dev);
>                 ^this cycle can be limited in depth (2 for PCI)

Right, this could work by itself and looks generic enough.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 10:17                                                                   ` Arnd Bergmann
@ 2016-09-08 12:28                                                                     ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-08 12:28 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel

On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > Arnd Bergmann <arnd@arndb.de> writes:
> > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > >> > If we do that, we have to put child devices of the dwc3 devices into
> > >> > the platform glue, and it also breaks those dwc3 devices that don't
> > >> > have a parent driver.
> > >> 
> > >> Well, this is easy to fix:
> > >> 
> > >>         if (dwc->dev->parent) {
> > >>                 dwc->sysdev = dwc->dev->parent;
> > >>         } else {
> > >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> > >>                 dwc->sysdev = dwc->dev;
> > >>         }
> > >
> > > I don't understand. Do you mean we should have an extra level of
> > > stacking and splitting "static struct platform_driver dwc3_driver"
> > > in two so instead of
> > >
> > >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> > >
> > > we do this?
> > >
> > >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> > 
> > no 
> > 
> > If we have a parent device, use that as sysdev, otherwise use self as
> > sysdev.
> 
> But there is often a parent device in DT, as the xhci device is
> attached to some internal bus that gets turned into a platform_device
> as well, so checking whether there is a parent will get the wrong
> device node.

>From my point, all platform and firmware information at dwc3 are
correct, so we don't need to change dwc3/core.c, only changing for
xhci-plat.c is ok.

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ed56bf9..fd57c0d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	struct clk              *clk;
 	int			ret;
 	int			irq;
+	struct device *dev = &pdev->dev, *sysdev;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
+	if (dev->parent) {
+		sysdev = dev->parent;
+	} else {
+        	sysdev = dev;
+	}
+
 	/* Try to set 64-bit DMA first */
 	if (WARN_ON(!pdev->dev.dma_mask))
 		/* Platform did not initialize dma_mask */
@@ -170,7 +177,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
+			dev_name(&pdev->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index d2e3f65..563600b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 		/* Did the HC die before the root hub was registered? */
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
-		usb_dev->dev.of_node = parent_dev->of_node;
+		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
 	}
 	mutex_unlock(&usb_bus_idr_lock);

At above changes, the root hub's of_node equals to xhci-hcd sysdev's
of_node, which is from firmware or from its parent (it is dwc3 core
device).

> 
> > > That sounds a bit clumsy for the sake of consistency with PCI.
> > > The advantage is that xhci can always use the grandparent device
> > > as sysdev whenever it isn't probed through PCI or firmware
> > > itself, but the purpose of the dwc3-glue is otherwise questionable.
> > >
> > > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > > device when that is created from the PCI driver and checking for that
> > > with the device property interface instead? If it's "snps,dwc3"
> > > we use the device itself while for "snps,dwc3-pci", we use the parent?
> > 

For pci glue device, it is always the parent for dwc3 core device.
In your patch, you may not need to split pci or non-pci, just using
if (dev->parent).

> > Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
> 
> That would be incompatible with the USB binding, as the sysdev
> is assumed to be a USB host controller with #address-cells=<1>
> and #size-cells=<0> in order to hold the child devices, for
> example:
> 
> / {
>      omap_dwc3_1: omap_dwc3_1@48880000 {
>         compatible = "ti,dwc3";
>         #address-cells = <1>;
>         #size-cells = <1>;
>         ranges;
>         usb1: usb@48890000 {
>                 compatible = "snps,dwc3";
>                 reg = <0x48890000 0x17000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "peripheral",
>                                   "host",
>                                   "otg";
>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>                 phy-names = "usb2-phy", "usb3-phy";
> 
>                 hub@1 {
>                         compatible = "usb5e3,608";
>                         reg = <1>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> 
>                         ethernet@1 {
>                                 compatible = "usb424,ec00";
>                                 mac-address = [00 11 22 33 44 55];
>                                 reg = <1>;
>                         };
>                 };
>         };
> };
> 

With my above changes, the hub of_node should be found since it is
child of root hub's of_node which is the dwc3's of_node.

> It's also the node that contains the "phys" properties and
> presumably other properties like "otg-rev", "maximum-speed"
> etc.
> 

This information is described at dwc3 core device of_node, and be
handled at dwc3/core.c

-- 

Best Regards,
Peter Chen

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:28                                                                     ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-08 12:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > Arnd Bergmann <arnd@arndb.de> writes:
> > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > >> > If we do that, we have to put child devices of the dwc3 devices into
> > >> > the platform glue, and it also breaks those dwc3 devices that don't
> > >> > have a parent driver.
> > >> 
> > >> Well, this is easy to fix:
> > >> 
> > >>         if (dwc->dev->parent) {
> > >>                 dwc->sysdev = dwc->dev->parent;
> > >>         } else {
> > >>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> > >>                 dwc->sysdev = dwc->dev;
> > >>         }
> > >
> > > I don't understand. Do you mean we should have an extra level of
> > > stacking and splitting "static struct platform_driver dwc3_driver"
> > > in two so instead of
> > >
> > >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> > >
> > > we do this?
> > >
> > >       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> > 
> > no 
> > 
> > If we have a parent device, use that as sysdev, otherwise use self as
> > sysdev.
> 
> But there is often a parent device in DT, as the xhci device is
> attached to some internal bus that gets turned into a platform_device
> as well, so checking whether there is a parent will get the wrong
> device node.

>From my point, all platform and firmware information at dwc3 are
correct, so we don't need to change dwc3/core.c, only changing for
xhci-plat.c is ok.

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ed56bf9..fd57c0d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	struct clk              *clk;
 	int			ret;
 	int			irq;
+	struct device *dev = &pdev->dev, *sysdev;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
+	if (dev->parent) {
+		sysdev = dev->parent;
+	} else {
+        	sysdev = dev;
+	}
+
 	/* Try to set 64-bit DMA first */
 	if (WARN_ON(!pdev->dev.dma_mask))
 		/* Platform did not initialize dma_mask */
@@ -170,7 +177,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
+			dev_name(&pdev->dev), NULL);
 	if (!hcd)
 		return -ENOMEM;
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index d2e3f65..563600b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 		/* Did the HC die before the root hub was registered? */
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
-		usb_dev->dev.of_node = parent_dev->of_node;
+		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
 	}
 	mutex_unlock(&usb_bus_idr_lock);

At above changes, the root hub's of_node equals to xhci-hcd sysdev's
of_node, which is from firmware or from its parent (it is dwc3 core
device).

> 
> > > That sounds a bit clumsy for the sake of consistency with PCI.
> > > The advantage is that xhci can always use the grandparent device
> > > as sysdev whenever it isn't probed through PCI or firmware
> > > itself, but the purpose of the dwc3-glue is otherwise questionable.
> > >
> > > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > > device when that is created from the PCI driver and checking for that
> > > with the device property interface instead? If it's "snps,dwc3"
> > > we use the device itself while for "snps,dwc3-pci", we use the parent?
> > 

For pci glue device, it is always the parent for dwc3 core device.
In your patch, you may not need to split pci or non-pci, just using
if (dev->parent).

> > Any reason why we wouldn't use e.g. dwc3-omap.dev as sysdev?
> 
> That would be incompatible with the USB binding, as the sysdev
> is assumed to be a USB host controller with #address-cells=<1>
> and #size-cells=<0> in order to hold the child devices, for
> example:
> 
> / {
>      omap_dwc3_1: omap_dwc3_1 at 48880000 {
>         compatible = "ti,dwc3";
>         #address-cells = <1>;
>         #size-cells = <1>;
>         ranges;
>         usb1: usb at 48890000 {
>                 compatible = "snps,dwc3";
>                 reg = <0x48890000 0x17000>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>                              <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>                 interrupt-names = "peripheral",
>                                   "host",
>                                   "otg";
>                 phys = <&usb2_phy1>, <&usb3_phy1>;
>                 phy-names = "usb2-phy", "usb3-phy";
> 
>                 hub at 1 {
>                         compatible = "usb5e3,608";
>                         reg = <1>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> 
>                         ethernet at 1 {
>                                 compatible = "usb424,ec00";
>                                 mac-address = [00 11 22 33 44 55];
>                                 reg = <1>;
>                         };
>                 };
>         };
> };
> 

With my above changes, the hub of_node should be found since it is
child of root hub's of_node which is the dwc3's of_node.

> It's also the node that contains the "phys" properties and
> presumably other properties like "otg-rev", "maximum-speed"
> etc.
> 

This information is described at dwc3 core device of_node, and be
handled at dwc3/core.c

-- 

Best Regards,
Peter Chen

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 11:52                                                                             ` Felipe Balbi
@ 2016-09-08 12:46                                                                               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:46 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thursday, September 8, 2016 2:52:46 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> >> If we make dwc3.ko a library which glue calls directly then all these
> >> problems are solved but we break all current DTs and fall into the trap
> >> of having another MUSB.
> >
> > I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3
> 
> well, at a minimum dwc3-{pci,exynos,st,omap,of-simple}.c would have to
> look at possible children for their own quirks and properties.
> 
> > into a library without changing the DT representation. However the parts
> > that I think would change are
> >
> > - The sysfs representation for dwc3-pci, as we would no longer have
> >   a parent-child relationship there.
> 
> that's a no-brainer, I think
> 
> > - The power management handling might need a rework, since you currently
> >   rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
> >   power on and off
> 
> simple enough to do as well.
> 
> > - turning dwc3 into a library probably implies also turning xhci into
> >   a library, in part for consistency.
> 
> yeah, I considered that too. We could still do it in parts, though.
> 
> > - if we don't do the whole usb_bus->sysdev thing, we need to not just
> >   do this for dwc3 but also chipidea and maybe a couple of others.
> 
> MUSB comes to mind

Right.

> > There should not be any show-stoppers here, but it's a lot of work.
> 
> I think the biggest work will making sure people don't abuse functions
> just because they're now part of a single binary. Having them as
> separate modules helped a lot reducing the maintenance overhead. There
> was only one occasion where someone sent a glue layer which iterated
> over its children to find struct dwc3 * from child's drvdata.

This is where it get a bit philosophical ;-)

I understand that you like the strict separation that the current model
provides, and I agree that can be an advantage.

Changing the abstraction model to a set of library modules the way that
other drivers (e.g. ehci, sdhci, or libata) work to me means changing
this separation model into a different model and once we do that I would
not consider it a mistake for the platform specific driver to take
advantage of that. You still get a bit of separation since the drivers
would be in separate modules that can only access exported symbols,
and the library can still hide its data structures (to some degree).

I still think that turning xhci (and dwc3) into a library would be
an overall win, but if we solve the problems of DMA settings and
usb_device DT properties without it, I'd prefer not to fight over
that with you again ;-)

> >> If we try to pass DMA bits from parent to child, then we have the fact
> >> that DT ends up, in practice, always having a parent device.
> >
> > I don't understand what you mean here, but I agree that the various ways
> 
> well, we can't simply use what I pointed out a few emails back:
> 
> if (dwc->dev->parent)
> 	dwc->sysdev = dwc->dev->parent
> else
> 	dwc->sysdev = dwc->dev

Ok, I see.

> > we discussed for copying the DMA flags from one 'struct device' to another
> > all turned out to be flawed in at least one way.
> >
> > Do you see any problems with the patch I posted other than the ugliness
> > of the dwc3 and xhci drivers finding out which pointer to use for
> > usb_bus->sysdev? If we can solve this, we shouldn't need any new
> > of_dma_configure/acpi_dma_configure calls and we won't have to
> > turn the drivers into a library, so maybe let's try to come up with
> > better ideas for that sub-problem.
> 
> No big problems with that, no. Just the ifdef looking for a PCI bus in
> the parent. How about passing a flag via device_properties? I don't
> wanna change dwc3 core's device name with a platform_device_id because
> there probably already are scripts relying on the names to enable
> pm_runtime for example.

Sounds ok to me. Grygorii's solution might a be a bit more elegant,
but also a bit more error-prone:
If we get a platform that mistakenly sets the dma_mask pointer of
the child device, or a platform that does not set the dma_mask
pointer of the parent, things break.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:46                                                                               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 2:52:46 PM CEST Felipe Balbi wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> >> If we make dwc3.ko a library which glue calls directly then all these
> >> problems are solved but we break all current DTs and fall into the trap
> >> of having another MUSB.
> >
> > I don't see how we'd break the current DTs, I'm fairly sure we could turn dwc3
> 
> well, at a minimum dwc3-{pci,exynos,st,omap,of-simple}.c would have to
> look at possible children for their own quirks and properties.
> 
> > into a library without changing the DT representation. However the parts
> > that I think would change are
> >
> > - The sysfs representation for dwc3-pci, as we would no longer have
> >   a parent-child relationship there.
> 
> that's a no-brainer, I think
> 
> > - The power management handling might need a rework, since you currently
> >   rely on the hierarchy between dwc3-pci, dwc3 and xhci for turning
> >   power on and off
> 
> simple enough to do as well.
> 
> > - turning dwc3 into a library probably implies also turning xhci into
> >   a library, in part for consistency.
> 
> yeah, I considered that too. We could still do it in parts, though.
> 
> > - if we don't do the whole usb_bus->sysdev thing, we need to not just
> >   do this for dwc3 but also chipidea and maybe a couple of others.
> 
> MUSB comes to mind

Right.

> > There should not be any show-stoppers here, but it's a lot of work.
> 
> I think the biggest work will making sure people don't abuse functions
> just because they're now part of a single binary. Having them as
> separate modules helped a lot reducing the maintenance overhead. There
> was only one occasion where someone sent a glue layer which iterated
> over its children to find struct dwc3 * from child's drvdata.

This is where it get a bit philosophical ;-)

I understand that you like the strict separation that the current model
provides, and I agree that can be an advantage.

Changing the abstraction model to a set of library modules the way that
other drivers (e.g. ehci, sdhci, or libata) work to me means changing
this separation model into a different model and once we do that I would
not consider it a mistake for the platform specific driver to take
advantage of that. You still get a bit of separation since the drivers
would be in separate modules that can only access exported symbols,
and the library can still hide its data structures (to some degree).

I still think that turning xhci (and dwc3) into a library would be
an overall win, but if we solve the problems of DMA settings and
usb_device DT properties without it, I'd prefer not to fight over
that with you again ;-)

> >> If we try to pass DMA bits from parent to child, then we have the fact
> >> that DT ends up, in practice, always having a parent device.
> >
> > I don't understand what you mean here, but I agree that the various ways
> 
> well, we can't simply use what I pointed out a few emails back:
> 
> if (dwc->dev->parent)
> 	dwc->sysdev = dwc->dev->parent
> else
> 	dwc->sysdev = dwc->dev

Ok, I see.

> > we discussed for copying the DMA flags from one 'struct device' to another
> > all turned out to be flawed in at least one way.
> >
> > Do you see any problems with the patch I posted other than the ugliness
> > of the dwc3 and xhci drivers finding out which pointer to use for
> > usb_bus->sysdev? If we can solve this, we shouldn't need any new
> > of_dma_configure/acpi_dma_configure calls and we won't have to
> > turn the drivers into a library, so maybe let's try to come up with
> > better ideas for that sub-problem.
> 
> No big problems with that, no. Just the ifdef looking for a PCI bus in
> the parent. How about passing a flag via device_properties? I don't
> wanna change dwc3 core's device name with a platform_device_id because
> there probably already are scripts relying on the names to enable
> pm_runtime for example.

Sounds ok to me. Grygorii's solution might a be a bit more elegant,
but also a bit more error-prone:
If we get a platform that mistakenly sets the dma_mask pointer of
the child device, or a platform that does not set the dma_mask
pointer of the parent, things break.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 12:28                                                                     ` Peter Chen
@ 2016-09-08 12:52                                                                       ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Peter Chen, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman,
	Alan Stern

On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote:
> On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > > Arnd Bergmann <arnd@arndb.de> writes:
> > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > > If we have a parent device, use that as sysdev, otherwise use self as
> > > sysdev.
> > 
> > But there is often a parent device in DT, as the xhci device is
> > attached to some internal bus that gets turned into a platform_device
> > as well, so checking whether there is a parent will get the wrong
> > device node.
> 
> From my point, all platform and firmware information at dwc3 are
> correct, so we don't need to change dwc3/core.c, only changing for
> xhci-plat.c is ok.

Ok, thanks. That leaves the PCI glue, right?

> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index d2e3f65..563600b 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
>  		/* Did the HC die before the root hub was registered? */
>  		if (HCD_DEAD(hcd))
>  			usb_hc_died (hcd);	/* This time clean up */
> -		usb_dev->dev.of_node = parent_dev->of_node;
> +		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
>  	}
>  	mutex_unlock(&usb_bus_idr_lock);
> 
> At above changes, the root hub's of_node equals to xhci-hcd sysdev's
> of_node, which is from firmware or from its parent (it is dwc3 core
> device).

Just to make sure I understand you right:

in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the
dwc3 device, not the qcom,dwc3 device.

> > > > That sounds a bit clumsy for the sake of consistency with PCI.
> > > > The advantage is that xhci can always use the grandparent device
> > > > as sysdev whenever it isn't probed through PCI or firmware
> > > > itself, but the purpose of the dwc3-glue is otherwise questionable.
> > > >
> > > > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > > > device when that is created from the PCI driver and checking for that
> > > > with the device property interface instead? If it's "snps,dwc3"
> > > > we use the device itself while for "snps,dwc3-pci", we use the parent?
> > > 
> 
> For pci glue device, it is always the parent for dwc3 core device.
> In your patch, you may not need to split pci or non-pci, just using
> if (dev->parent).

Here we have the pci-dwc3 -> dwc3 -> xhci hierarchy, and we want
sysdev to point to pci-dwc3, not dwc3!

The point is that the pci_dev is where we have the dma settings
and (optionally) additional DT or ACPI data for that device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:52                                                                       ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-08 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote:
> On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > > Arnd Bergmann <arnd@arndb.de> writes:
> > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > > If we have a parent device, use that as sysdev, otherwise use self as
> > > sysdev.
> > 
> > But there is often a parent device in DT, as the xhci device is
> > attached to some internal bus that gets turned into a platform_device
> > as well, so checking whether there is a parent will get the wrong
> > device node.
> 
> From my point, all platform and firmware information at dwc3 are
> correct, so we don't need to change dwc3/core.c, only changing for
> xhci-plat.c is ok.

Ok, thanks. That leaves the PCI glue, right?

> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index d2e3f65..563600b 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
>  		/* Did the HC die before the root hub was registered? */
>  		if (HCD_DEAD(hcd))
>  			usb_hc_died (hcd);	/* This time clean up */
> -		usb_dev->dev.of_node = parent_dev->of_node;
> +		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
>  	}
>  	mutex_unlock(&usb_bus_idr_lock);
> 
> At above changes, the root hub's of_node equals to xhci-hcd sysdev's
> of_node, which is from firmware or from its parent (it is dwc3 core
> device).

Just to make sure I understand you right:

in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the
dwc3 device, not the qcom,dwc3 device.

> > > > That sounds a bit clumsy for the sake of consistency with PCI.
> > > > The advantage is that xhci can always use the grandparent device
> > > > as sysdev whenever it isn't probed through PCI or firmware
> > > > itself, but the purpose of the dwc3-glue is otherwise questionable.
> > > >
> > > > How about adding a 'compatible="snps,dwc3-pci"' property for the dwc3
> > > > device when that is created from the PCI driver and checking for that
> > > > with the device property interface instead? If it's "snps,dwc3"
> > > > we use the device itself while for "snps,dwc3-pci", we use the parent?
> > > 
> 
> For pci glue device, it is always the parent for dwc3 core device.
> In your patch, you may not need to split pci or non-pci, just using
> if (dev->parent).

Here we have the pci-dwc3 -> dwc3 -> xhci hierarchy, and we want
sysdev to point to pci-dwc3, not dwc3!

The point is that the pci_dev is where we have the dma settings
and (optionally) additional DT or ACPI data for that device.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 12:28                                                                     ` Peter Chen
@ 2016-09-08 12:59                                                                       ` Grygorii Strashko
  -1 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-08 12:59 UTC (permalink / raw)
  To: Peter Chen, Arnd Bergmann
  Cc: Felipe Balbi, Leo Li, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel

On 09/08/2016 03:28 PM, Peter Chen wrote:
> On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
>> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>>> Arnd Bergmann <arnd@arndb.de> writes:
>>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>>>>>> If we do that, we have to put child devices of the dwc3 devices into
>>>>>> the platform glue, and it also breaks those dwc3 devices that don't
>>>>>> have a parent driver.
>>>>>
>>>>> Well, this is easy to fix:
>>>>>
>>>>>         if (dwc->dev->parent) {
>>>>>                 dwc->sysdev = dwc->dev->parent;
>>>>>         } else {
>>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>>>>                 dwc->sysdev = dwc->dev;
>>>>>         }
>>>>
>>>> I don't understand. Do you mean we should have an extra level of
>>>> stacking and splitting "static struct platform_driver dwc3_driver"
>>>> in two so instead of
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>>>>
>>>> we do this?
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>>>
>>> no 
>>>
>>> If we have a parent device, use that as sysdev, otherwise use self as
>>> sysdev.
>>
>> But there is often a parent device in DT, as the xhci device is
>> attached to some internal bus that gets turned into a platform_device
>> as well, so checking whether there is a parent will get the wrong
>> device node.
> 
> From my point, all platform and firmware information at dwc3 are
> correct, so we don't need to change dwc3/core.c, only changing for
> xhci-plat.c is ok.
> 
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index ed56bf9..fd57c0d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	struct clk              *clk;
>  	int			ret;
>  	int			irq;
> +	struct device *dev = &pdev->dev, *sysdev;
>  
>  	if (usb_disabled())
>  		return -ENODEV;
> @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	if (irq < 0)
>  		return -ENODEV;
>  
> +	if (dev->parent) {
> +		sysdev = dev->parent;
> +	} else {
> +        	sysdev = dev;
> +	}
> +

Shouldn't we be more careful with that?

armada-375.dtsi

	soc {
		compatible = "marvell,armada375-mbus", "simple-bus";

		internal-regs {
			compatible = "simple-bus";

			usb3@58000 {
				compatible = "marvell,armada-375-xhci";
				reg = <0x58000 0x20000>,<0x5b880 0x80>;
				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&gateclk 16>;
				phys = <&usbcluster PHY_TYPE_USB3>;
				phy-names = "usb";
				status = "disabled";
			};


What will be the parent dev in above case?

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-08 12:59                                                                       ` Grygorii Strashko
  0 siblings, 0 replies; 182+ messages in thread
From: Grygorii Strashko @ 2016-09-08 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/08/2016 03:28 PM, Peter Chen wrote:
> On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
>> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
>>> Arnd Bergmann <arnd@arndb.de> writes:
>>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
>>>>>> If we do that, we have to put child devices of the dwc3 devices into
>>>>>> the platform glue, and it also breaks those dwc3 devices that don't
>>>>>> have a parent driver.
>>>>>
>>>>> Well, this is easy to fix:
>>>>>
>>>>>         if (dwc->dev->parent) {
>>>>>                 dwc->sysdev = dwc->dev->parent;
>>>>>         } else {
>>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
>>>>>                 dwc->sysdev = dwc->dev;
>>>>>         }
>>>>
>>>> I don't understand. Do you mean we should have an extra level of
>>>> stacking and splitting "static struct platform_driver dwc3_driver"
>>>> in two so instead of
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
>>>>
>>>> we do this?
>>>>
>>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
>>>
>>> no 
>>>
>>> If we have a parent device, use that as sysdev, otherwise use self as
>>> sysdev.
>>
>> But there is often a parent device in DT, as the xhci device is
>> attached to some internal bus that gets turned into a platform_device
>> as well, so checking whether there is a parent will get the wrong
>> device node.
> 
> From my point, all platform and firmware information at dwc3 are
> correct, so we don't need to change dwc3/core.c, only changing for
> xhci-plat.c is ok.
> 
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index ed56bf9..fd57c0d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	struct clk              *clk;
>  	int			ret;
>  	int			irq;
> +	struct device *dev = &pdev->dev, *sysdev;
>  
>  	if (usb_disabled())
>  		return -ENODEV;
> @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	if (irq < 0)
>  		return -ENODEV;
>  
> +	if (dev->parent) {
> +		sysdev = dev->parent;
> +	} else {
> +        	sysdev = dev;
> +	}
> +

Shouldn't we be more careful with that?

armada-375.dtsi

	soc {
		compatible = "marvell,armada375-mbus", "simple-bus";

		internal-regs {
			compatible = "simple-bus";

			usb3 at 58000 {
				compatible = "marvell,armada-375-xhci";
				reg = <0x58000 0x20000>,<0x5b880 0x80>;
				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&gateclk 16>;
				phys = <&usbcluster PHY_TYPE_USB3>;
				phy-names = "usb";
				status = "disabled";
			};


What will be the parent dev in above case?

-- 
regards,
-grygorii

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 12:52                                                                       ` Arnd Bergmann
@ 2016-09-09  1:37                                                                         ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-09  1:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman,
	Alan Stern

On Thu, Sep 08, 2016 at 02:52:29PM +0200, Arnd Bergmann wrote:
> On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote:
> > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> > > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > > > Arnd Bergmann <arnd@arndb.de> writes:
> > > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > > > If we have a parent device, use that as sysdev, otherwise use self as
> > > > sysdev.
> > > 
> > > But there is often a parent device in DT, as the xhci device is
> > > attached to some internal bus that gets turned into a platform_device
> > > as well, so checking whether there is a parent will get the wrong
> > > device node.
> > 
> > From my point, all platform and firmware information at dwc3 are
> > correct, so we don't need to change dwc3/core.c, only changing for
> > xhci-plat.c is ok.
> 
> Ok, thanks. That leaves the PCI glue, right?

If pci's firmware information can only get from dwc3-pci, I was wrong.
I am almost sure your patch covers all 3 cases. dwc3->sysdev covers
dwc3 core and gadget side, hcd->self.sysdev cover host side. The only
possible improvement may be how to detect pci device.

> 
> > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> > index d2e3f65..563600b 100644
> > --- a/drivers/usb/core/hcd.c
> > +++ b/drivers/usb/core/hcd.c
> > @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
> >  		/* Did the HC die before the root hub was registered? */
> >  		if (HCD_DEAD(hcd))
> >  			usb_hc_died (hcd);	/* This time clean up */
> > -		usb_dev->dev.of_node = parent_dev->of_node;
> > +		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
> >  	}
> >  	mutex_unlock(&usb_bus_idr_lock);
> > 
> > At above changes, the root hub's of_node equals to xhci-hcd sysdev's
> > of_node, which is from firmware or from its parent (it is dwc3 core
> > device).
> 
> Just to make sure I understand you right:
> 
> in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the
> dwc3 device, not the qcom,dwc3 device.
> 

Yes, since there is a DT node for dwc3, and firmware information is there,
that's why the original patch (Grygorii Strashko's) can work.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-09  1:37                                                                         ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-09  1:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2016 at 02:52:29PM +0200, Arnd Bergmann wrote:
> On Thursday, September 8, 2016 8:28:10 PM CEST Peter Chen wrote:
> > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> > > On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> > > > Arnd Bergmann <arnd@arndb.de> writes:
> > > > > On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> > > > If we have a parent device, use that as sysdev, otherwise use self as
> > > > sysdev.
> > > 
> > > But there is often a parent device in DT, as the xhci device is
> > > attached to some internal bus that gets turned into a platform_device
> > > as well, so checking whether there is a parent will get the wrong
> > > device node.
> > 
> > From my point, all platform and firmware information at dwc3 are
> > correct, so we don't need to change dwc3/core.c, only changing for
> > xhci-plat.c is ok.
> 
> Ok, thanks. That leaves the PCI glue, right?

If pci's firmware information can only get from dwc3-pci, I was wrong.
I am almost sure your patch covers all 3 cases. dwc3->sysdev covers
dwc3 core and gadget side, hcd->self.sysdev cover host side. The only
possible improvement may be how to detect pci device.

> 
> > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> > index d2e3f65..563600b 100644
> > --- a/drivers/usb/core/hcd.c
> > +++ b/drivers/usb/core/hcd.c
> > @@ -1118,7 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
> >  		/* Did the HC die before the root hub was registered? */
> >  		if (HCD_DEAD(hcd))
> >  			usb_hc_died (hcd);	/* This time clean up */
> > -		usb_dev->dev.of_node = parent_dev->of_node;
> > +		usb_dev->dev.of_node = parent_dev->sysdev->of_node;
> >  	}
> >  	mutex_unlock(&usb_bus_idr_lock);
> > 
> > At above changes, the root hub's of_node equals to xhci-hcd sysdev's
> > of_node, which is from firmware or from its parent (it is dwc3 core
> > device).
> 
> Just to make sure I understand you right:
> 
> in the qcom,dwc3 -> dwc3 -> xhci hierarchy, this would be the
> dwc3 device, not the qcom,dwc3 device.
> 

Yes, since there is a DT node for dwc3, and firmware information is there,
that's why the original patch (Grygorii Strashko's) can work.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-08 12:59                                                                       ` Grygorii Strashko
@ 2016-09-09  1:52                                                                         ` Peter Chen
  -1 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-09  1:52 UTC (permalink / raw)
  To: Grygorii Strashko
  Cc: Arnd Bergmann, Felipe Balbi, Leo Li, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel

On Thu, Sep 08, 2016 at 03:59:19PM +0300, Grygorii Strashko wrote:
> On 09/08/2016 03:28 PM, Peter Chen wrote:
> > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> >> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> >>> Arnd Bergmann <arnd@arndb.de> writes:
> >>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> >>>>>> If we do that, we have to put child devices of the dwc3 devices into
> >>>>>> the platform glue, and it also breaks those dwc3 devices that don't
> >>>>>> have a parent driver.
> >>>>>
> >>>>> Well, this is easy to fix:
> >>>>>
> >>>>>         if (dwc->dev->parent) {
> >>>>>                 dwc->sysdev = dwc->dev->parent;
> >>>>>         } else {
> >>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> >>>>>                 dwc->sysdev = dwc->dev;
> >>>>>         }
> >>>>
> >>>> I don't understand. Do you mean we should have an extra level of
> >>>> stacking and splitting "static struct platform_driver dwc3_driver"
> >>>> in two so instead of
> >>>>
> >>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> >>>>
> >>>> we do this?
> >>>>
> >>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> >>>
> >>> no 
> >>>
> >>> If we have a parent device, use that as sysdev, otherwise use self as
> >>> sysdev.
> >>
> >> But there is often a parent device in DT, as the xhci device is
> >> attached to some internal bus that gets turned into a platform_device
> >> as well, so checking whether there is a parent will get the wrong
> >> device node.
> > 
> > From my point, all platform and firmware information at dwc3 are
> > correct, so we don't need to change dwc3/core.c, only changing for
> > xhci-plat.c is ok.
> > 
> > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> > index ed56bf9..fd57c0d 100644
> > --- a/drivers/usb/host/xhci-plat.c
> > +++ b/drivers/usb/host/xhci-plat.c
> > @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
> >  	struct clk              *clk;
> >  	int			ret;
> >  	int			irq;
> > +	struct device *dev = &pdev->dev, *sysdev;
> >  
> >  	if (usb_disabled())
> >  		return -ENODEV;
> > @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
> >  	if (irq < 0)
> >  		return -ENODEV;
> >  
> > +	if (dev->parent) {
> > +		sysdev = dev->parent;
> > +	} else {
> > +        	sysdev = dev;
> > +	}
> > +
> 
> Shouldn't we be more careful with that?
> 

Above code does not consider pci device case, Arnd's patch covers
all cases.

> armada-375.dtsi
> 
> 	soc {
> 		compatible = "marvell,armada375-mbus", "simple-bus";
> 
> 		internal-regs {
> 			compatible = "simple-bus";
> 
> 			usb3@58000 {
> 				compatible = "marvell,armada-375-xhci";
> 				reg = <0x58000 0x20000>,<0x5b880 0x80>;
> 				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> 				clocks = <&gateclk 16>;
> 				phys = <&usbcluster PHY_TYPE_USB3>;
> 				phy-names = "usb";
> 				status = "disabled";
> 			};
> 
> 
> What will be the parent dev in above case?
> 

In this case, no parent dev for above case, it will use itself as sysdev
since it has of_node at dts.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-09  1:52                                                                         ` Peter Chen
  0 siblings, 0 replies; 182+ messages in thread
From: Peter Chen @ 2016-09-09  1:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 08, 2016 at 03:59:19PM +0300, Grygorii Strashko wrote:
> On 09/08/2016 03:28 PM, Peter Chen wrote:
> > On Thu, Sep 08, 2016 at 12:17:21PM +0200, Arnd Bergmann wrote:
> >> On Thursday, September 8, 2016 12:43:06 PM CEST Felipe Balbi wrote:
> >>> Arnd Bergmann <arnd@arndb.de> writes:
> >>>> On Thursday, September 8, 2016 11:29:04 AM CEST Felipe Balbi wrote:
> >>>>>> If we do that, we have to put child devices of the dwc3 devices into
> >>>>>> the platform glue, and it also breaks those dwc3 devices that don't
> >>>>>> have a parent driver.
> >>>>>
> >>>>> Well, this is easy to fix:
> >>>>>
> >>>>>         if (dwc->dev->parent) {
> >>>>>                 dwc->sysdev = dwc->dev->parent;
> >>>>>         } else {
> >>>>>                 dev_info(dwc->dev, "Please provide a glue layer!\n");
> >>>>>                 dwc->sysdev = dwc->dev;
> >>>>>         }
> >>>>
> >>>> I don't understand. Do you mean we should have an extra level of
> >>>> stacking and splitting "static struct platform_driver dwc3_driver"
> >>>> in two so instead of
> >>>>
> >>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "xhci" (usb_bus.dev)
> >>>>
> >>>> we do this?
> >>>>
> >>>>       "qcom,dwc3" -> "snps,dwc3" (usb_bus.sysdev) -> "dwc3-glue" -> "xhci" (usb_bus.dev)
> >>>
> >>> no 
> >>>
> >>> If we have a parent device, use that as sysdev, otherwise use self as
> >>> sysdev.
> >>
> >> But there is often a parent device in DT, as the xhci device is
> >> attached to some internal bus that gets turned into a platform_device
> >> as well, so checking whether there is a parent will get the wrong
> >> device node.
> > 
> > From my point, all platform and firmware information at dwc3 are
> > correct, so we don't need to change dwc3/core.c, only changing for
> > xhci-plat.c is ok.
> > 
> > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> > index ed56bf9..fd57c0d 100644
> > --- a/drivers/usb/host/xhci-plat.c
> > +++ b/drivers/usb/host/xhci-plat.c
> > @@ -145,6 +145,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
> >  	struct clk              *clk;
> >  	int			ret;
> >  	int			irq;
> > +	struct device *dev = &pdev->dev, *sysdev;
> >  
> >  	if (usb_disabled())
> >  		return -ENODEV;
> > @@ -155,6 +156,12 @@ static int xhci_plat_probe(struct platform_device *pdev)
> >  	if (irq < 0)
> >  		return -ENODEV;
> >  
> > +	if (dev->parent) {
> > +		sysdev = dev->parent;
> > +	} else {
> > +        	sysdev = dev;
> > +	}
> > +
> 
> Shouldn't we be more careful with that?
> 

Above code does not consider pci device case, Arnd's patch covers
all cases.

> armada-375.dtsi
> 
> 	soc {
> 		compatible = "marvell,armada375-mbus", "simple-bus";
> 
> 		internal-regs {
> 			compatible = "simple-bus";
> 
> 			usb3 at 58000 {
> 				compatible = "marvell,armada-375-xhci";
> 				reg = <0x58000 0x20000>,<0x5b880 0x80>;
> 				interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> 				clocks = <&gateclk 16>;
> 				phys = <&usbcluster PHY_TYPE_USB3>;
> 				phy-names = "usb";
> 				status = "disabled";
> 			};
> 
> 
> What will be the parent dev in above case?
> 

In this case, no parent dev for above case, it will use itself as sysdev
since it has of_node at dts.

-- 

Best Regards,
Peter Chen

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 10:47                                                         ` Felipe Balbi
@ 2016-09-14 16:31                                                           ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 182+ messages in thread
From: Lorenzo Pieralisi @ 2016-09-14 16:31 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Robin Murphy, Peter Chen, Arnd Bergmann, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman,
	Alan Stern, linux-arm-kernel

On Wed, Sep 07, 2016 at 01:47:22PM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Robin Murphy <robin.murphy@arm.com> writes:
> > On 07/09/16 10:55, Peter Chen wrote:
> > [...]
> >>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> >>> I think we should replace 
> >>>
> >>>         pdev->dev.dma_mask = dev->dma_mask;
> >>>         pdev->dev.dma_parms = dev->dma_parms;
> >>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> >>>
> >>> with of_dma_configure(), which has the chance to configure more than
> >>> just those three, as the dma API might look into different aspects:
> >>>
> >>> - iommu specific configuration
> >>> - cache coherency information
> >>> - bus type
> >>> - dma offset
> >>> - dma_map_ops pointer
> >>>
> >>> We try to handle everything in of_dma_configure() at configuration
> >>> time, and that would be the place to add anything else that we might
> >>> need in the future.
> >>>
> >> 
> >> Yes, I agree with you, but just like Felipe mentioned, we also need to
> >> consider PCI device, can we do something like gpiod_get_index does? Are
> >> there any similar APIs like of_dma_configure for ACPI?
> >
> > Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> > abstracting away the IOMMU configuration.
> >
> > Robin.
> >
> > [1]:http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1209911.html
> 
> not exported for drivers to use. If Lorenzo is trying to making a
> matching API for ACPI systems, then it needs to follow what
> of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()

That's easy enough, not sure I understand though why
of_dma_deconfigure() is not exported then. The second question mark
is about the dma-ranges equivalent in ACPI world; the _DMA method
seems to be the exact equivalent but to the best of my knowledge
it is ignored by the kernel, to really have an of_dma_configure()
equivalent that's really necessary, unless we want to resort to
arch specific methods (is that what x86 is currently doing ?) to
retrieve/build the dma masks.

Lorenzo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-14 16:31                                                           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 182+ messages in thread
From: Lorenzo Pieralisi @ 2016-09-14 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 07, 2016 at 01:47:22PM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Robin Murphy <robin.murphy@arm.com> writes:
> > On 07/09/16 10:55, Peter Chen wrote:
> > [...]
> >>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> >>> I think we should replace 
> >>>
> >>>         pdev->dev.dma_mask = dev->dma_mask;
> >>>         pdev->dev.dma_parms = dev->dma_parms;
> >>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> >>>
> >>> with of_dma_configure(), which has the chance to configure more than
> >>> just those three, as the dma API might look into different aspects:
> >>>
> >>> - iommu specific configuration
> >>> - cache coherency information
> >>> - bus type
> >>> - dma offset
> >>> - dma_map_ops pointer
> >>>
> >>> We try to handle everything in of_dma_configure() at configuration
> >>> time, and that would be the place to add anything else that we might
> >>> need in the future.
> >>>
> >> 
> >> Yes, I agree with you, but just like Felipe mentioned, we also need to
> >> consider PCI device, can we do something like gpiod_get_index does? Are
> >> there any similar APIs like of_dma_configure for ACPI?
> >
> > Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> > abstracting away the IOMMU configuration.
> >
> > Robin.
> >
> > [1]:http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1209911.html
> 
> not exported for drivers to use. If Lorenzo is trying to making a
> matching API for ACPI systems, then it needs to follow what
> of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()

That's easy enough, not sure I understand though why
of_dma_deconfigure() is not exported then. The second question mark
is about the dma-ranges equivalent in ACPI world; the _DMA method
seems to be the exact equivalent but to the best of my knowledge
it is ignored by the kernel, to really have an of_dma_configure()
equivalent that's really necessary, unless we want to resort to
arch specific methods (is that what x86 is currently doing ?) to
retrieve/build the dma masks.

Lorenzo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-14 16:31                                                           ` Lorenzo Pieralisi
@ 2016-09-14 21:50                                                             ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-14 21:50 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Lorenzo Pieralisi, Felipe Balbi, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Leo Li, Greg Kroah-Hartman,
	Alan Stern, Robin Murphy, Peter Chen

On Wednesday, September 14, 2016 5:31:36 PM CEST Lorenzo Pieralisi wrote:
> On Wed, Sep 07, 2016 at 01:47:22PM +0300, Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Robin Murphy <robin.murphy@arm.com> writes:
> > > On 07/09/16 10:55, Peter Chen wrote:
> > > [...]
> > >>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > >>> I think we should replace 
> > >>>
> > >>>         pdev->dev.dma_mask = dev->dma_mask;
> > >>>         pdev->dev.dma_parms = dev->dma_parms;
> > >>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> > >>>
> > >>> with of_dma_configure(), which has the chance to configure more than
> > >>> just those three, as the dma API might look into different aspects:
> > >>>
> > >>> - iommu specific configuration
> > >>> - cache coherency information
> > >>> - bus type
> > >>> - dma offset
> > >>> - dma_map_ops pointer
> > >>>
> > >>> We try to handle everything in of_dma_configure() at configuration
> > >>> time, and that would be the place to add anything else that we might
> > >>> need in the future.
> > >>>
> > >> 
> > >> Yes, I agree with you, but just like Felipe mentioned, we also need to
> > >> consider PCI device, can we do something like gpiod_get_index does? Are
> > >> there any similar APIs like of_dma_configure for ACPI?
> > >
> > > Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> > > abstracting away the IOMMU configuration.
> > >
> > > Robin.
> > >
> > > [1]:http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1209911.html
> > 
> > not exported for drivers to use. If Lorenzo is trying to making a
> > matching API for ACPI systems, then it needs to follow what
> > of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()
> 
> That's easy enough, not sure I understand though why
> of_dma_deconfigure() is not exported then. The second question mark
> is about the dma-ranges equivalent in ACPI world; the _DMA method
> seems to be the exact equivalent but to the best of my knowledge
> it is ignored by the kernel, to really have an of_dma_configure()
> equivalent that's really necessary, unless we want to resort to
> arch specific methods (is that what x86 is currently doing ?) to
> retrieve/build the dma masks.

Please see the follow-up emails after my proposed patch: if we add
a pointer to the device that firmware knows about in the USB core layer,
there is no longer a problem to be solved and the DMA operations will
do the right thing.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-14 21:50                                                             ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-14 21:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 14, 2016 5:31:36 PM CEST Lorenzo Pieralisi wrote:
> On Wed, Sep 07, 2016 at 01:47:22PM +0300, Felipe Balbi wrote:
> > 
> > Hi,
> > 
> > Robin Murphy <robin.murphy@arm.com> writes:
> > > On 07/09/16 10:55, Peter Chen wrote:
> > > [...]
> > >>> Regarding the DMA configuration that you mention in ci_hdrc_add_device(),
> > >>> I think we should replace 
> > >>>
> > >>>         pdev->dev.dma_mask = dev->dma_mask;
> > >>>         pdev->dev.dma_parms = dev->dma_parms;
> > >>>         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
> > >>>
> > >>> with of_dma_configure(), which has the chance to configure more than
> > >>> just those three, as the dma API might look into different aspects:
> > >>>
> > >>> - iommu specific configuration
> > >>> - cache coherency information
> > >>> - bus type
> > >>> - dma offset
> > >>> - dma_map_ops pointer
> > >>>
> > >>> We try to handle everything in of_dma_configure() at configuration
> > >>> time, and that would be the place to add anything else that we might
> > >>> need in the future.
> > >>>
> > >> 
> > >> Yes, I agree with you, but just like Felipe mentioned, we also need to
> > >> consider PCI device, can we do something like gpiod_get_index does? Are
> > >> there any similar APIs like of_dma_configure for ACPI?
> > >
> > > Not yet, but Lorenzo has one in progress[1], primarily for the sake of
> > > abstracting away the IOMMU configuration.
> > >
> > > Robin.
> > >
> > > [1]:http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1209911.html
> > 
> > not exported for drivers to use. If Lorenzo is trying to making a
> > matching API for ACPI systems, then it needs to follow what
> > of_dma_configure() is doing, and add an EXPORT_SYMBOL_GPL()
> 
> That's easy enough, not sure I understand though why
> of_dma_deconfigure() is not exported then. The second question mark
> is about the dma-ranges equivalent in ACPI world; the _DMA method
> seems to be the exact equivalent but to the best of my knowledge
> it is ignored by the kernel, to really have an of_dma_configure()
> equivalent that's really necessary, unless we want to resort to
> arch specific methods (is that what x86 is currently doing ?) to
> retrieve/build the dma masks.

Please see the follow-up emails after my proposed patch: if we add
a pointer to the device that firmware knows about in the USB core layer,
there is no longer a problem to be solved and the DMA operations will
do the right thing.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* RE: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-07 15:24                                                       ` Arnd Bergmann
@ 2016-09-21 11:06                                                         ` Sriram Dash
  -1 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-21 11:06 UTC (permalink / raw)
  To: Arnd Bergmann, Felipe Balbi
  Cc: Peter Chen, Leo Li, Grygorii Strashko, Russell King - ARM Linux,
	Catalin Marinas, Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml,
	Stuart Yoder, Scott Wood, David Fisher, Thang Q. Nguyen,
	Alan Stern, Greg Kroah-Hartman, linux-arm-kernel, Suresh Gupta

>From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-owner@vger.kernel.org]
>On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
>>
>> Hi,
>>
>> Arnd Bergmann <arnd@arndb.de> writes:
>>
>> [...]
>>
>> > Regarding the DMA configuration that you mention in
>> > ci_hdrc_add_device(), I think we should replace
>> >
>> >         pdev->dev.dma_mask = dev->dma_mask;
>> >         pdev->dev.dma_parms = dev->dma_parms;
>> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>> >
>> > with of_dma_configure(), which has the chance to configure more than
>> > just those three, as the dma API might look into different aspects:
>> >
>> > - iommu specific configuration
>> > - cache coherency information
>> > - bus type
>> > - dma offset
>> > - dma_map_ops pointer
>> >
>> > We try to handle everything in of_dma_configure() at configuration
>> > time, and that would be the place to add anything else that we might
>> > need in the future.
>>
>> There are a couple problems with this:
>>
>> 1) won't work for PCI-based systems.
>>
>> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
>> platform (FPGA that appears like a PCI card to host PC)
>
>Right, I was specifically talking about the code in chipidea here, which I think is
>never used on the PCI bus, and how the current code is broken. We can probably do
>better than of_dma_configure() (see below), but it would be an improvement.
>
>> 2) not very robust solution
>>
>> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat
>> because that's not created by DT. The only reason why this works at
>> all is because of the default 32-bit dma mask thing :-) So, how is it
>> any different than copying 32-bit dma mask from parent?
>
>The idea here is that you pass in the parent of_node along with the child device
>pointer, so it would behave exactly like the parent already does.
>The difference is that it also handles all the other attributes besides the mask.
>
>However, to summarize the discussion so far, I agree that
>of_dma_configure() is not the solution to these problems, and I think we can do
>much better:
>
>Splitting the usb_bus->controller field into the Linux-internal device (used for the
>sysfs hierarchy, for printks and for power management) and a new pointer (used for
>DMA, DT enumeration and phy lookup) probably covers all that we really need.
>
>I've prototyped it below, with the dwc3, xhci and chipidea changes together with
>the core changes. I've surely made mistakes there and don't expect it to work out
>of the box, but this should give an idea of how I think this can all be solved in the
>least invasive way.
>

Hello Arnd,

We tried this patch on NXP platforms (ls2085 and ls1043) which use dwc3 
controller without any glue layer. On first go, this did not work. But after
minimal reworks mention snippet below, we are able to verify that the USB
was working OK.

 drivers/usb/host/xhci-mem.c | 12 ++++++------
 drivers/usb/host/xhci.c     | 20 ++++++++++----------

-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;

We believe the patch needs little modification to work or there might be chances
we may have missed something. Any idea?

Regards,
Sriram

>I noticed that the gadget interface already has a way to handle the DMA allocation
>by device, so I added that in as well.
>
>Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>
> drivers/usb/chipidea/core.c    |  4 ----
> drivers/usb/chipidea/host.c    |  3 ++-
> drivers/usb/chipidea/udc.c     |  8 ++++----
> drivers/usb/core/buffer.c      | 12 ++++++------
> drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++------------------
>-
> drivers/usb/core/usb.c         | 16 ++++++++--------
> drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
> drivers/usb/dwc3/core.h        |  1 +
> drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
> drivers/usb/dwc3/dwc3-st.c     |  1 -
> drivers/usb/dwc3/ep0.c         |  8 ++++----
> drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
> drivers/usb/dwc3/host.c        | 13 ++++---------
> drivers/usb/host/ehci-fsl.c    |  4 ++--
> drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
> include/linux/usb.h            |  1 +
> include/linux/usb/hcd.h        |  3 +++
>
>diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index
>69426e644d17..dff69837b349 100644
>--- a/drivers/usb/chipidea/core.c
>+++ b/drivers/usb/chipidea/core.c
>@@ -833,10 +833,6 @@ struct platform_device *ci_hdrc_add_device(struct device
>*dev,
> 	}
>
> 	pdev->dev.parent = dev;
>-	pdev->dev.dma_mask = dev->dma_mask;
>-	pdev->dev.dma_parms = dev->dma_parms;
>-	dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>-
> 	ret = platform_device_add_resources(pdev, res, nres);
> 	if (ret)
> 		goto err;
>diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index
>053bac9d983c..40d29c4d7772 100644
>--- a/drivers/usb/chipidea/host.c
>+++ b/drivers/usb/chipidea/host.c
>@@ -113,7 +113,8 @@ static int host_start(struct ci_hdrc *ci)
> 	if (usb_disabled())
> 		return -ENODEV;
>
>-	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
>+	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
>+			       ci->dev, dev_name(ci->dev), NULL);
> 	if (!hcd)
> 		return -ENOMEM;
>
>diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index
>0f692fcda638..4cbfff7934c6 100644
>--- a/drivers/usb/chipidea/udc.c
>+++ b/drivers/usb/chipidea/udc.c
>@@ -424,7 +424,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep,
>struct ci_hw_req *hwreq)
>
> 	hwreq->req.status = -EALREADY;
>
>-	ret = usb_gadget_map_request(&ci->gadget, &hwreq->req, hwep->dir);
>+	ret = usb_gadget_map_request_by_dev(&ci->dev->parent, &hwreq->req,
>+hwep->dir);
> 	if (ret)
> 		return ret;
>
>@@ -604,7 +604,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep,
>struct ci_hw_req *hwreq)
> 		list_del_init(&node->td);
> 	}
>
>-	usb_gadget_unmap_request(&hwep->ci->gadget, &hwreq->req, hwep-
>>dir);
>+	usb_gadget_unmap_request_by_dev(&hwep->ci->dev->parent, &hwreq-
>>req,
>+hwep->dir);
>
> 	hwreq->req.actual += actual;
>
>@@ -1898,13 +1898,13 @@ static int udc_start(struct ci_hdrc *ci)
> 	INIT_LIST_HEAD(&ci->gadget.ep_list);
>
> 	/* alloc resources */
>-	ci->qh_pool = dma_pool_create("ci_hw_qh", dev,
>+	ci->qh_pool = dma_pool_create("ci_hw_qh", dev->parent,
> 				       sizeof(struct ci_hw_qh),
> 				       64, CI_HDRC_PAGE_SIZE);
> 	if (ci->qh_pool == NULL)
> 		return -ENOMEM;
>
>-	ci->td_pool = dma_pool_create("ci_hw_td", dev,
>+	ci->td_pool = dma_pool_create("ci_hw_td", dev->parent,
> 				       sizeof(struct ci_hw_td),
> 				       64, CI_HDRC_PAGE_SIZE);
> 	if (ci->td_pool == NULL) {
>diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index
>98e39f91723a..1e41ef7f3c1f 100644
>--- a/drivers/usb/core/buffer.c
>+++ b/drivers/usb/core/buffer.c
>@@ -63,7 +63,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
> 	int		i, size;
>
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!hcd->self.controller->dma_mask &&
>+	    (!hcd->self.sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM)))
> 		return 0;
>
>@@ -72,7 +72,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
> 		if (!size)
> 			continue;
> 		snprintf(name, sizeof(name), "buffer-%d", size);
>-		hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
>+		hcd->pool[i] = dma_pool_create(name, hcd->self.sysdev,
> 				size, size, 0);
> 		if (!hcd->pool[i]) {
> 			hcd_buffer_destroy(hcd);
>@@ -127,7 +127,7 @@ void *hcd_buffer_alloc(
>
> 	/* some USB hosts just use PIO */
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!bus->controller->dma_mask &&
>+	    (!bus->sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
> 		*dma = ~(dma_addr_t) 0;
> 		return kmalloc(size, mem_flags);
>@@ -137,7 +137,7 @@ void *hcd_buffer_alloc(
> 		if (size <= pool_max[i])
> 			return dma_pool_alloc(hcd->pool[i], mem_flags, dma);
> 	}
>-	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
>+	return dma_alloc_coherent(hcd->self.sysdev, size, dma, mem_flags);
> }
>
> void hcd_buffer_free(
>@@ -154,7 +154,7 @@ void hcd_buffer_free(
> 		return;
>
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!bus->controller->dma_mask &&
>+	    (!bus->sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
> 		kfree(addr);
> 		return;
>@@ -166,5 +166,5 @@ void hcd_buffer_free(
> 			return;
> 		}
> 	}
>-	dma_free_coherent(hcd->self.controller, size, addr, dma);
>+	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
> }
>diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index
>746c47d86cf5..70d48941f8f4 100644
>--- a/drivers/usb/core/hcd.c
>+++ b/drivers/usb/core/hcd.c
>@@ -1072,6 +1072,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
>static int register_root_hub(struct usb_hcd *hcd)  {
> 	struct device *parent_dev = hcd->self.controller;
>+	struct device *sysdev = hcd->self.sysdev;
> 	struct usb_device *usb_dev = hcd->self.root_hub;
> 	const int devnum = 1;
> 	int retval;
>@@ -1118,7 +1119,7 @@ static int register_root_hub(struct usb_hcd *hcd)
> 		/* Did the HC die before the root hub was registered? */
> 		if (HCD_DEAD(hcd))
> 			usb_hc_died (hcd);	/* This time clean up */
>-		usb_dev->dev.of_node = parent_dev->of_node;
>+		usb_dev->dev.of_node = sysdev->of_node;
> 	}
> 	mutex_unlock(&usb_bus_idr_lock);
>
>@@ -1464,19 +1465,19 @@ void usb_hcd_unmap_urb_for_dma(struct usb_hcd
>*hcd, struct urb *urb)
> 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
> 	if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 	    (urb->transfer_flags & URB_DMA_MAP_SG))
>-		dma_unmap_sg(hcd->self.controller,
>+		dma_unmap_sg(hcd->self.sysdev,
> 				urb->sg,
> 				urb->num_sgs,
> 				dir);
> 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 		 (urb->transfer_flags & URB_DMA_MAP_PAGE))
>-		dma_unmap_page(hcd->self.controller,
>+		dma_unmap_page(hcd->self.sysdev,
> 				urb->transfer_dma,
> 				urb->transfer_buffer_length,
> 				dir);
> 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 		 (urb->transfer_flags & URB_DMA_MAP_SINGLE))
>-		dma_unmap_single(hcd->self.controller,
>+		dma_unmap_single(hcd->self.sysdev,
> 				urb->transfer_dma,
> 				urb->transfer_buffer_length,
> 				dir);
>@@ -1519,11 +1520,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 			return ret;
> 		if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
> 			urb->setup_dma = dma_map_single(
>-					hcd->self.controller,
>+					hcd->self.sysdev,
> 					urb->setup_packet,
> 					sizeof(struct usb_ctrlrequest),
> 					DMA_TO_DEVICE);
>-			if (dma_mapping_error(hcd->self.controller,
>+			if (dma_mapping_error(hcd->self.sysdev,
> 						urb->setup_dma))
> 				return -EAGAIN;
> 			urb->transfer_flags |= URB_SETUP_MAP_SINGLE; @@ -
>1554,7 +1555,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb
>*urb,
> 				}
>
> 				n = dma_map_sg(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						urb->sg,
> 						urb->num_sgs,
> 						dir);
>@@ -1569,12 +1570,12 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 			} else if (urb->sg) {
> 				struct scatterlist *sg = urb->sg;
> 				urb->transfer_dma = dma_map_page(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						sg_page(sg),
> 						sg->offset,
> 						urb->transfer_buffer_length,
> 						dir);
>-				if (dma_mapping_error(hcd->self.controller,
>+				if (dma_mapping_error(hcd->self.sysdev,
> 						urb->transfer_dma))
> 					ret = -EAGAIN;
> 				else
>@@ -1584,11 +1585,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 				ret = -EAGAIN;
> 			} else {
> 				urb->transfer_dma = dma_map_single(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						urb->transfer_buffer,
> 						urb->transfer_buffer_length,
> 						dir);
>-				if (dma_mapping_error(hcd->self.controller,
>+				if (dma_mapping_error(hcd->self.sysdev,
> 						urb->transfer_dma))
> 					ret = -EAGAIN;
> 				else
>@@ -2510,8 +2511,8 @@ static void init_giveback_urb_bh(struct giveback_urb_bh
>*bh)
>  * Return: On success, a pointer to the created and initialized HCD structure.
>  * On failure (e.g. if memory is unavailable), %NULL.
>  */
>-struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>-		struct device *dev, const char *bus_name,
>+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
>+		struct device *sysdev, struct device *dev, const char *bus_name,
> 		struct usb_hcd *primary_hcd)
> {
> 	struct usb_hcd *hcd;
>@@ -2552,8 +2553,9 @@ struct usb_hcd *usb_create_shared_hcd(const struct
>hc_driver *driver,
>
> 	usb_bus_init(&hcd->self);
> 	hcd->self.controller = dev;
>+	hcd->self.sysdev = sysdev;
> 	hcd->self.bus_name = bus_name;
>-	hcd->self.uses_dma = (dev->dma_mask != NULL);
>+	hcd->self.uses_dma = (sysdev->dma_mask != NULL);
>
> 	init_timer(&hcd->rh_timer);
> 	hcd->rh_timer.function = rh_timer_func; @@ -2568,6 +2570,14 @@ struct
>usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> 			"USB Host Controller";
> 	return hcd;
> }
>+EXPORT_SYMBOL_GPL(__usb_create_hcd);
>+
>+struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>+		struct device *dev, const char *bus_name,
>+		struct usb_hcd *primary_hcd)
>+{
>+	return __usb_create_hcd(driver, dev, dev, bus_name, primary_hcd); }
> EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
>
> /**
>@@ -2587,7 +2597,7 @@ EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
> struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
> 		struct device *dev, const char *bus_name)  {
>-	return usb_create_shared_hcd(driver, dev, bus_name, NULL);
>+	return __usb_create_hcd(driver, dev, dev, bus_name, NULL);
> }
> EXPORT_SYMBOL_GPL(usb_create_hcd);
>
>@@ -2714,7 +2724,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	struct usb_device *rhdev;
>
> 	if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
>-		struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
>+		struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
>
> 		if (IS_ERR(phy)) {
> 			retval = PTR_ERR(phy);
>@@ -2732,7 +2742,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	}
>
> 	if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
>-		struct phy *phy = phy_get(hcd->self.controller, "usb");
>+		struct phy *phy = phy_get(hcd->self.sysdev, "usb");
>
> 		if (IS_ERR(phy)) {
> 			retval = PTR_ERR(phy);
>@@ -2780,7 +2790,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	 */
> 	retval = hcd_buffer_create(hcd);
> 	if (retval != 0) {
>-		dev_dbg(hcd->self.controller, "pool alloc failed\n");
>+		dev_dbg(hcd->self.sysdev, "pool alloc failed\n");
> 		goto err_create_buf;
> 	}
>
>@@ -2790,7 +2800,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
>
> 	rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
> 	if (rhdev == NULL) {
>-		dev_err(hcd->self.controller, "unable to allocate root hub\n");
>+		dev_err(hcd->self.sysdev, "unable to allocate root hub\n");
> 		retval = -ENOMEM;
> 		goto err_allocate_root_hub;
> 	}
>diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index
>5e80697ef952..199f67ae8857 100644
>--- a/drivers/usb/core/usb.c
>+++ b/drivers/usb/core/usb.c
>@@ -440,8 +440,8 @@ struct usb_device *usb_alloc_dev(struct usb_device
>*parent,
> 	dev->dev.bus = &usb_bus_type;
> 	dev->dev.type = &usb_device_type;
> 	dev->dev.groups = usb_device_groups;
>-	dev->dev.dma_mask = bus->controller->dma_mask;
>-	set_dev_node(&dev->dev, dev_to_node(bus->controller));
>+	dev->dev.dma_mask = bus->sysdev->dma_mask;
>+	set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
> 	dev->state = USB_STATE_ATTACHED;
> 	dev->lpm_disable_count = 1;
> 	atomic_set(&dev->urbnum, 0);
>@@ -789,7 +789,7 @@ struct urb *usb_buffer_map(struct urb *urb)
> 	if (!urb
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return NULL;
>
> 	if (controller->dma_mask) {
>@@ -827,7 +827,7 @@ void usb_buffer_dmasync(struct urb *urb)
> 			|| !(urb->transfer_flags &
>URB_NO_TRANSFER_DMA_MAP)
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return;
>
> 	if (controller->dma_mask) {
>@@ -861,7 +861,7 @@ void usb_buffer_unmap(struct urb *urb)
> 			|| !(urb->transfer_flags &
>URB_NO_TRANSFER_DMA_MAP)
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return;
>
> 	if (controller->dma_mask) {
>@@ -911,7 +911,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, int
>is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return -EINVAL;
>
>@@ -947,7 +947,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev,
>int is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return;
>
>@@ -975,7 +975,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev,
>int is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return;
>
>diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index
>35d092456bec..08db66c64c66 100644
>--- a/drivers/usb/dwc3/core.c
>+++ b/drivers/usb/dwc3/core.c
>@@ -25,6 +25,7 @@
> #include <linux/slab.h>
> #include <linux/spinlock.h>
> #include <linux/platform_device.h>
>+#include <linux/pci.h>
> #include <linux/pm_runtime.h>
> #include <linux/interrupt.h>
> #include <linux/ioport.h>
>@@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3
>*dwc)  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
> 		struct dwc3_event_buffer *evt)
> {
>-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
>+	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
> }
>
> /**
>@@ -200,7 +201,7 @@ static struct dwc3_event_buffer
>*dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
>
> 	evt->dwc	= dwc;
> 	evt->length	= length;
>-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
>+	evt->buf	= dma_alloc_coherent(dwc->sysdev, length,
> 			&evt->dma, GFP_KERNEL);
> 	if (!evt->buf)
> 		return ERR_PTR(-ENOMEM);
>@@ -319,11 +320,11 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
> 	if (!WARN_ON(dwc->scratchbuf))
> 		return 0;
>
>-	scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
>+	scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
> 			dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
> 			DMA_BIDIRECTIONAL);
>-	if (dma_mapping_error(dwc->dev, scratch_addr)) {
>-		dev_err(dwc->dev, "failed to map scratch buffer\n");
>+	if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
>+		dev_err(dwc->sysdev, "failed to map scratch buffer\n");
> 		ret = -EFAULT;
> 		goto err0;
> 	}
>@@ -347,7 +348,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
> 	return 0;
>
> err1:
>-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
>+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
> 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
>
> err0:
>@@ -366,7 +367,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
> 	if (!WARN_ON(dwc->scratchbuf))
> 		return;
>
>-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
>+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
> 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
> 	kfree(dwc->scratchbuf);
> }
>@@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
> 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
> 	dwc->mem = mem;
> 	dwc->dev = dev;
>+#ifdef CONFIG_PCI
>+	/* TODO: or some other way of detecting this? */
>+	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
>+		dwc->sysdev = dwc->dev->parent;
>+	else
>+#endif
>+		dwc->sysdev = dwc->dev;
>
> 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> 	if (!res) {
>@@ -949,12 +957,6 @@ static int dwc3_probe(struct platform_device *pdev)
>
> 	spin_lock_init(&dwc->lock);
>
>-	if (!dev->dma_mask) {
>-		dev->dma_mask = dev->parent->dma_mask;
>-		dev->dma_parms = dev->parent->dma_parms;
>-		dma_set_coherent_mask(dev, dev->parent-
>>coherent_dma_mask);
>-	}
>-
> 	pm_runtime_set_active(dev);
> 	pm_runtime_use_autosuspend(dev);
> 	pm_runtime_set_autosuspend_delay(dev,
>DWC3_DEFAULT_AUTOSUSPEND_DELAY); diff --git a/drivers/usb/dwc3/core.h
>b/drivers/usb/dwc3/core.h index 45d6de5107c7..2fbc92143ab9 100644
>--- a/drivers/usb/dwc3/core.h
>+++ b/drivers/usb/dwc3/core.h
>@@ -823,6 +823,7 @@ struct dwc3 {
> 	spinlock_t		lock;
>
> 	struct device		*dev;
>+	struct device		*sysdev;
>
> 	struct platform_device	*xhci;
> 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
>diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
>index 2f1fb7e7aa54..e27899bb5706 100644
>--- a/drivers/usb/dwc3/dwc3-exynos.c
>+++ b/drivers/usb/dwc3/dwc3-exynos.c
>@@ -20,7 +20,6 @@
> #include <linux/kernel.h>
> #include <linux/slab.h>
> #include <linux/platform_device.h>
>-#include <linux/dma-mapping.h>
> #include <linux/clk.h>
> #include <linux/usb/otg.h>
> #include <linux/usb/usb_phy_generic.h>
>@@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device
>*pdev)
> 	if (!exynos)
> 		return -ENOMEM;
>
>-	/*
>-	 * Right now device-tree probed devices don't get dma_mask set.
>-	 * Since shared usb code relies on it, set it here for now.
>-	 * Once we move to full device tree support this will vanish off.
>-	 */
>-	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
>-	if (ret)
>-		return ret;
>-
> 	platform_set_drvdata(pdev, exynos);
>
> 	exynos->dev	= dev;
>diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index
>89a2f712fdfe..4d7439cb8cd8 100644
>--- a/drivers/usb/dwc3/dwc3-st.c
>+++ b/drivers/usb/dwc3/dwc3-st.c
>@@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
> 	if (IS_ERR(regmap))
> 		return PTR_ERR(regmap);
>
>-	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
> 	dwc3_data->dev = dev;
> 	dwc3_data->regmap = regmap;
>
>diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index
>ae4c5e89c134..9cda9ee91b9d 100644
>--- a/drivers/usb/dwc3/ep0.c
>+++ b/drivers/usb/dwc3/ep0.c
>@@ -974,8 +974,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3
>*dwc,
> 		u32	transfer_size = 0;
> 		u32	maxpacket;
>
>-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-				dep->number);
>+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+				&req->request, dep->number);
> 		if (ret) {
> 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
> 			return;
>@@ -1002,8 +1002,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3
>*dwc,
> 				dwc->ep0_bounce_addr, transfer_size,
> 				DWC3_TRBCTL_CONTROL_DATA, false);
> 	} else {
>-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-				dep->number);
>+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+				&req->request, dep->number);
> 		if (ret) {
> 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
> 			return;
>diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index
>122e64df2f4d..77d62ce4547f 100644
>--- a/drivers/usb/dwc3/gadget.c
>+++ b/drivers/usb/dwc3/gadget.c
>@@ -192,8 +192,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct
>dwc3_request *req,
> 	if (dwc->ep0_bounced && dep->number == 0)
> 		dwc->ep0_bounced = false;
> 	else
>-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
>-				req->direction);
>+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
>+				&req->request, req->direction);
>
> 	trace_dwc3_gadget_giveback(req);
>
>@@ -371,7 +371,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
> 	if (dep->trb_pool)
> 		return 0;
>
>-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
>+	dep->trb_pool = dma_alloc_coherent(dwc->sysdev,
> 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
> 			&dep->trb_pool_dma, GFP_KERNEL);
> 	if (!dep->trb_pool) {
>@@ -387,7 +387,7 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)  {
> 	struct dwc3		*dwc = dep->dwc;
>
>-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) *
>DWC3_TRB_NUM,
>+	dma_free_coherent(dwc->sysdev, sizeof(struct dwc3_trb) *
>DWC3_TRB_NUM,
> 			dep->trb_pool, dep->trb_pool_dma);
>
> 	dep->trb_pool = NULL;
>@@ -1027,8 +1027,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep
>*dep, u16 cmd_param)
> 		 * here and stop, unmap, free and del each of the linked
> 		 * requests instead of what we do now.
> 		 */
>-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
>-				req->direction);
>+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
>+				&req->request, req->direction);
> 		list_del(&req->list);
> 		return ret;
> 	}
>@@ -1113,8 +1113,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep
>*dep, struct dwc3_request *req)
> 	 * This will also avoid Host cancelling URBs due to too
> 	 * many NAKs.
> 	 */
>-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-			dep->direction);
>+	ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+		&req->request, dep->direction);
> 	if (ret)
> 		return ret;
>
>@@ -2953,7 +2953,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>
> 	dwc->irq_gadget = irq;
>
>-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dwc->ctrl_req = dma_alloc_coherent(dwc->sysdev,
>+sizeof(*dwc->ctrl_req),
> 			&dwc->ctrl_req_addr, GFP_KERNEL);
> 	if (!dwc->ctrl_req) {
> 		dev_err(dwc->dev, "failed to allocate ctrl request\n"); @@ -2961,7
>+2961,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> 		goto err0;
> 	}
>
>-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
>+	dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb)
>*
>+2,
> 			&dwc->ep0_trb_addr, GFP_KERNEL);
> 	if (!dwc->ep0_trb) {
> 		dev_err(dwc->dev, "failed to allocate ep0 trb\n"); @@ -2975,7
>+2975,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> 		goto err2;
> 	}
>
>-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
>+	dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev,
> 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
> 			GFP_KERNEL);
> 	if (!dwc->ep0_bounce) {
>@@ -3047,18 +3047,18 @@ err5:
>
> err4:
> 	dwc3_gadget_free_endpoints(dwc);
>-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
>+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
> 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
>
> err3:
> 	kfree(dwc->setup_buf);
>
> err2:
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
> 			dwc->ep0_trb, dwc->ep0_trb_addr);
>
> err1:
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
> 			dwc->ctrl_req, dwc->ctrl_req_addr);
>
> err0:
>@@ -3073,16 +3073,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
>
> 	dwc3_gadget_free_endpoints(dwc);
>
>-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
>+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
> 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
>
> 	kfree(dwc->setup_buf);
> 	kfree(dwc->zlp_buf);
>
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
> 			dwc->ep0_trb, dwc->ep0_trb_addr);
>
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
> 			dwc->ctrl_req, dwc->ctrl_req_addr);
> }
>
>diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index
>f6533c68fed1..3c078e85fa98 100644
>--- a/drivers/usb/dwc3/host.c
>+++ b/drivers/usb/dwc3/host.c
>@@ -72,12 +72,7 @@ int dwc3_host_init(struct dwc3 *dwc)
> 		return -ENOMEM;
> 	}
>
>-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
>-
> 	xhci->dev.parent	= dwc->dev;
>-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
>-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
>-
> 	dwc->xhci = xhci;
>
> 	ret = platform_device_add_resources(xhci, dwc->xhci_resources, @@ -
>112,9 +107,9 @@ int dwc3_host_init(struct dwc3 *dwc)
> 	return 0;
> err2:
> 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
>-			  dev_name(&xhci->dev));
>+			  dev_name(dwc->dev));
> 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
>-			  dev_name(&xhci->dev));
>+			  dev_name(dwc->dev));
> err1:
> 	platform_device_put(xhci);
> 	return ret;
>@@ -123,8 +118,8 @@ err1:
> void dwc3_host_exit(struct dwc3 *dwc)
> {
> 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
>-			  dev_name(&dwc->xhci->dev));
>+			  dev_name(dwc->dev));
> 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
>-			  dev_name(&dwc->xhci->dev));
>+			  dev_name(dwc->dev));
> 	platform_device_unregister(dwc->xhci);
> }
>diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index
>9f5ffb629973..b2419950221f 100644
>--- a/drivers/usb/host/ehci-fsl.c
>+++ b/drivers/usb/host/ehci-fsl.c
>@@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
> 	}
> 	irq = res->start;
>
>-	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
>-				dev_name(&pdev->dev));
>+	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
>+				&pdev->dev, dev_name(&pdev->dev), NULL);
> 	if (!hcd) {
> 		retval = -ENOMEM;
> 		goto err1;
>diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index
>ed56bf9ed885..c1d69e14432d 100644
>--- a/drivers/usb/host/xhci-plat.c
>+++ b/drivers/usb/host/xhci-plat.c
>@@ -14,6 +14,7 @@
> #include <linux/clk.h>
> #include <linux/dma-mapping.h>
> #include <linux/module.h>
>+#include <linux/pci.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/usb/phy.h>
>@@ -139,6 +140,7 @@ static int xhci_plat_probe(struct platform_device *pdev)  {
> 	const struct of_device_id *match;
> 	const struct hc_driver	*driver;
>+	struct device		*sysdev;
> 	struct xhci_hcd		*xhci;
> 	struct resource         *res;
> 	struct usb_hcd		*hcd;
>@@ -155,22 +157,38 @@ static int xhci_plat_probe(struct platform_device *pdev)
> 	if (irq < 0)
> 		return -ENODEV;
>
>+	/*
>+	 * sysdev must point to a device that is known to the system firmware
>+	 * or PCI hardware. We handle these three cases here:
>+	 * 1. xhci_plat comes from firmware
>+	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
>+	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
>+	 */
>+	sysdev = &pdev->dev;
>+	if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node)
>+		sysdev = sysdev->parent;
>+#ifdef CONFIG_PCI
>+	else if (sysdev->parent && sysdev->parent->parent &&
>+		 sysdev->parent->parent->bus == &pci_bus_type)
>+		sysdev = sysdev->parent->parent;
>+#endif
>+
> 	/* Try to set 64-bit DMA first */
>-	if (WARN_ON(!pdev->dev.dma_mask))
>+	if (WARN_ON(!sysdev->dma_mask))
> 		/* Platform did not initialize dma_mask */
>-		ret = dma_coerce_mask_and_coherent(&pdev->dev,
>+		ret = dma_coerce_mask_and_coherent(sysdev,
> 						   DMA_BIT_MASK(64));
> 	else
>-		ret = dma_set_mask_and_coherent(&pdev->dev,
>DMA_BIT_MASK(64));
>+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
>
> 	/* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
> 	if (ret) {
>-		ret = dma_set_mask_and_coherent(&pdev->dev,
>DMA_BIT_MASK(32));
>+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
> 		if (ret)
> 			return ret;
> 	}
>
>-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
>+dev_name(&pdev->dev), NULL);
> 	if (!hcd)
> 		return -ENOMEM;
>
>@@ -220,13 +238,13 @@ static int xhci_plat_probe(struct platform_device *pdev)
> 		goto disable_clk;
> 	}
>
>-	if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
>+	if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
> 		xhci->quirks |= XHCI_LPM_SUPPORT;
>
> 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
> 		xhci->shared_hcd->can_do_streams = 1;
>
>-	hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy",
>0);
>+	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
> 	if (IS_ERR(hcd->usb_phy)) {
> 		ret = PTR_ERR(hcd->usb_phy);
> 		if (ret == -EPROBE_DEFER)
>diff --git a/include/linux/usb.h b/include/linux/usb.h index
>eba1f10e8cfd..f3f5d8a396e4 100644
>--- a/include/linux/usb.h
>+++ b/include/linux/usb.h
>@@ -354,6 +354,7 @@ struct usb_devmap {
>  */
> struct usb_bus {
> 	struct device *controller;	/* host/master side hardware */
>+	struct device *sysdev;		/* as seen from firmware or bus */
> 	int busnum;			/* Bus number (in order of reg) */
> 	const char *bus_name;		/* stable id (PCI slot_name etc) */
> 	u8 uses_dma;			/* Does the host controller use DMA? */
>diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index
>66fc13705ab7..3860560a61bb 100644
>--- a/include/linux/usb/hcd.h
>+++ b/include/linux/usb/hcd.h
>@@ -437,6 +437,9 @@ extern int usb_hcd_alloc_bandwidth(struct usb_device
>*udev,
> 		struct usb_host_interface *new_alt);
> extern int usb_hcd_get_frame_number(struct usb_device *udev);
>
>+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
>+		struct device *sysdev, struct device *dev, const char *bus_name,
>+		struct usb_hcd *primary_hcd);
> extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
> 		struct device *dev, const char *bus_name);  extern struct usb_hcd
>*usb_create_shared_hcd(const struct hc_driver *driver,
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a
>message to majordomo@vger.kernel.org More majordomo info at
>http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-21 11:06                                                         ` Sriram Dash
  0 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-21 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-owner at vger.kernel.org]
>On Wednesday, September 7, 2016 1:24:07 PM CEST Felipe Balbi wrote:
>>
>> Hi,
>>
>> Arnd Bergmann <arnd@arndb.de> writes:
>>
>> [...]
>>
>> > Regarding the DMA configuration that you mention in
>> > ci_hdrc_add_device(), I think we should replace
>> >
>> >         pdev->dev.dma_mask = dev->dma_mask;
>> >         pdev->dev.dma_parms = dev->dma_parms;
>> >         dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>> >
>> > with of_dma_configure(), which has the chance to configure more than
>> > just those three, as the dma API might look into different aspects:
>> >
>> > - iommu specific configuration
>> > - cache coherency information
>> > - bus type
>> > - dma offset
>> > - dma_map_ops pointer
>> >
>> > We try to handle everything in of_dma_configure() at configuration
>> > time, and that would be the place to add anything else that we might
>> > need in the future.
>>
>> There are a couple problems with this:
>>
>> 1) won't work for PCI-based systems.
>>
>> DWC3 is used in production PCI-based HW and also in Synopsys HAPS DX
>> platform (FPGA that appears like a PCI card to host PC)
>
>Right, I was specifically talking about the code in chipidea here, which I think is
>never used on the PCI bus, and how the current code is broken. We can probably do
>better than of_dma_configure() (see below), but it would be an improvement.
>
>> 2) not very robust solution
>>
>> of_dma_configure() will hardcode 32-bit DMA dmask for xhci-plat
>> because that's not created by DT. The only reason why this works at
>> all is because of the default 32-bit dma mask thing :-) So, how is it
>> any different than copying 32-bit dma mask from parent?
>
>The idea here is that you pass in the parent of_node along with the child device
>pointer, so it would behave exactly like the parent already does.
>The difference is that it also handles all the other attributes besides the mask.
>
>However, to summarize the discussion so far, I agree that
>of_dma_configure() is not the solution to these problems, and I think we can do
>much better:
>
>Splitting the usb_bus->controller field into the Linux-internal device (used for the
>sysfs hierarchy, for printks and for power management) and a new pointer (used for
>DMA, DT enumeration and phy lookup) probably covers all that we really need.
>
>I've prototyped it below, with the dwc3, xhci and chipidea changes together with
>the core changes. I've surely made mistakes there and don't expect it to work out
>of the box, but this should give an idea of how I think this can all be solved in the
>least invasive way.
>

Hello Arnd,

We tried this patch on NXP platforms (ls2085 and ls1043) which use dwc3 
controller without any glue layer. On first go, this did not work. But after
minimal reworks mention snippet below, we are able to verify that the USB
was working OK.

 drivers/usb/host/xhci-mem.c | 12 ++++++------
 drivers/usb/host/xhci.c     | 20 ++++++++++----------

-       struct device *dev = xhci_to_hcd(xhci)->self.controller;
+       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;

We believe the patch needs little modification to work or there might be chances
we may have missed something. Any idea?

Regards,
Sriram

>I noticed that the gadget interface already has a way to handle the DMA allocation
>by device, so I added that in as well.
>
>Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>
> drivers/usb/chipidea/core.c    |  4 ----
> drivers/usb/chipidea/host.c    |  3 ++-
> drivers/usb/chipidea/udc.c     |  8 ++++----
> drivers/usb/core/buffer.c      | 12 ++++++------
> drivers/usb/core/hcd.c         | 48 +++++++++++++++++++++++++++++------------------
>-
> drivers/usb/core/usb.c         | 16 ++++++++--------
> drivers/usb/dwc3/core.c        | 28 +++++++++++++++-------------
> drivers/usb/dwc3/core.h        |  1 +
> drivers/usb/dwc3/dwc3-exynos.c | 10 ----------
> drivers/usb/dwc3/dwc3-st.c     |  1 -
> drivers/usb/dwc3/ep0.c         |  8 ++++----
> drivers/usb/dwc3/gadget.c      | 34 +++++++++++++++++-----------------
> drivers/usb/dwc3/host.c        | 13 ++++---------
> drivers/usb/host/ehci-fsl.c    |  4 ++--
> drivers/usb/host/xhci-plat.c   | 32 +++++++++++++++++++++++++-------
> include/linux/usb.h            |  1 +
> include/linux/usb/hcd.h        |  3 +++
>
>diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index
>69426e644d17..dff69837b349 100644
>--- a/drivers/usb/chipidea/core.c
>+++ b/drivers/usb/chipidea/core.c
>@@ -833,10 +833,6 @@ struct platform_device *ci_hdrc_add_device(struct device
>*dev,
> 	}
>
> 	pdev->dev.parent = dev;
>-	pdev->dev.dma_mask = dev->dma_mask;
>-	pdev->dev.dma_parms = dev->dma_parms;
>-	dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
>-
> 	ret = platform_device_add_resources(pdev, res, nres);
> 	if (ret)
> 		goto err;
>diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index
>053bac9d983c..40d29c4d7772 100644
>--- a/drivers/usb/chipidea/host.c
>+++ b/drivers/usb/chipidea/host.c
>@@ -113,7 +113,8 @@ static int host_start(struct ci_hdrc *ci)
> 	if (usb_disabled())
> 		return -ENODEV;
>
>-	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
>+	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
>+			       ci->dev, dev_name(ci->dev), NULL);
> 	if (!hcd)
> 		return -ENOMEM;
>
>diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index
>0f692fcda638..4cbfff7934c6 100644
>--- a/drivers/usb/chipidea/udc.c
>+++ b/drivers/usb/chipidea/udc.c
>@@ -424,7 +424,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep,
>struct ci_hw_req *hwreq)
>
> 	hwreq->req.status = -EALREADY;
>
>-	ret = usb_gadget_map_request(&ci->gadget, &hwreq->req, hwep->dir);
>+	ret = usb_gadget_map_request_by_dev(&ci->dev->parent, &hwreq->req,
>+hwep->dir);
> 	if (ret)
> 		return ret;
>
>@@ -604,7 +604,7 @@ static int _hardware_dequeue(struct ci_hw_ep *hwep,
>struct ci_hw_req *hwreq)
> 		list_del_init(&node->td);
> 	}
>
>-	usb_gadget_unmap_request(&hwep->ci->gadget, &hwreq->req, hwep-
>>dir);
>+	usb_gadget_unmap_request_by_dev(&hwep->ci->dev->parent, &hwreq-
>>req,
>+hwep->dir);
>
> 	hwreq->req.actual += actual;
>
>@@ -1898,13 +1898,13 @@ static int udc_start(struct ci_hdrc *ci)
> 	INIT_LIST_HEAD(&ci->gadget.ep_list);
>
> 	/* alloc resources */
>-	ci->qh_pool = dma_pool_create("ci_hw_qh", dev,
>+	ci->qh_pool = dma_pool_create("ci_hw_qh", dev->parent,
> 				       sizeof(struct ci_hw_qh),
> 				       64, CI_HDRC_PAGE_SIZE);
> 	if (ci->qh_pool == NULL)
> 		return -ENOMEM;
>
>-	ci->td_pool = dma_pool_create("ci_hw_td", dev,
>+	ci->td_pool = dma_pool_create("ci_hw_td", dev->parent,
> 				       sizeof(struct ci_hw_td),
> 				       64, CI_HDRC_PAGE_SIZE);
> 	if (ci->td_pool == NULL) {
>diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index
>98e39f91723a..1e41ef7f3c1f 100644
>--- a/drivers/usb/core/buffer.c
>+++ b/drivers/usb/core/buffer.c
>@@ -63,7 +63,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
> 	int		i, size;
>
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!hcd->self.controller->dma_mask &&
>+	    (!hcd->self.sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM)))
> 		return 0;
>
>@@ -72,7 +72,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
> 		if (!size)
> 			continue;
> 		snprintf(name, sizeof(name), "buffer-%d", size);
>-		hcd->pool[i] = dma_pool_create(name, hcd->self.controller,
>+		hcd->pool[i] = dma_pool_create(name, hcd->self.sysdev,
> 				size, size, 0);
> 		if (!hcd->pool[i]) {
> 			hcd_buffer_destroy(hcd);
>@@ -127,7 +127,7 @@ void *hcd_buffer_alloc(
>
> 	/* some USB hosts just use PIO */
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!bus->controller->dma_mask &&
>+	    (!bus->sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
> 		*dma = ~(dma_addr_t) 0;
> 		return kmalloc(size, mem_flags);
>@@ -137,7 +137,7 @@ void *hcd_buffer_alloc(
> 		if (size <= pool_max[i])
> 			return dma_pool_alloc(hcd->pool[i], mem_flags, dma);
> 	}
>-	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);
>+	return dma_alloc_coherent(hcd->self.sysdev, size, dma, mem_flags);
> }
>
> void hcd_buffer_free(
>@@ -154,7 +154,7 @@ void hcd_buffer_free(
> 		return;
>
> 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
>-	    (!bus->controller->dma_mask &&
>+	    (!bus->sysdev->dma_mask &&
> 	     !(hcd->driver->flags & HCD_LOCAL_MEM))) {
> 		kfree(addr);
> 		return;
>@@ -166,5 +166,5 @@ void hcd_buffer_free(
> 			return;
> 		}
> 	}
>-	dma_free_coherent(hcd->self.controller, size, addr, dma);
>+	dma_free_coherent(hcd->self.sysdev, size, addr, dma);
> }
>diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index
>746c47d86cf5..70d48941f8f4 100644
>--- a/drivers/usb/core/hcd.c
>+++ b/drivers/usb/core/hcd.c
>@@ -1072,6 +1072,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
>static int register_root_hub(struct usb_hcd *hcd)  {
> 	struct device *parent_dev = hcd->self.controller;
>+	struct device *sysdev = hcd->self.sysdev;
> 	struct usb_device *usb_dev = hcd->self.root_hub;
> 	const int devnum = 1;
> 	int retval;
>@@ -1118,7 +1119,7 @@ static int register_root_hub(struct usb_hcd *hcd)
> 		/* Did the HC die before the root hub was registered? */
> 		if (HCD_DEAD(hcd))
> 			usb_hc_died (hcd);	/* This time clean up */
>-		usb_dev->dev.of_node = parent_dev->of_node;
>+		usb_dev->dev.of_node = sysdev->of_node;
> 	}
> 	mutex_unlock(&usb_bus_idr_lock);
>
>@@ -1464,19 +1465,19 @@ void usb_hcd_unmap_urb_for_dma(struct usb_hcd
>*hcd, struct urb *urb)
> 	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
> 	if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 	    (urb->transfer_flags & URB_DMA_MAP_SG))
>-		dma_unmap_sg(hcd->self.controller,
>+		dma_unmap_sg(hcd->self.sysdev,
> 				urb->sg,
> 				urb->num_sgs,
> 				dir);
> 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 		 (urb->transfer_flags & URB_DMA_MAP_PAGE))
>-		dma_unmap_page(hcd->self.controller,
>+		dma_unmap_page(hcd->self.sysdev,
> 				urb->transfer_dma,
> 				urb->transfer_buffer_length,
> 				dir);
> 	else if (IS_ENABLED(CONFIG_HAS_DMA) &&
> 		 (urb->transfer_flags & URB_DMA_MAP_SINGLE))
>-		dma_unmap_single(hcd->self.controller,
>+		dma_unmap_single(hcd->self.sysdev,
> 				urb->transfer_dma,
> 				urb->transfer_buffer_length,
> 				dir);
>@@ -1519,11 +1520,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 			return ret;
> 		if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
> 			urb->setup_dma = dma_map_single(
>-					hcd->self.controller,
>+					hcd->self.sysdev,
> 					urb->setup_packet,
> 					sizeof(struct usb_ctrlrequest),
> 					DMA_TO_DEVICE);
>-			if (dma_mapping_error(hcd->self.controller,
>+			if (dma_mapping_error(hcd->self.sysdev,
> 						urb->setup_dma))
> 				return -EAGAIN;
> 			urb->transfer_flags |= URB_SETUP_MAP_SINGLE; @@ -
>1554,7 +1555,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb
>*urb,
> 				}
>
> 				n = dma_map_sg(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						urb->sg,
> 						urb->num_sgs,
> 						dir);
>@@ -1569,12 +1570,12 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 			} else if (urb->sg) {
> 				struct scatterlist *sg = urb->sg;
> 				urb->transfer_dma = dma_map_page(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						sg_page(sg),
> 						sg->offset,
> 						urb->transfer_buffer_length,
> 						dir);
>-				if (dma_mapping_error(hcd->self.controller,
>+				if (dma_mapping_error(hcd->self.sysdev,
> 						urb->transfer_dma))
> 					ret = -EAGAIN;
> 				else
>@@ -1584,11 +1585,11 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd,
>struct urb *urb,
> 				ret = -EAGAIN;
> 			} else {
> 				urb->transfer_dma = dma_map_single(
>-						hcd->self.controller,
>+						hcd->self.sysdev,
> 						urb->transfer_buffer,
> 						urb->transfer_buffer_length,
> 						dir);
>-				if (dma_mapping_error(hcd->self.controller,
>+				if (dma_mapping_error(hcd->self.sysdev,
> 						urb->transfer_dma))
> 					ret = -EAGAIN;
> 				else
>@@ -2510,8 +2511,8 @@ static void init_giveback_urb_bh(struct giveback_urb_bh
>*bh)
>  * Return: On success, a pointer to the created and initialized HCD structure.
>  * On failure (e.g. if memory is unavailable), %NULL.
>  */
>-struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>-		struct device *dev, const char *bus_name,
>+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
>+		struct device *sysdev, struct device *dev, const char *bus_name,
> 		struct usb_hcd *primary_hcd)
> {
> 	struct usb_hcd *hcd;
>@@ -2552,8 +2553,9 @@ struct usb_hcd *usb_create_shared_hcd(const struct
>hc_driver *driver,
>
> 	usb_bus_init(&hcd->self);
> 	hcd->self.controller = dev;
>+	hcd->self.sysdev = sysdev;
> 	hcd->self.bus_name = bus_name;
>-	hcd->self.uses_dma = (dev->dma_mask != NULL);
>+	hcd->self.uses_dma = (sysdev->dma_mask != NULL);
>
> 	init_timer(&hcd->rh_timer);
> 	hcd->rh_timer.function = rh_timer_func; @@ -2568,6 +2570,14 @@ struct
>usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
> 			"USB Host Controller";
> 	return hcd;
> }
>+EXPORT_SYMBOL_GPL(__usb_create_hcd);
>+
>+struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
>+		struct device *dev, const char *bus_name,
>+		struct usb_hcd *primary_hcd)
>+{
>+	return __usb_create_hcd(driver, dev, dev, bus_name, primary_hcd); }
> EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
>
> /**
>@@ -2587,7 +2597,7 @@ EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
> struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
> 		struct device *dev, const char *bus_name)  {
>-	return usb_create_shared_hcd(driver, dev, bus_name, NULL);
>+	return __usb_create_hcd(driver, dev, dev, bus_name, NULL);
> }
> EXPORT_SYMBOL_GPL(usb_create_hcd);
>
>@@ -2714,7 +2724,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	struct usb_device *rhdev;
>
> 	if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
>-		struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
>+		struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
>
> 		if (IS_ERR(phy)) {
> 			retval = PTR_ERR(phy);
>@@ -2732,7 +2742,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	}
>
> 	if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
>-		struct phy *phy = phy_get(hcd->self.controller, "usb");
>+		struct phy *phy = phy_get(hcd->self.sysdev, "usb");
>
> 		if (IS_ERR(phy)) {
> 			retval = PTR_ERR(phy);
>@@ -2780,7 +2790,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
> 	 */
> 	retval = hcd_buffer_create(hcd);
> 	if (retval != 0) {
>-		dev_dbg(hcd->self.controller, "pool alloc failed\n");
>+		dev_dbg(hcd->self.sysdev, "pool alloc failed\n");
> 		goto err_create_buf;
> 	}
>
>@@ -2790,7 +2800,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
>
> 	rhdev = usb_alloc_dev(NULL, &hcd->self, 0);
> 	if (rhdev == NULL) {
>-		dev_err(hcd->self.controller, "unable to allocate root hub\n");
>+		dev_err(hcd->self.sysdev, "unable to allocate root hub\n");
> 		retval = -ENOMEM;
> 		goto err_allocate_root_hub;
> 	}
>diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index
>5e80697ef952..199f67ae8857 100644
>--- a/drivers/usb/core/usb.c
>+++ b/drivers/usb/core/usb.c
>@@ -440,8 +440,8 @@ struct usb_device *usb_alloc_dev(struct usb_device
>*parent,
> 	dev->dev.bus = &usb_bus_type;
> 	dev->dev.type = &usb_device_type;
> 	dev->dev.groups = usb_device_groups;
>-	dev->dev.dma_mask = bus->controller->dma_mask;
>-	set_dev_node(&dev->dev, dev_to_node(bus->controller));
>+	dev->dev.dma_mask = bus->sysdev->dma_mask;
>+	set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
> 	dev->state = USB_STATE_ATTACHED;
> 	dev->lpm_disable_count = 1;
> 	atomic_set(&dev->urbnum, 0);
>@@ -789,7 +789,7 @@ struct urb *usb_buffer_map(struct urb *urb)
> 	if (!urb
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return NULL;
>
> 	if (controller->dma_mask) {
>@@ -827,7 +827,7 @@ void usb_buffer_dmasync(struct urb *urb)
> 			|| !(urb->transfer_flags &
>URB_NO_TRANSFER_DMA_MAP)
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return;
>
> 	if (controller->dma_mask) {
>@@ -861,7 +861,7 @@ void usb_buffer_unmap(struct urb *urb)
> 			|| !(urb->transfer_flags &
>URB_NO_TRANSFER_DMA_MAP)
> 			|| !urb->dev
> 			|| !(bus = urb->dev->bus)
>-			|| !(controller = bus->controller))
>+			|| !(controller = bus->sysdev))
> 		return;
>
> 	if (controller->dma_mask) {
>@@ -911,7 +911,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, int
>is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return -EINVAL;
>
>@@ -947,7 +947,7 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev,
>int is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return;
>
>@@ -975,7 +975,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev,
>int is_in,
>
> 	if (!dev
> 			|| !(bus = dev->bus)
>-			|| !(controller = bus->controller)
>+			|| !(controller = bus->sysdev)
> 			|| !controller->dma_mask)
> 		return;
>
>diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index
>35d092456bec..08db66c64c66 100644
>--- a/drivers/usb/dwc3/core.c
>+++ b/drivers/usb/dwc3/core.c
>@@ -25,6 +25,7 @@
> #include <linux/slab.h>
> #include <linux/spinlock.h>
> #include <linux/platform_device.h>
>+#include <linux/pci.h>
> #include <linux/pm_runtime.h>
> #include <linux/interrupt.h>
> #include <linux/ioport.h>
>@@ -178,7 +179,7 @@ static void dwc3_frame_length_adjustment(struct dwc3
>*dwc)  static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
> 		struct dwc3_event_buffer *evt)
> {
>-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
>+	dma_free_coherent(dwc->sysdev, evt->length, evt->buf, evt->dma);
> }
>
> /**
>@@ -200,7 +201,7 @@ static struct dwc3_event_buffer
>*dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
>
> 	evt->dwc	= dwc;
> 	evt->length	= length;
>-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
>+	evt->buf	= dma_alloc_coherent(dwc->sysdev, length,
> 			&evt->dma, GFP_KERNEL);
> 	if (!evt->buf)
> 		return ERR_PTR(-ENOMEM);
>@@ -319,11 +320,11 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
> 	if (!WARN_ON(dwc->scratchbuf))
> 		return 0;
>
>-	scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
>+	scratch_addr = dma_map_single(dwc->sysdev, dwc->scratchbuf,
> 			dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
> 			DMA_BIDIRECTIONAL);
>-	if (dma_mapping_error(dwc->dev, scratch_addr)) {
>-		dev_err(dwc->dev, "failed to map scratch buffer\n");
>+	if (dma_mapping_error(dwc->sysdev, scratch_addr)) {
>+		dev_err(dwc->sysdev, "failed to map scratch buffer\n");
> 		ret = -EFAULT;
> 		goto err0;
> 	}
>@@ -347,7 +348,7 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
> 	return 0;
>
> err1:
>-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
>+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
> 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
>
> err0:
>@@ -366,7 +367,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
> 	if (!WARN_ON(dwc->scratchbuf))
> 		return;
>
>-	dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
>+	dma_unmap_single(dwc->sysdev, dwc->scratch_addr, dwc->nr_scratch *
> 			DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
> 	kfree(dwc->scratchbuf);
> }
>@@ -846,6 +847,13 @@ static int dwc3_probe(struct platform_device *pdev)
> 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
> 	dwc->mem = mem;
> 	dwc->dev = dev;
>+#ifdef CONFIG_PCI
>+	/* TODO: or some other way of detecting this? */
>+	if (dwc->dev->parent && dwc->dev->parent->bus == &pci_bus_type)
>+		dwc->sysdev = dwc->dev->parent;
>+	else
>+#endif
>+		dwc->sysdev = dwc->dev;
>
> 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> 	if (!res) {
>@@ -949,12 +957,6 @@ static int dwc3_probe(struct platform_device *pdev)
>
> 	spin_lock_init(&dwc->lock);
>
>-	if (!dev->dma_mask) {
>-		dev->dma_mask = dev->parent->dma_mask;
>-		dev->dma_parms = dev->parent->dma_parms;
>-		dma_set_coherent_mask(dev, dev->parent-
>>coherent_dma_mask);
>-	}
>-
> 	pm_runtime_set_active(dev);
> 	pm_runtime_use_autosuspend(dev);
> 	pm_runtime_set_autosuspend_delay(dev,
>DWC3_DEFAULT_AUTOSUSPEND_DELAY); diff --git a/drivers/usb/dwc3/core.h
>b/drivers/usb/dwc3/core.h index 45d6de5107c7..2fbc92143ab9 100644
>--- a/drivers/usb/dwc3/core.h
>+++ b/drivers/usb/dwc3/core.h
>@@ -823,6 +823,7 @@ struct dwc3 {
> 	spinlock_t		lock;
>
> 	struct device		*dev;
>+	struct device		*sysdev;
>
> 	struct platform_device	*xhci;
> 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
>diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
>index 2f1fb7e7aa54..e27899bb5706 100644
>--- a/drivers/usb/dwc3/dwc3-exynos.c
>+++ b/drivers/usb/dwc3/dwc3-exynos.c
>@@ -20,7 +20,6 @@
> #include <linux/kernel.h>
> #include <linux/slab.h>
> #include <linux/platform_device.h>
>-#include <linux/dma-mapping.h>
> #include <linux/clk.h>
> #include <linux/usb/otg.h>
> #include <linux/usb/usb_phy_generic.h>
>@@ -117,15 +116,6 @@ static int dwc3_exynos_probe(struct platform_device
>*pdev)
> 	if (!exynos)
> 		return -ENOMEM;
>
>-	/*
>-	 * Right now device-tree probed devices don't get dma_mask set.
>-	 * Since shared usb code relies on it, set it here for now.
>-	 * Once we move to full device tree support this will vanish off.
>-	 */
>-	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
>-	if (ret)
>-		return ret;
>-
> 	platform_set_drvdata(pdev, exynos);
>
> 	exynos->dev	= dev;
>diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index
>89a2f712fdfe..4d7439cb8cd8 100644
>--- a/drivers/usb/dwc3/dwc3-st.c
>+++ b/drivers/usb/dwc3/dwc3-st.c
>@@ -218,7 +218,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
> 	if (IS_ERR(regmap))
> 		return PTR_ERR(regmap);
>
>-	dma_set_coherent_mask(dev, dev->coherent_dma_mask);
> 	dwc3_data->dev = dev;
> 	dwc3_data->regmap = regmap;
>
>diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index
>ae4c5e89c134..9cda9ee91b9d 100644
>--- a/drivers/usb/dwc3/ep0.c
>+++ b/drivers/usb/dwc3/ep0.c
>@@ -974,8 +974,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3
>*dwc,
> 		u32	transfer_size = 0;
> 		u32	maxpacket;
>
>-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-				dep->number);
>+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+				&req->request, dep->number);
> 		if (ret) {
> 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
> 			return;
>@@ -1002,8 +1002,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3
>*dwc,
> 				dwc->ep0_bounce_addr, transfer_size,
> 				DWC3_TRBCTL_CONTROL_DATA, false);
> 	} else {
>-		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-				dep->number);
>+		ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+				&req->request, dep->number);
> 		if (ret) {
> 			dwc3_trace(trace_dwc3_ep0, "failed to map request");
> 			return;
>diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index
>122e64df2f4d..77d62ce4547f 100644
>--- a/drivers/usb/dwc3/gadget.c
>+++ b/drivers/usb/dwc3/gadget.c
>@@ -192,8 +192,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct
>dwc3_request *req,
> 	if (dwc->ep0_bounced && dep->number == 0)
> 		dwc->ep0_bounced = false;
> 	else
>-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
>-				req->direction);
>+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
>+				&req->request, req->direction);
>
> 	trace_dwc3_gadget_giveback(req);
>
>@@ -371,7 +371,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
> 	if (dep->trb_pool)
> 		return 0;
>
>-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
>+	dep->trb_pool = dma_alloc_coherent(dwc->sysdev,
> 			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
> 			&dep->trb_pool_dma, GFP_KERNEL);
> 	if (!dep->trb_pool) {
>@@ -387,7 +387,7 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)  {
> 	struct dwc3		*dwc = dep->dwc;
>
>-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) *
>DWC3_TRB_NUM,
>+	dma_free_coherent(dwc->sysdev, sizeof(struct dwc3_trb) *
>DWC3_TRB_NUM,
> 			dep->trb_pool, dep->trb_pool_dma);
>
> 	dep->trb_pool = NULL;
>@@ -1027,8 +1027,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep
>*dep, u16 cmd_param)
> 		 * here and stop, unmap, free and del each of the linked
> 		 * requests instead of what we do now.
> 		 */
>-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
>-				req->direction);
>+		usb_gadget_unmap_request_by_dev(dwc->sysdev,
>+				&req->request, req->direction);
> 		list_del(&req->list);
> 		return ret;
> 	}
>@@ -1113,8 +1113,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep
>*dep, struct dwc3_request *req)
> 	 * This will also avoid Host cancelling URBs due to too
> 	 * many NAKs.
> 	 */
>-	ret = usb_gadget_map_request(&dwc->gadget, &req->request,
>-			dep->direction);
>+	ret = usb_gadget_map_request_by_dev(dwc->sysdev,
>+		&req->request, dep->direction);
> 	if (ret)
> 		return ret;
>
>@@ -2953,7 +2953,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>
> 	dwc->irq_gadget = irq;
>
>-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dwc->ctrl_req = dma_alloc_coherent(dwc->sysdev,
>+sizeof(*dwc->ctrl_req),
> 			&dwc->ctrl_req_addr, GFP_KERNEL);
> 	if (!dwc->ctrl_req) {
> 		dev_err(dwc->dev, "failed to allocate ctrl request\n"); @@ -2961,7
>+2961,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> 		goto err0;
> 	}
>
>-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
>+	dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb)
>*
>+2,
> 			&dwc->ep0_trb_addr, GFP_KERNEL);
> 	if (!dwc->ep0_trb) {
> 		dev_err(dwc->dev, "failed to allocate ep0 trb\n"); @@ -2975,7
>+2975,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> 		goto err2;
> 	}
>
>-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
>+	dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev,
> 			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
> 			GFP_KERNEL);
> 	if (!dwc->ep0_bounce) {
>@@ -3047,18 +3047,18 @@ err5:
>
> err4:
> 	dwc3_gadget_free_endpoints(dwc);
>-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
>+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
> 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
>
> err3:
> 	kfree(dwc->setup_buf);
>
> err2:
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
> 			dwc->ep0_trb, dwc->ep0_trb_addr);
>
> err1:
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
> 			dwc->ctrl_req, dwc->ctrl_req_addr);
>
> err0:
>@@ -3073,16 +3073,16 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
>
> 	dwc3_gadget_free_endpoints(dwc);
>
>-	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
>+	dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
> 			dwc->ep0_bounce, dwc->ep0_bounce_addr);
>
> 	kfree(dwc->setup_buf);
> 	kfree(dwc->zlp_buf);
>
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb),
> 			dwc->ep0_trb, dwc->ep0_trb_addr);
>
>-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
>+	dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
> 			dwc->ctrl_req, dwc->ctrl_req_addr);
> }
>
>diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index
>f6533c68fed1..3c078e85fa98 100644
>--- a/drivers/usb/dwc3/host.c
>+++ b/drivers/usb/dwc3/host.c
>@@ -72,12 +72,7 @@ int dwc3_host_init(struct dwc3 *dwc)
> 		return -ENOMEM;
> 	}
>
>-	dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask);
>-
> 	xhci->dev.parent	= dwc->dev;
>-	xhci->dev.dma_mask	= dwc->dev->dma_mask;
>-	xhci->dev.dma_parms	= dwc->dev->dma_parms;
>-
> 	dwc->xhci = xhci;
>
> 	ret = platform_device_add_resources(xhci, dwc->xhci_resources, @@ -
>112,9 +107,9 @@ int dwc3_host_init(struct dwc3 *dwc)
> 	return 0;
> err2:
> 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
>-			  dev_name(&xhci->dev));
>+			  dev_name(dwc->dev));
> 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
>-			  dev_name(&xhci->dev));
>+			  dev_name(dwc->dev));
> err1:
> 	platform_device_put(xhci);
> 	return ret;
>@@ -123,8 +118,8 @@ err1:
> void dwc3_host_exit(struct dwc3 *dwc)
> {
> 	phy_remove_lookup(dwc->usb2_generic_phy, "usb2-phy",
>-			  dev_name(&dwc->xhci->dev));
>+			  dev_name(dwc->dev));
> 	phy_remove_lookup(dwc->usb3_generic_phy, "usb3-phy",
>-			  dev_name(&dwc->xhci->dev));
>+			  dev_name(dwc->dev));
> 	platform_device_unregister(dwc->xhci);
> }
>diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index
>9f5ffb629973..b2419950221f 100644
>--- a/drivers/usb/host/ehci-fsl.c
>+++ b/drivers/usb/host/ehci-fsl.c
>@@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
> 	}
> 	irq = res->start;
>
>-	hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
>-				dev_name(&pdev->dev));
>+	hcd = __usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev.parent,
>+				&pdev->dev, dev_name(&pdev->dev), NULL);
> 	if (!hcd) {
> 		retval = -ENOMEM;
> 		goto err1;
>diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index
>ed56bf9ed885..c1d69e14432d 100644
>--- a/drivers/usb/host/xhci-plat.c
>+++ b/drivers/usb/host/xhci-plat.c
>@@ -14,6 +14,7 @@
> #include <linux/clk.h>
> #include <linux/dma-mapping.h>
> #include <linux/module.h>
>+#include <linux/pci.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/usb/phy.h>
>@@ -139,6 +140,7 @@ static int xhci_plat_probe(struct platform_device *pdev)  {
> 	const struct of_device_id *match;
> 	const struct hc_driver	*driver;
>+	struct device		*sysdev;
> 	struct xhci_hcd		*xhci;
> 	struct resource         *res;
> 	struct usb_hcd		*hcd;
>@@ -155,22 +157,38 @@ static int xhci_plat_probe(struct platform_device *pdev)
> 	if (irq < 0)
> 		return -ENODEV;
>
>+	/*
>+	 * sysdev must point to a device that is known to the system firmware
>+	 * or PCI hardware. We handle these three cases here:
>+	 * 1. xhci_plat comes from firmware
>+	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
>+	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
>+	 */
>+	sysdev = &pdev->dev;
>+	if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node)
>+		sysdev = sysdev->parent;
>+#ifdef CONFIG_PCI
>+	else if (sysdev->parent && sysdev->parent->parent &&
>+		 sysdev->parent->parent->bus == &pci_bus_type)
>+		sysdev = sysdev->parent->parent;
>+#endif
>+
> 	/* Try to set 64-bit DMA first */
>-	if (WARN_ON(!pdev->dev.dma_mask))
>+	if (WARN_ON(!sysdev->dma_mask))
> 		/* Platform did not initialize dma_mask */
>-		ret = dma_coerce_mask_and_coherent(&pdev->dev,
>+		ret = dma_coerce_mask_and_coherent(sysdev,
> 						   DMA_BIT_MASK(64));
> 	else
>-		ret = dma_set_mask_and_coherent(&pdev->dev,
>DMA_BIT_MASK(64));
>+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
>
> 	/* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
> 	if (ret) {
>-		ret = dma_set_mask_and_coherent(&pdev->dev,
>DMA_BIT_MASK(32));
>+		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
> 		if (ret)
> 			return ret;
> 	}
>
>-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>+	hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
>+dev_name(&pdev->dev), NULL);
> 	if (!hcd)
> 		return -ENOMEM;
>
>@@ -220,13 +238,13 @@ static int xhci_plat_probe(struct platform_device *pdev)
> 		goto disable_clk;
> 	}
>
>-	if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
>+	if (device_property_read_bool(sysdev, "usb3-lpm-capable"))
> 		xhci->quirks |= XHCI_LPM_SUPPORT;
>
> 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
> 		xhci->shared_hcd->can_do_streams = 1;
>
>-	hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy",
>0);
>+	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
> 	if (IS_ERR(hcd->usb_phy)) {
> 		ret = PTR_ERR(hcd->usb_phy);
> 		if (ret == -EPROBE_DEFER)
>diff --git a/include/linux/usb.h b/include/linux/usb.h index
>eba1f10e8cfd..f3f5d8a396e4 100644
>--- a/include/linux/usb.h
>+++ b/include/linux/usb.h
>@@ -354,6 +354,7 @@ struct usb_devmap {
>  */
> struct usb_bus {
> 	struct device *controller;	/* host/master side hardware */
>+	struct device *sysdev;		/* as seen from firmware or bus */
> 	int busnum;			/* Bus number (in order of reg) */
> 	const char *bus_name;		/* stable id (PCI slot_name etc) */
> 	u8 uses_dma;			/* Does the host controller use DMA? */
>diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index
>66fc13705ab7..3860560a61bb 100644
>--- a/include/linux/usb/hcd.h
>+++ b/include/linux/usb/hcd.h
>@@ -437,6 +437,9 @@ extern int usb_hcd_alloc_bandwidth(struct usb_device
>*udev,
> 		struct usb_host_interface *new_alt);
> extern int usb_hcd_get_frame_number(struct usb_device *udev);
>
>+struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
>+		struct device *sysdev, struct device *dev, const char *bus_name,
>+		struct usb_hcd *primary_hcd);
> extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
> 		struct device *dev, const char *bus_name);  extern struct usb_hcd
>*usb_create_shared_hcd(const struct hc_driver *driver,
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a
>message to majordomo at vger.kernel.org More majordomo info at
>http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-21 11:06                                                         ` Sriram Dash
@ 2016-09-21 11:31                                                           ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-21 11:31 UTC (permalink / raw)
  To: Sriram Dash
  Cc: Felipe Balbi, Peter Chen, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Suresh Gupta

On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
> 
> Hello Arnd,
> 
> We tried this patch on NXP platforms (ls2085 and ls1043) which use dwc3 
> controller without any glue layer. On first go, this did not work. But after
> minimal reworks mention snippet below, we are able to verify that the USB
> was working OK.
> 
>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
> 
> -       struct device *dev = xhci_to_hcd(xhci)->self.controller;
> +       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
> 
> We believe the patch needs little modification to work or there might be chances
> we may have missed something. Any idea?


I had not tried the patch, it was just sent for clarification what I
meant, so I'm glad you got it working with just minimal changes.

Unfortunately, I can't tell from your lines above what exactly you
changed, can you send that again as a proper patch?

I think I also had some minimal changes that I did myself in order
to fix a build regression I introduced.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-21 11:31                                                           ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-21 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
> 
> Hello Arnd,
> 
> We tried this patch on NXP platforms (ls2085 and ls1043) which use dwc3 
> controller without any glue layer. On first go, this did not work. But after
> minimal reworks mention snippet below, we are able to verify that the USB
> was working OK.
> 
>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
> 
> -       struct device *dev = xhci_to_hcd(xhci)->self.controller;
> +       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
> 
> We believe the patch needs little modification to work or there might be chances
> we may have missed something. Any idea?


I had not tried the patch, it was just sent for clarification what I
meant, so I'm glad you got it working with just minimal changes.

Unfortunately, I can't tell from your lines above what exactly you
changed, can you send that again as a proper patch?

I think I also had some minimal changes that I did myself in order
to fix a build regression I introduced.

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* RE: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-21 11:31                                                           ` Arnd Bergmann
@ 2016-09-21 11:43                                                             ` Sriram Dash
  -1 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-21 11:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Peter Chen, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Suresh Gupta

>From: Arnd Bergmann [mailto:arnd@arndb.de]
>On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>
>> Hello Arnd,
>>
>> We tried this patch on NXP platforms (ls2085 and ls1043) which use
>> dwc3 controller without any glue layer. On first go, this did not
>> work. But after minimal reworks mention snippet below, we are able to
>> verify that the USB was working OK.
>>
>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>
>> -       struct device *dev = xhci_to_hcd(xhci)->self.controller;
>> +       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
>>
>> We believe the patch needs little modification to work or there might
>> be chances we may have missed something. Any idea?
>
>
>I had not tried the patch, it was just sent for clarification what I meant, so I'm glad
>you got it working with just minimal changes.
>
>Unfortunately, I can't tell from your lines above what exactly you changed, can you
>send that again as a proper patch?
>

Sure.

==============================================================
>From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
From: Sriram Dash <sriram.dash@nxp.com>
Date: Wed, 21 Sep 2016 11:39:30 +0530
Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration from
 parent dev

Fixes the patch https://patchwork.kernel.org/patch/9319527/
("usb: dwc3: host: inherit dma configuration from parent dev").

Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
---
 drivers/usb/host/xhci-mem.c | 12 ++++++------
 drivers/usb/host/xhci.c     | 20 ++++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 6afe323..79608df 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -586,7 +586,7 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs,
 		struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
 {
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
 	if (size > MEDIUM_STREAM_ARRAY_SIZE)
@@ -614,7 +614,7 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs, dma_addr_t *dma,
 		gfp_t mem_flags)
 {
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
 	if (size > MEDIUM_STREAM_ARRAY_SIZE)
@@ -1644,7 +1644,7 @@ void xhci_slot_copy(struct xhci_hcd *xhci,
 static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
 {
 	int i;
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
 
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
@@ -1716,7 +1716,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
 {
 	int num_sp;
 	int i;
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 
 	if (!xhci->scratchpad)
 		return;
@@ -1792,7 +1792,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
 
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
-	struct device	*dev = xhci_to_hcd(xhci)->self.controller;
+	struct device	*dev = xhci_to_hcd(xhci)->self.sysdev;
 	int size;
 	int i, j, num_ports;
 
@@ -2334,7 +2334,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
 	dma_addr_t	dma;
-	struct device	*dev = xhci_to_hcd(xhci)->self.controller;
+	struct device	*dev = xhci_to_hcd(xhci)->self.sysdev;
 	unsigned int	val, val2;
 	u64		val_64;
 	struct xhci_segment	*seg;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 01d96c9..9a1ff09 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
 static int xhci_setup_msi(struct xhci_hcd *xhci)
 {
 	int ret;
-	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 
 	ret = pci_enable_msi(pdev);
 	if (ret) {
@@ -257,7 +257,7 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
  */
 static void xhci_free_irq(struct xhci_hcd *xhci)
 {
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 	int ret;
 
 	/* return if using legacy interrupt */
@@ -280,7 +280,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 {
 	int i, ret = 0;
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
 
 	/*
 	 * calculate number of msi-x vectors supported.
@@ -337,7 +337,7 @@ free_entries:
 static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 {
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
 
 	if (xhci->quirks & XHCI_PLAT)
 		return;
@@ -376,7 +376,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 	if (xhci->quirks & XHCI_PLAT)
 		return 0;
 
-	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 	/*
 	 * Some Fresco Logic host controllers advertise MSI, but fail to
 	 * generate interrupts.  Don't even try to enable MSI.
@@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
 	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
-		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
+		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
 
 	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
@@ -762,7 +762,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
 
 	/* Yet another workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-		pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
+		pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
 
 #ifdef CONFIG_PM
@@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	 * if no devices remain.
 	 */
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
-		pm_runtime_put_noidle(hcd->self.controller);
+		pm_runtime_put_noidle(hcd->self.sysdev);
 #endif
 
 	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
@@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	 * suspend if there is a device attached.
 	 */
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
-		pm_runtime_get_noresume(hcd->self.controller);
+		pm_runtime_get_noresume(hcd->self.sysdev);
 #endif
 
 
@@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 {
 	struct xhci_hcd		*xhci;
-	struct device		*dev = hcd->self.controller;
+	struct device		*dev = hcd->self.sysdev;
 	int			retval;
 
 	/* Accept arbitrarily long scatter-gather lists */
-- 
2.1.0

==============================================================

>I think I also had some minimal changes that I did myself in order to fix a build
>regression I introduced.
>
>	Arnd

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-21 11:43                                                             ` Sriram Dash
  0 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-21 11:43 UTC (permalink / raw)
  To: linux-arm-kernel

>From: Arnd Bergmann [mailto:arnd at arndb.de]
>On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>
>> Hello Arnd,
>>
>> We tried this patch on NXP platforms (ls2085 and ls1043) which use
>> dwc3 controller without any glue layer. On first go, this did not
>> work. But after minimal reworks mention snippet below, we are able to
>> verify that the USB was working OK.
>>
>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>
>> -       struct device *dev = xhci_to_hcd(xhci)->self.controller;
>> +       struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
>>
>> We believe the patch needs little modification to work or there might
>> be chances we may have missed something. Any idea?
>
>
>I had not tried the patch, it was just sent for clarification what I meant, so I'm glad
>you got it working with just minimal changes.
>
>Unfortunately, I can't tell from your lines above what exactly you changed, can you
>send that again as a proper patch?
>

Sure.

==============================================================
>From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
From: Sriram Dash <sriram.dash@nxp.com>
Date: Wed, 21 Sep 2016 11:39:30 +0530
Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration from
 parent dev

Fixes the patch https://patchwork.kernel.org/patch/9319527/
("usb: dwc3: host: inherit dma configuration from parent dev").

Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
---
 drivers/usb/host/xhci-mem.c | 12 ++++++------
 drivers/usb/host/xhci.c     | 20 ++++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 6afe323..79608df 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -586,7 +586,7 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs,
 		struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
 {
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
 	if (size > MEDIUM_STREAM_ARRAY_SIZE)
@@ -614,7 +614,7 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
 		unsigned int num_stream_ctxs, dma_addr_t *dma,
 		gfp_t mem_flags)
 {
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
 
 	if (size > MEDIUM_STREAM_ARRAY_SIZE)
@@ -1644,7 +1644,7 @@ void xhci_slot_copy(struct xhci_hcd *xhci,
 static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
 {
 	int i;
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 	int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
 
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
@@ -1716,7 +1716,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
 {
 	int num_sp;
 	int i;
-	struct device *dev = xhci_to_hcd(xhci)->self.controller;
+	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
 
 	if (!xhci->scratchpad)
 		return;
@@ -1792,7 +1792,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
 
 void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
-	struct device	*dev = xhci_to_hcd(xhci)->self.controller;
+	struct device	*dev = xhci_to_hcd(xhci)->self.sysdev;
 	int size;
 	int i, j, num_ports;
 
@@ -2334,7 +2334,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 {
 	dma_addr_t	dma;
-	struct device	*dev = xhci_to_hcd(xhci)->self.controller;
+	struct device	*dev = xhci_to_hcd(xhci)->self.sysdev;
 	unsigned int	val, val2;
 	u64		val_64;
 	struct xhci_segment	*seg;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 01d96c9..9a1ff09 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
 static int xhci_setup_msi(struct xhci_hcd *xhci)
 {
 	int ret;
-	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 
 	ret = pci_enable_msi(pdev);
 	if (ret) {
@@ -257,7 +257,7 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
  */
 static void xhci_free_irq(struct xhci_hcd *xhci)
 {
-	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 	int ret;
 
 	/* return if using legacy interrupt */
@@ -280,7 +280,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 {
 	int i, ret = 0;
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
 
 	/*
 	 * calculate number of msi-x vectors supported.
@@ -337,7 +337,7 @@ free_entries:
 static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 {
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
 
 	if (xhci->quirks & XHCI_PLAT)
 		return;
@@ -376,7 +376,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 	if (xhci->quirks & XHCI_PLAT)
 		return 0;
 
-	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
 	/*
 	 * Some Fresco Logic host controllers advertise MSI, but fail to
 	 * generate interrupts.  Don't even try to enable MSI.
@@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
 	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
-		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
+		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
 
 	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
@@ -762,7 +762,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
 
 	/* Yet another workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
-		pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);
+		pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
 }
 
 #ifdef CONFIG_PM
@@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	 * if no devices remain.
 	 */
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
-		pm_runtime_put_noidle(hcd->self.controller);
+		pm_runtime_put_noidle(hcd->self.sysdev);
 #endif
 
 	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
@@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
 	 * suspend if there is a device attached.
 	 */
 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
-		pm_runtime_get_noresume(hcd->self.controller);
+		pm_runtime_get_noresume(hcd->self.sysdev);
 #endif
 
 
@@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 {
 	struct xhci_hcd		*xhci;
-	struct device		*dev = hcd->self.controller;
+	struct device		*dev = hcd->self.sysdev;
 	int			retval;
 
 	/* Accept arbitrarily long scatter-gather lists */
-- 
2.1.0

==============================================================

>I think I also had some minimal changes that I did myself in order to fix a build
>regression I introduced.
>
>	Arnd

^ permalink raw reply related	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-21 11:43                                                             ` Sriram Dash
@ 2016-09-21 12:48                                                               ` Arnd Bergmann
  -1 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-21 12:48 UTC (permalink / raw)
  To: Sriram Dash
  Cc: Felipe Balbi, Peter Chen, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Suresh Gupta

On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
> >From: Arnd Bergmann [mailto:arnd@arndb.de]
> >On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
> 
> ==============================================================
> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
> From: Sriram Dash <sriram.dash@nxp.com>
> Date: Wed, 21 Sep 2016 11:39:30 +0530
> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration from
>  parent dev
> 
> Fixes the patch https://patchwork.kernel.org/patch/9319527/
> ("usb: dwc3: host: inherit dma configuration from parent dev").
> 
> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
> ---
>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>  2 files changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 6afe323..79608df 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c

All the changes you did to this file seem fine, I completely missed that part.

> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 01d96c9..9a1ff09 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
>  static int xhci_setup_msi(struct xhci_hcd *xhci)
>  {
>  	int ret;
> -	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
> +	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
>  
>  	ret = pci_enable_msi(pdev);
>  	if (ret) {

This one is interesting as I stumbled over some code comment mentioning
that for dwc3-pci, we don't support MSI. I think with this change,
we /can/ actually support MSI, but this could be a separate patch
and we'd have to test it on dwc3-pci hardware. Same for most of
this file.

> @@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
>  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
>  
>  	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
> -		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
> +		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
>  
>  	spin_lock_irq(&xhci->lock);
>  	xhci_halt(xhci);

This seems obviously correct, but I don't yet see why it currently
works. We probably don't call this function on dwc3.

>  #ifdef CONFIG_PM
> @@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
>  	 * if no devices remain.
>  	 */
>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
> -		pm_runtime_put_noidle(hcd->self.controller);
> +		pm_runtime_put_noidle(hcd->self.sysdev);
>  #endif
>  
>  	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);

I suspect this one is wrong, based on what Felipe explained earlier:
the power management should propagate down from the child to the
parent device.

Someone who understands this better than I do should look at it.

> @@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
>  	 * suspend if there is a device attached.
>  	 */
>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
> -		pm_runtime_get_noresume(hcd->self.controller);
> +		pm_runtime_get_noresume(hcd->self.sysdev);
>  #endif
>  
>  

Same here.

> @@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)
>  int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
>  {
>  	struct xhci_hcd		*xhci;
> -	struct device		*dev = hcd->self.controller;
> +	struct device		*dev = hcd->self.sysdev;
>  	int			retval;


This one calls

        get_quirks(dev, xhci);

not sure whether this should be called with self.controller or
self.sysdev, we should audit every one of the callers here to
be sure:

drivers/usb/host/xhci-mtk.c:    return xhci_gen_setup(hcd, xhci_mtk_quirks);
drivers/usb/host/xhci-pci.c:    retval = xhci_gen_setup(hcd, xhci_pci_quirks);
drivers/usb/host/xhci-plat.c:   return xhci_gen_setup(hcd, xhci_plat_quirks);
drivers/usb/host/xhci-rcar.c:    * xhci_gen_setup().
drivers/usb/host/xhci-tegra.c:  return xhci_gen_setup(hcd, tegra_xhci_quirks);

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-21 12:48                                                               ` Arnd Bergmann
  0 siblings, 0 replies; 182+ messages in thread
From: Arnd Bergmann @ 2016-09-21 12:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
> >From: Arnd Bergmann [mailto:arnd at arndb.de]
> >On Wednesday, September 21, 2016 11:06:47 AM CEST Sriram Dash wrote:
> 
> ==============================================================
> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
> From: Sriram Dash <sriram.dash@nxp.com>
> Date: Wed, 21 Sep 2016 11:39:30 +0530
> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration from
>  parent dev
> 
> Fixes the patch https://patchwork.kernel.org/patch/9319527/
> ("usb: dwc3: host: inherit dma configuration from parent dev").
> 
> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
> ---
>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>  2 files changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index 6afe323..79608df 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c

All the changes you did to this file seem fine, I completely missed that part.

> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 01d96c9..9a1ff09 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
>  static int xhci_setup_msi(struct xhci_hcd *xhci)
>  {
>  	int ret;
> -	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
> +	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
>  
>  	ret = pci_enable_msi(pdev);
>  	if (ret) {

This one is interesting as I stumbled over some code comment mentioning
that for dwc3-pci, we don't support MSI. I think with this change,
we /can/ actually support MSI, but this could be a separate patch
and we'd have to test it on dwc3-pci hardware. Same for most of
this file.

> @@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
>  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
>  
>  	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
> -		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
> +		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
>  
>  	spin_lock_irq(&xhci->lock);
>  	xhci_halt(xhci);

This seems obviously correct, but I don't yet see why it currently
works. We probably don't call this function on dwc3.

>  #ifdef CONFIG_PM
> @@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
>  	 * if no devices remain.
>  	 */
>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
> -		pm_runtime_put_noidle(hcd->self.controller);
> +		pm_runtime_put_noidle(hcd->self.sysdev);
>  #endif
>  
>  	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);

I suspect this one is wrong, based on what Felipe explained earlier:
the power management should propagate down from the child to the
parent device.

Someone who understands this better than I do should look at it.

> @@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
>  	 * suspend if there is a device attached.
>  	 */
>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
> -		pm_runtime_get_noresume(hcd->self.controller);
> +		pm_runtime_get_noresume(hcd->self.sysdev);
>  #endif
>  
>  

Same here.

> @@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)
>  int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
>  {
>  	struct xhci_hcd		*xhci;
> -	struct device		*dev = hcd->self.controller;
> +	struct device		*dev = hcd->self.sysdev;
>  	int			retval;


This one calls

        get_quirks(dev, xhci);

not sure whether this should be called with self.controller or
self.sysdev, we should audit every one of the callers here to
be sure:

drivers/usb/host/xhci-mtk.c:    return xhci_gen_setup(hcd, xhci_mtk_quirks);
drivers/usb/host/xhci-pci.c:    retval = xhci_gen_setup(hcd, xhci_pci_quirks);
drivers/usb/host/xhci-plat.c:   return xhci_gen_setup(hcd, xhci_plat_quirks);
drivers/usb/host/xhci-rcar.c:    * xhci_gen_setup().
drivers/usb/host/xhci-tegra.c:  return xhci_gen_setup(hcd, tegra_xhci_quirks);

	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: xhci: Fix the patch inherit dma configuration from
  2016-09-21 11:43                                                             ` Sriram Dash
@ 2016-09-21 17:14                                                               ` kbuild test robot
  -1 siblings, 0 replies; 182+ messages in thread
From: kbuild test robot @ 2016-09-21 17:14 UTC (permalink / raw)
  To: Sriram Dash
  Cc: kbuild-all, Arnd Bergmann, Felipe Balbi, Peter Chen, Leo Li,
	Grygorii Strashko, Russell King - ARM Linux, Catalin Marinas,
	Yoshihiro Shimoda, linux-usb, Sekhar Nori, lkml, Stuart Yoder,
	Scott Wood, David Fisher, Thang Q. Nguyen, Alan Stern,
	Greg Kroah-Hartman, linux-arm-kernel, Suresh Gupta

[-- Attachment #1: Type: text/plain, Size: 7732 bytes --]

Hi Sriram,

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.8-rc7 next-20160921]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Sriram-Dash/usb-xhci-Fix-the-patch-inherit-dma-configuration-from/20160922-004329
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-x012-201638 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/list.h:8:0,
                    from include/linux/pci.h:25,
                    from drivers/usb/host/xhci.c:23:
   drivers/usb/host/xhci.c: In function 'xhci_setup_msi':
>> drivers/usb/host/xhci.c:234:60: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                                               ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
>> drivers/usb/host/xhci.c:234:26: note: in expansion of macro 'to_pci_dev'
     struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                             ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_free_irq':
   drivers/usb/host/xhci.c:260:59: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:260:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_setup_msix':
   drivers/usb/host/xhci.c:283:45: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                                                ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:283:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_cleanup_msix':
   drivers/usb/host/xhci.c:338:45: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                                                ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:338:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_try_enable_msi':
   drivers/usb/host/xhci.c:377:43: error: 'struct usb_bus' has no member named 'sysdev'
     pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:377:9: note: in expansion of macro 'to_pci_dev'
     pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_shutdown':
   drivers/usb/host/xhci.c:746:46: error: 'struct usb_bus' has no member named 'sysdev'
      usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
                                                 ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:746:26: note: in expansion of macro 'to_pci_dev'
      usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
                             ^~~~~~~~~~
   drivers/usb/host/xhci.c:763:43: error: 'struct usb_bus' has no member named 'sysdev'
      pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:763:23: note: in expansion of macro 'to_pci_dev'
      pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
                          ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_gen_setup':
   drivers/usb/host/xhci.c:4835:33: error: 'struct usb_bus' has no member named 'sysdev'
     struct device  *dev = hcd->self.sysdev;
                                    ^
--
   drivers/usb/host/xhci-mem.c: In function 'xhci_free_stream_ctx':
>> drivers/usb/host/xhci-mem.c:589:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_alloc_stream_ctx':
   drivers/usb/host/xhci-mem.c:617:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'scratchpad_alloc':
   drivers/usb/host/xhci-mem.c:1647:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'scratchpad_free':
   drivers/usb/host/xhci-mem.c:1719:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_mem_cleanup':
   drivers/usb/host/xhci-mem.c:1795:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_mem_init':
   drivers/usb/host/xhci-mem.c:2337:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^

vim +234 drivers/usb/host/xhci.c

   228	/*
   229	 * Set up MSI
   230	 */
   231	static int xhci_setup_msi(struct xhci_hcd *xhci)
   232	{
   233		int ret;
 > 234		struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
   235	
   236		ret = pci_enable_msi(pdev);
   237		if (ret) {

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 21706 bytes --]

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: xhci: Fix the patch inherit dma configuration from
@ 2016-09-21 17:14                                                               ` kbuild test robot
  0 siblings, 0 replies; 182+ messages in thread
From: kbuild test robot @ 2016-09-21 17:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sriram,

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.8-rc7 next-20160921]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Sriram-Dash/usb-xhci-Fix-the-patch-inherit-dma-configuration-from/20160922-004329
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-x012-201638 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/list.h:8:0,
                    from include/linux/pci.h:25,
                    from drivers/usb/host/xhci.c:23:
   drivers/usb/host/xhci.c: In function 'xhci_setup_msi':
>> drivers/usb/host/xhci.c:234:60: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                                               ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
>> drivers/usb/host/xhci.c:234:26: note: in expansion of macro 'to_pci_dev'
     struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                             ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_free_irq':
   drivers/usb/host/xhci.c:260:59: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:260:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_setup_msix':
   drivers/usb/host/xhci.c:283:45: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                                                ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:283:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_cleanup_msix':
   drivers/usb/host/xhci.c:338:45: error: 'struct usb_bus' has no member named 'sysdev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                                                ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:338:25: note: in expansion of macro 'to_pci_dev'
     struct pci_dev *pdev = to_pci_dev(hcd->self.sysdev);
                            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_try_enable_msi':
   drivers/usb/host/xhci.c:377:43: error: 'struct usb_bus' has no member named 'sysdev'
     pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:377:9: note: in expansion of macro 'to_pci_dev'
     pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
            ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_shutdown':
   drivers/usb/host/xhci.c:746:46: error: 'struct usb_bus' has no member named 'sysdev'
      usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
                                                 ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:746:26: note: in expansion of macro 'to_pci_dev'
      usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
                             ^~~~~~~~~~
   drivers/usb/host/xhci.c:763:43: error: 'struct usb_bus' has no member named 'sysdev'
      pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
                                              ^
   include/linux/kernel.h:831:49: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                    ^~~
   drivers/usb/host/xhci.c:763:23: note: in expansion of macro 'to_pci_dev'
      pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot);
                          ^~~~~~~~~~
   drivers/usb/host/xhci.c: In function 'xhci_gen_setup':
   drivers/usb/host/xhci.c:4835:33: error: 'struct usb_bus' has no member named 'sysdev'
     struct device  *dev = hcd->self.sysdev;
                                    ^
--
   drivers/usb/host/xhci-mem.c: In function 'xhci_free_stream_ctx':
>> drivers/usb/host/xhci-mem.c:589:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_alloc_stream_ctx':
   drivers/usb/host/xhci-mem.c:617:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'scratchpad_alloc':
   drivers/usb/host/xhci-mem.c:1647:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'scratchpad_free':
   drivers/usb/host/xhci-mem.c:1719:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_mem_cleanup':
   drivers/usb/host/xhci-mem.c:1795:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^
   drivers/usb/host/xhci-mem.c: In function 'xhci_mem_init':
   drivers/usb/host/xhci-mem.c:2337:46: error: 'struct usb_bus' has no member named 'sysdev'
     struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
                                                 ^

vim +234 drivers/usb/host/xhci.c

   228	/*
   229	 * Set up MSI
   230	 */
   231	static int xhci_setup_msi(struct xhci_hcd *xhci)
   232	{
   233		int ret;
 > 234		struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
   235	
   236		ret = pci_enable_msi(pdev);
   237		if (ret) {

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 21706 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160922/df321917/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 182+ messages in thread

* RE: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-21 12:48                                                               ` Arnd Bergmann
@ 2016-09-22  5:02                                                                 ` Sriram Dash
  -1 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-22  5:02 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Peter Chen, Leo Li, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Suresh Gupta

>From: Arnd Bergmann [mailto:arnd@arndb.de]
>On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
>> >From: Arnd Bergmann [mailto:arnd@arndb.de] On Wednesday, September
>> >21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>
>> ==============================================================
>> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
>> From: Sriram Dash <sriram.dash@nxp.com>
>> Date: Wed, 21 Sep 2016 11:39:30 +0530
>> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration
>> from  parent dev
>>
>> Fixes the patch https://patchwork.kernel.org/patch/9319527/
>> ("usb: dwc3: host: inherit dma configuration from parent dev").
>>
>> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
>> ---
>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>  2 files changed, 16 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>> index 6afe323..79608df 100644
>> --- a/drivers/usb/host/xhci-mem.c
>> +++ b/drivers/usb/host/xhci-mem.c
>
>All the changes you did to this file seem fine, I completely missed that part.
>
>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index
>> 01d96c9..9a1ff09 100644
>> --- a/drivers/usb/host/xhci.c
>> +++ b/drivers/usb/host/xhci.c

Yes. Some sanity is required over this patch.

>> @@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
>> static int xhci_setup_msi(struct xhci_hcd *xhci)  {
>>  	int ret;
>> -	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
>> +	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
>>
>>  	ret = pci_enable_msi(pdev);
>>  	if (ret) {
>
>This one is interesting as I stumbled over some code comment mentioning that for
>dwc3-pci, we don't support MSI. I think with this change, we /can/ actually support
>MSI, but this could be a separate patch and we'd have to test it on dwc3-pci
>hardware. Same for most of this file.
>
>> @@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
>>  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
>>
>>  	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
>> -		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
>> +		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
>>
>>  	spin_lock_irq(&xhci->lock);
>>  	xhci_halt(xhci);
>
>This seems obviously correct, but I don't yet see why it currently works. We
>probably don't call this function on dwc3.
>
>>  #ifdef CONFIG_PM
>> @@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct
>usb_device *udev)
>>  	 * if no devices remain.
>>  	 */
>>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
>> -		pm_runtime_put_noidle(hcd->self.controller);
>> +		pm_runtime_put_noidle(hcd->self.sysdev);
>>  #endif
>>
>>  	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
>
>I suspect this one is wrong, based on what Felipe explained earlier:
>the power management should propagate down from the child to the parent
>device.
>
>Someone who understands this better than I do should look at it.
>
>> @@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct
>usb_device *udev)
>>  	 * suspend if there is a device attached.
>>  	 */
>>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
>> -		pm_runtime_get_noresume(hcd->self.controller);
>> +		pm_runtime_get_noresume(hcd->self.sysdev);
>>  #endif
>>
>>
>
>Same here.
>
>> @@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)  int
>> xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)  {
>>  	struct xhci_hcd		*xhci;
>> -	struct device		*dev = hcd->self.controller;
>> +	struct device		*dev = hcd->self.sysdev;
>>  	int			retval;
>
>
>This one calls
>
>        get_quirks(dev, xhci);
>
>not sure whether this should be called with self.controller or self.sysdev, we should
>audit every one of the callers here to be sure:
>
>drivers/usb/host/xhci-mtk.c:    return xhci_gen_setup(hcd, xhci_mtk_quirks);
>drivers/usb/host/xhci-pci.c:    retval = xhci_gen_setup(hcd, xhci_pci_quirks);
>drivers/usb/host/xhci-plat.c:   return xhci_gen_setup(hcd, xhci_plat_quirks);
>drivers/usb/host/xhci-rcar.c:    * xhci_gen_setup().
>drivers/usb/host/xhci-tegra.c:  return xhci_gen_setup(hcd, tegra_xhci_quirks);
>
>	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-09-22  5:02                                                                 ` Sriram Dash
  0 siblings, 0 replies; 182+ messages in thread
From: Sriram Dash @ 2016-09-22  5:02 UTC (permalink / raw)
  To: linux-arm-kernel

>From: Arnd Bergmann [mailto:arnd at arndb.de]
>On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
>> >From: Arnd Bergmann [mailto:arnd at arndb.de] On Wednesday, September
>> >21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>
>> ==============================================================
>> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
>> From: Sriram Dash <sriram.dash@nxp.com>
>> Date: Wed, 21 Sep 2016 11:39:30 +0530
>> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration
>> from  parent dev
>>
>> Fixes the patch https://patchwork.kernel.org/patch/9319527/
>> ("usb: dwc3: host: inherit dma configuration from parent dev").
>>
>> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
>> ---
>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>  2 files changed, 16 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>> index 6afe323..79608df 100644
>> --- a/drivers/usb/host/xhci-mem.c
>> +++ b/drivers/usb/host/xhci-mem.c
>
>All the changes you did to this file seem fine, I completely missed that part.
>
>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index
>> 01d96c9..9a1ff09 100644
>> --- a/drivers/usb/host/xhci.c
>> +++ b/drivers/usb/host/xhci.c

Yes. Some sanity is required over this patch.

>> @@ -231,7 +231,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
>> static int xhci_setup_msi(struct xhci_hcd *xhci)  {
>>  	int ret;
>> -	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
>> +	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.sysdev);
>>
>>  	ret = pci_enable_msi(pdev);
>>  	if (ret) {
>
>This one is interesting as I stumbled over some code comment mentioning that for
>dwc3-pci, we don't support MSI. I think with this change, we /can/ actually support
>MSI, but this could be a separate patch and we'd have to test it on dwc3-pci
>hardware. Same for most of this file.
>
>> @@ -745,7 +745,7 @@ void xhci_shutdown(struct usb_hcd *hcd)
>>  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
>>
>>  	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
>> -		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));
>> +		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
>>
>>  	spin_lock_irq(&xhci->lock);
>>  	xhci_halt(xhci);
>
>This seems obviously correct, but I don't yet see why it currently works. We
>probably don't call this function on dwc3.
>
>>  #ifdef CONFIG_PM
>> @@ -3605,7 +3605,7 @@ void xhci_free_dev(struct usb_hcd *hcd, struct
>usb_device *udev)
>>  	 * if no devices remain.
>>  	 */
>>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
>> -		pm_runtime_put_noidle(hcd->self.controller);
>> +		pm_runtime_put_noidle(hcd->self.sysdev);
>>  #endif
>>
>>  	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
>
>I suspect this one is wrong, based on what Felipe explained earlier:
>the power management should propagate down from the child to the parent
>device.
>
>Someone who understands this better than I do should look at it.
>
>> @@ -3745,7 +3745,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct
>usb_device *udev)
>>  	 * suspend if there is a device attached.
>>  	 */
>>  	if (xhci->quirks & XHCI_RESET_ON_RESUME)
>> -		pm_runtime_get_noresume(hcd->self.controller);
>> +		pm_runtime_get_noresume(hcd->self.sysdev);
>>  #endif
>>
>>
>
>Same here.
>
>> @@ -4834,7 +4834,7 @@ int xhci_get_frame(struct usb_hcd *hcd)  int
>> xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)  {
>>  	struct xhci_hcd		*xhci;
>> -	struct device		*dev = hcd->self.controller;
>> +	struct device		*dev = hcd->self.sysdev;
>>  	int			retval;
>
>
>This one calls
>
>        get_quirks(dev, xhci);
>
>not sure whether this should be called with self.controller or self.sysdev, we should
>audit every one of the callers here to be sure:
>
>drivers/usb/host/xhci-mtk.c:    return xhci_gen_setup(hcd, xhci_mtk_quirks);
>drivers/usb/host/xhci-pci.c:    retval = xhci_gen_setup(hcd, xhci_pci_quirks);
>drivers/usb/host/xhci-plat.c:   return xhci_gen_setup(hcd, xhci_plat_quirks);
>drivers/usb/host/xhci-rcar.c:    * xhci_gen_setup().
>drivers/usb/host/xhci-tegra.c:  return xhci_gen_setup(hcd, tegra_xhci_quirks);
>
>	Arnd

^ permalink raw reply	[flat|nested] 182+ messages in thread

* Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
  2016-09-22  5:02                                                                 ` Sriram Dash
@ 2016-10-07 22:46                                                                   ` Leo Li
  -1 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-10-07 22:46 UTC (permalink / raw)
  To: Sriram Dash
  Cc: Arnd Bergmann, Felipe Balbi, Peter Chen, Grygorii Strashko,
	Russell King - ARM Linux, Catalin Marinas, Yoshihiro Shimoda,
	linux-usb, Sekhar Nori, lkml, Stuart Yoder, Scott Wood,
	David Fisher, Thang Q. Nguyen, Alan Stern, Greg Kroah-Hartman,
	linux-arm-kernel, Suresh Gupta

On Thu, Sep 22, 2016 at 12:02 AM, Sriram Dash <sriram.dash@nxp.com> wrote:
>>From: Arnd Bergmann [mailto:arnd@arndb.de]
>>On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
>>> >From: Arnd Bergmann [mailto:arnd@arndb.de] On Wednesday, September
>>> >21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>>
>>> ==============================================================
>>> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
>>> From: Sriram Dash <sriram.dash@nxp.com>
>>> Date: Wed, 21 Sep 2016 11:39:30 +0530
>>> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration
>>> from  parent dev
>>>
>>> Fixes the patch https://patchwork.kernel.org/patch/9319527/
>>> ("usb: dwc3: host: inherit dma configuration from parent dev").
>>>
>>> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
>>> ---
>>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>>  2 files changed, 16 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>>> index 6afe323..79608df 100644
>>> --- a/drivers/usb/host/xhci-mem.c
>>> +++ b/drivers/usb/host/xhci-mem.c
>>
>>All the changes you did to this file seem fine, I completely missed that part.
>>
>>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index
>>> 01d96c9..9a1ff09 100644
>>> --- a/drivers/usb/host/xhci.c
>>> +++ b/drivers/usb/host/xhci.c
>
> Yes. Some sanity is required over this patch.

Hi Sriram,

Have you been able to do the sanity check on the patch?  I will be
good to have the formal patch submitted for integration as soon as
possible because the dwc3 USB functionality has been broken for a
while in upstream kernel.

Regards,
Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

* [PATCH] usb: dwc3: host: inherit dma configuration from parent dev
@ 2016-10-07 22:46                                                                   ` Leo Li
  0 siblings, 0 replies; 182+ messages in thread
From: Leo Li @ 2016-10-07 22:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 22, 2016 at 12:02 AM, Sriram Dash <sriram.dash@nxp.com> wrote:
>>From: Arnd Bergmann [mailto:arnd at arndb.de]
>>On Wednesday, September 21, 2016 11:43:59 AM CEST Sriram Dash wrote:
>>> >From: Arnd Bergmann [mailto:arnd at arndb.de] On Wednesday, September
>>> >21, 2016 11:06:47 AM CEST Sriram Dash wrote:
>>>
>>> ==============================================================
>>> From 8b0dea1513e9e73a11dcfa802ddc71cca11d66f8 Mon Sep 17 00:00:00 2001
>>> From: Sriram Dash <sriram.dash@nxp.com>
>>> Date: Wed, 21 Sep 2016 11:39:30 +0530
>>> Subject: [PATCH] usb: xhci: Fix the patch inherit dma configuration
>>> from  parent dev
>>>
>>> Fixes the patch https://patchwork.kernel.org/patch/9319527/
>>> ("usb: dwc3: host: inherit dma configuration from parent dev").
>>>
>>> Signed-off-by: Sriram Dash <sriram.dash@nxp.com>
>>> ---
>>>  drivers/usb/host/xhci-mem.c | 12 ++++++------
>>>  drivers/usb/host/xhci.c     | 20 ++++++++++----------
>>>  2 files changed, 16 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
>>> index 6afe323..79608df 100644
>>> --- a/drivers/usb/host/xhci-mem.c
>>> +++ b/drivers/usb/host/xhci-mem.c
>>
>>All the changes you did to this file seem fine, I completely missed that part.
>>
>>> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index
>>> 01d96c9..9a1ff09 100644
>>> --- a/drivers/usb/host/xhci.c
>>> +++ b/drivers/usb/host/xhci.c
>
> Yes. Some sanity is required over this patch.

Hi Sriram,

Have you been able to do the sanity check on the patch?  I will be
good to have the formal patch submitted for integration as soon as
possible because the dwc3 USB functionality has been broken for a
while in upstream kernel.

Regards,
Leo

^ permalink raw reply	[flat|nested] 182+ messages in thread

end of thread, other threads:[~2016-10-07 22:47 UTC | newest]

Thread overview: 182+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-25 19:21 [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Grygorii Strashko
2016-04-25 19:21 ` Grygorii Strashko
2016-04-26  6:17 ` Felipe Balbi
2016-04-26  6:17   ` Felipe Balbi
2016-04-26  8:14   ` Grygorii Strashko
2016-04-26  8:14     ` Grygorii Strashko
2016-04-27  5:41     ` Felipe Balbi
2016-04-27  5:41       ` Felipe Balbi
2016-04-27 11:55       ` Grygorii Strashko
2016-04-27 11:55         ` Grygorii Strashko
2016-04-27 13:59       ` Catalin Marinas
2016-04-27 13:59         ` Catalin Marinas
2016-04-27 14:11         ` Arnd Bergmann
2016-04-27 14:11           ` Arnd Bergmann
2016-04-27 15:50           ` Catalin Marinas
2016-04-27 15:50             ` Catalin Marinas
2016-04-27 16:04             ` Arnd Bergmann
2016-04-27 16:04               ` Arnd Bergmann
2016-04-27 16:53               ` Felipe Balbi
2016-04-27 16:53                 ` Felipe Balbi
2016-04-27 17:42                 ` Arnd Bergmann
2016-04-27 17:42                   ` Arnd Bergmann
2016-04-27 17:59                   ` Alan Stern
2016-04-27 17:59                     ` Alan Stern
2016-04-27 18:08                     ` Arnd Bergmann
2016-04-27 18:08                       ` Arnd Bergmann
2016-04-27 20:05                       ` Felipe Balbi
2016-04-27 20:05                         ` Felipe Balbi
2016-04-27 21:05                         ` Arnd Bergmann
2016-04-27 21:05                           ` Arnd Bergmann
2016-04-28  6:37                           ` Felipe Balbi
2016-04-28  6:37                             ` Felipe Balbi
2016-04-28 14:16                             ` Russell King - ARM Linux
2016-04-28 14:16                               ` Russell King - ARM Linux
2016-04-28 14:23                               ` Arnd Bergmann
2016-04-28 14:23                                 ` Arnd Bergmann
2016-04-28 14:27                                 ` Felipe Balbi
2016-04-28 14:27                                   ` Felipe Balbi
2016-09-01 22:14                                   ` Leo Li
2016-09-01 22:14                                     ` Leo Li
2016-09-02 10:43                                     ` Arnd Bergmann
2016-09-02 10:43                                       ` Arnd Bergmann
2016-09-02 10:47                                       ` Russell King - ARM Linux
2016-09-02 10:47                                         ` Russell King - ARM Linux
2016-09-02 11:08                                         ` Felipe Balbi
2016-09-02 11:08                                           ` Felipe Balbi
2016-09-02 14:11                                           ` Felipe Balbi
2016-09-02 14:11                                             ` Felipe Balbi
2016-09-02 14:21                                           ` Alan Stern
2016-09-02 14:21                                             ` Alan Stern
2016-09-02 15:51                                             ` Arnd Bergmann
2016-09-02 15:51                                               ` Arnd Bergmann
2016-09-07  7:17                                               ` Roger Quadros
2016-09-07  7:17                                                 ` Roger Quadros
2016-09-07  8:29                                                 ` Arnd Bergmann
2016-09-07  8:29                                                   ` Arnd Bergmann
2016-09-07 13:04                                                   ` Roger Quadros
2016-09-07 13:04                                                     ` Roger Quadros
2016-09-07 14:38                                                     ` Arnd Bergmann
2016-09-07 14:38                                                       ` Arnd Bergmann
2016-09-02 16:23                                           ` Grygorii Strashko
2016-09-02 16:23                                             ` Grygorii Strashko
2016-09-02 10:53                                       ` Felipe Balbi
2016-09-02 10:53                                         ` Felipe Balbi
2016-09-02 11:55                                         ` Robin Murphy
2016-09-02 11:55                                           ` Robin Murphy
2016-09-02 12:56                                           ` Felipe Balbi
2016-09-02 12:56                                             ` Felipe Balbi
2016-09-02 13:10                                           ` Arnd Bergmann
2016-09-02 13:10                                             ` Arnd Bergmann
2016-09-02 22:16                                       ` Leo Li
2016-09-02 22:16                                         ` Leo Li
2016-09-05 15:39                                         ` Arnd Bergmann
2016-09-05 15:39                                           ` Arnd Bergmann
2016-09-06  6:35                                           ` Peter Chen
2016-09-06  6:35                                             ` Peter Chen
2016-09-06  6:40                                             ` Felipe Balbi
2016-09-06  6:40                                               ` Felipe Balbi
2016-09-06 10:46                                               ` Arnd Bergmann
2016-09-06 10:46                                                 ` Arnd Bergmann
2016-09-06 10:50                                                 ` Felipe Balbi
2016-09-06 10:50                                                   ` Felipe Balbi
2016-09-06 13:27                                                   ` Arnd Bergmann
2016-09-06 13:27                                                     ` Arnd Bergmann
2016-09-07  6:51                                                     ` Felipe Balbi
2016-09-07  6:51                                                       ` Felipe Balbi
2016-09-07  7:44                                                     ` Peter Chen
2016-09-07  7:44                                                       ` Peter Chen
2016-09-07  8:52                                                       ` Arnd Bergmann
2016-09-07  8:52                                                         ` Arnd Bergmann
2016-09-07  9:29                                                         ` Peter Chen
2016-09-07  9:29                                                           ` Peter Chen
2016-09-07  9:35                                                           ` Russell King - ARM Linux
2016-09-07  9:35                                                             ` Russell King - ARM Linux
2016-09-07 10:18                                                             ` Felipe Balbi
2016-09-07 10:18                                                               ` Felipe Balbi
2016-09-06 10:38                                             ` Arnd Bergmann
2016-09-06 10:38                                               ` Arnd Bergmann
2016-09-07  6:33                                               ` Peter Chen
2016-09-07  6:33                                                 ` Peter Chen
2016-09-07  8:48                                                 ` Arnd Bergmann
2016-09-07  8:48                                                   ` Arnd Bergmann
2016-09-07  9:55                                                   ` Peter Chen
2016-09-07  9:55                                                     ` Peter Chen
2016-09-07 10:33                                                     ` Robin Murphy
2016-09-07 10:33                                                       ` Robin Murphy
2016-09-07 10:47                                                       ` Felipe Balbi
2016-09-07 10:47                                                         ` Felipe Balbi
2016-09-14 16:31                                                         ` Lorenzo Pieralisi
2016-09-14 16:31                                                           ` Lorenzo Pieralisi
2016-09-14 21:50                                                           ` Arnd Bergmann
2016-09-14 21:50                                                             ` Arnd Bergmann
2016-09-07 10:24                                                   ` Felipe Balbi
2016-09-07 10:24                                                     ` Felipe Balbi
2016-09-07 15:24                                                     ` Arnd Bergmann
2016-09-07 15:24                                                       ` Arnd Bergmann
2016-09-07 16:08                                                       ` Alan Stern
2016-09-07 16:08                                                         ` Alan Stern
2016-09-07 19:45                                                         ` Arnd Bergmann
2016-09-07 19:45                                                           ` Arnd Bergmann
2016-09-08  1:15                                                       ` Peter Chen
2016-09-08  1:15                                                         ` Peter Chen
2016-09-08  8:02                                                         ` Arnd Bergmann
2016-09-08  8:02                                                           ` Arnd Bergmann
2016-09-08  8:03                                                       ` Felipe Balbi
2016-09-08  8:03                                                         ` Felipe Balbi
2016-09-08  8:26                                                         ` Arnd Bergmann
2016-09-08  8:26                                                           ` Arnd Bergmann
2016-09-08  8:29                                                           ` Felipe Balbi
2016-09-08  8:29                                                             ` Felipe Balbi
2016-09-08  8:45                                                             ` Arnd Bergmann
2016-09-08  8:45                                                               ` Arnd Bergmann
2016-09-08  9:43                                                               ` Felipe Balbi
2016-09-08  9:43                                                                 ` Felipe Balbi
2016-09-08 10:17                                                                 ` Arnd Bergmann
2016-09-08 10:17                                                                   ` Arnd Bergmann
2016-09-08 11:00                                                                   ` Felipe Balbi
2016-09-08 11:00                                                                     ` Felipe Balbi
2016-09-08 11:11                                                                     ` Arnd Bergmann
2016-09-08 11:11                                                                       ` Arnd Bergmann
2016-09-08 11:20                                                                       ` Felipe Balbi
2016-09-08 11:20                                                                         ` Felipe Balbi
2016-09-08 11:39                                                                         ` Arnd Bergmann
2016-09-08 11:39                                                                           ` Arnd Bergmann
2016-09-08 11:52                                                                           ` Felipe Balbi
2016-09-08 11:52                                                                             ` Felipe Balbi
2016-09-08 12:46                                                                             ` Arnd Bergmann
2016-09-08 12:46                                                                               ` Arnd Bergmann
2016-09-08 12:02                                                                     ` Grygorii Strashko
2016-09-08 12:02                                                                       ` Grygorii Strashko
2016-09-08 12:14                                                                       ` Arnd Bergmann
2016-09-08 12:14                                                                         ` Arnd Bergmann
2016-09-08 12:28                                                                   ` Peter Chen
2016-09-08 12:28                                                                     ` Peter Chen
2016-09-08 12:52                                                                     ` Arnd Bergmann
2016-09-08 12:52                                                                       ` Arnd Bergmann
2016-09-09  1:37                                                                       ` Peter Chen
2016-09-09  1:37                                                                         ` Peter Chen
2016-09-08 12:59                                                                     ` Grygorii Strashko
2016-09-08 12:59                                                                       ` Grygorii Strashko
2016-09-09  1:52                                                                       ` Peter Chen
2016-09-09  1:52                                                                         ` Peter Chen
2016-09-21 11:06                                                       ` Sriram Dash
2016-09-21 11:06                                                         ` Sriram Dash
2016-09-21 11:31                                                         ` Arnd Bergmann
2016-09-21 11:31                                                           ` Arnd Bergmann
2016-09-21 11:43                                                           ` Sriram Dash
2016-09-21 11:43                                                             ` Sriram Dash
2016-09-21 12:48                                                             ` Arnd Bergmann
2016-09-21 12:48                                                               ` Arnd Bergmann
2016-09-22  5:02                                                               ` Sriram Dash
2016-09-22  5:02                                                                 ` Sriram Dash
2016-10-07 22:46                                                                 ` Leo Li
2016-10-07 22:46                                                                   ` Leo Li
2016-09-21 17:14                                                             ` [PATCH] usb: xhci: Fix the patch inherit dma configuration from kbuild test robot
2016-09-21 17:14                                                               ` kbuild test robot
2016-04-27 20:57                   ` [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi
2016-04-27 20:57                     ` Felipe Balbi
2016-04-27 14:14         ` Grygorii Strashko
2016-04-27 14:14           ` Grygorii Strashko
2016-05-05 17:07 ` Brian Norris
2016-05-05 17:07   ` Brian Norris

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.