Re: [PATCH 1/3] usb: dwc3: host: inherit dma configuration from parent dev
From: Peter Chen
Date: Tue Oct 25 2016 - 23:30:24 EST
On Tue, Oct 25, 2016 at 04:26:26PM +0530, Sriram Dash wrote:
> For xhci-hcd platform device, all the DMA parameters are not configured
> properly, notably dma ops for dwc3 devices.
>
> 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.
> 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.
>
> Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
> Signed-off-by: Sriram Dash <sriram.dash@xxxxxxx>
> Cc: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
> Cc: Grygorii Strashko <grygorii.strashko@xxxxxx>
> Cc: Sinjan Kumar <sinjank@xxxxxxxxxxxxxx>
> Cc: David Fisher <david.fisher1@xxxxxxxxxxxx>
> Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
> Cc: "Thang Q. Nguyen" <tqnguyen@xxxxxxx>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx>
> Cc: Stephen Boyd <sboyd@xxxxxxxxxxxxxx>
> Cc: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>
> Cc: Ming Lei <tom.leiming@xxxxxxxxx>
> Cc: Jon Masters <jcm@xxxxxxxxxx>
> Cc: Dann Frazier <dann.frazier@xxxxxxxxxxxxx>
> Cc: Peter Chen <peter.chen@xxxxxxx>
> Cc: Leo Li <pku.leo@xxxxxxxxx>
> ---
> drivers/usb/chipidea/host.c | 3 ++-
> drivers/usb/chipidea/udc.c | 10 +++++----
> drivers/usb/core/buffer.c | 12 +++++------
> drivers/usb/core/hcd.c | 48 ++++++++++++++++++++++++++------------------
> drivers/usb/core/usb.c | 18 ++++++++---------
> drivers/usb/dwc3/core.c | 22 +++++++++++++-------
> drivers/usb/dwc3/core.h | 1 +
> drivers/usb/dwc3/ep0.c | 8 ++++----
> drivers/usb/dwc3/gadget.c | 37 +++++++++++++++++-----------------
> drivers/usb/dwc3/host.c | 8 ++++----
> drivers/usb/host/ehci-fsl.c | 4 ++--
> drivers/usb/host/xhci-mem.c | 12 +++++------
> drivers/usb/host/xhci-plat.c | 33 +++++++++++++++++++++++-------
> drivers/usb/host/xhci.c | 15 ++++++++++----
> include/linux/usb.h | 1 +
> include/linux/usb/hcd.h | 3 +++
> 16 files changed, 144 insertions(+), 91 deletions(-)
>
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 96ae695..ca27893 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -116,7 +116,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 661f43f..bc55922 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -423,7 +423,8 @@ 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;
>
> @@ -603,7 +604,8 @@ 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;
>
> @@ -1904,13 +1906,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);
The chipidea part is ok for me, but just follow Arnd's suggestion
for patch split, subject, and commit log.
Peter
> if (ci->td_pool == NULL) {
> diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
> index 98e39f9..1e41ef7 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 479e223..f8feb08 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -1073,6 +1073,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;
> @@ -1119,7 +1120,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);
>
> @@ -1465,19 +1466,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);
> @@ -1520,11 +1521,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;
> @@ -1555,7 +1556,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);
> @@ -1570,12 +1571,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
> @@ -1585,11 +1586,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
> @@ -2511,8 +2512,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;
> @@ -2553,8 +2554,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;
> @@ -2569,6 +2571,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);
>
> /**
> @@ -2588,7 +2598,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);
>
> @@ -2715,7 +2725,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);
> @@ -2733,7 +2743,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);
> @@ -2781,7 +2791,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;
> }
>
> @@ -2791,7 +2801,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 5921514..3abe83a 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -450,9 +450,9 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
> * Note: calling dma_set_mask() on a USB device would set the
> * mask for the entire HCD, so don't do that.
> */
> - dev->dev.dma_mask = bus->controller->dma_mask;
> - dev->dev.dma_pfn_offset = bus->controller->dma_pfn_offset;
> - set_dev_node(&dev->dev, dev_to_node(bus->controller));
> + dev->dev.dma_mask = bus->sysdev->dma_mask;
> + dev->dev.dma_pfn_offset = bus->sysdev->dma_pfn_offset;
> + 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);
> @@ -800,7 +800,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) {
> @@ -838,7 +838,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) {
> @@ -872,7 +872,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) {
> @@ -922,7 +922,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;
>
> @@ -958,7 +958,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;
>
> @@ -986,7 +986,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 7287a76..e0f64ef 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>
> @@ -229,7 +230,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);
> }
>
> /**
> @@ -251,7 +252,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);
> @@ -370,11 +371,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;
> }
> @@ -398,7 +399,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:
> @@ -417,7 +418,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);
> }
> @@ -943,6 +944,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) {
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 6b60e42..b166b0a 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -851,6 +851,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/ep0.c b/drivers/usb/dwc3/ep0.c
> index fe79d77..4d13723 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 07cc892..35375f4 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -185,8 +185,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);
>
> @@ -365,7 +365,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) {
> @@ -381,7 +381,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;
> @@ -990,8 +990,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;
> }
> @@ -1064,8 +1064,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
>
> trace_dwc3_ep_queue(req);
>
> - 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;
>
> @@ -2879,7 +2879,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");
> @@ -2887,8 +2887,9 @@ 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_addr, GFP_KERNEL);
> + 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");
> ret = -ENOMEM;
> @@ -2901,7 +2902,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) {
> @@ -2973,18 +2974,18 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>
> 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:
> @@ -2999,16 +3000,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 f6533c6..bb83eee 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -112,9 +112,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 +123,8 @@ int dwc3_host_init(struct dwc3 *dwc)
> 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 9f5ffb6..b241995 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-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-plat.c b/drivers/usb/host/xhci-plat.c
> index ed56bf9..beb95c8 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,39 @@ 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 +239,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/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 1a4ca02..6ce610b 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -231,6 +231,9 @@ static int xhci_free_msi(struct xhci_hcd *xhci)
> static int xhci_setup_msi(struct xhci_hcd *xhci)
> {
> int ret;
> + /*
> + * TODO:Check with MSI Soc for sysdev
> + */
> struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
>
> ret = pci_enable_msi(pdev);
> @@ -257,7 +260,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 */
> @@ -743,7 +746,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);
> @@ -760,7 +763,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
> @@ -4832,7 +4835,11 @@ 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;
> + /*
> + * TODO: Check with DWC3 clients for sysdev according to
> + * quirks
> + */
> + struct device *dev = hcd->self.sysdev;
> int retval;
>
> /* Accept arbitrarily long scatter-gather lists */
> diff --git a/include/linux/usb.h b/include/linux/usb.h
> index eba1f10..f3f5d8a 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 66fc137..3860560 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,
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Best Regards,
Peter Chen