Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1474745 > unrolled thread
| Started by | Leo Li <pku.leo@gmail.com> |
|---|---|
| First post | 2016-09-02 00:20 +0200 |
| Last post | 2016-09-09 04:00 +0200 |
| Articles | 20 on this page of 60 — 9 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Leo Li <pku.leo@gmail.com> - 2016-09-02 00:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-02 12:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Russell King - ARM Linux <linux@armlinux.org.uk> - 2016-09-02 13:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-02 13:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-02 16:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Alan Stern <stern@rowland.harvard.edu> - 2016-09-02 16:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-02 18:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Roger Quadros <rogerq@ti.com> - 2016-09-07 09:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 10:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Roger Quadros <rogerq@ti.com> - 2016-09-07 15:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 16:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Grygorii Strashko <grygorii.strashko@ti.com> - 2016-09-02 18:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-02 13:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Robin Murphy <robin.murphy@arm.com> - 2016-09-02 14:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-02 15:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-02 15:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Leo Li <pku.leo@gmail.com> - 2016-09-03 00:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-05 17:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-06 08:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-06 08:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-06 12:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-06 13:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-06 15:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-07 09:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-07 09:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 11:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-07 11:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Russell King - ARM Linux <linux@armlinux.org.uk> - 2016-09-07 11:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-07 12:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-06 12:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-07 08:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 10:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-07 12:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Robin Murphy <robin.murphy@arm.com> - 2016-09-07 12:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-07 12:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-07 12:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 17:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Alan Stern <stern@rowland.harvard.edu> - 2016-09-07 18:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-07 21:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-08 03:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 10:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 10:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 10:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 10:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 10:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 11:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 12:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 13:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 13:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 13:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 13:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Felipe Balbi <balbi@kernel.org> - 2016-09-08 14:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 14:50 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Grygorii Strashko <grygorii.strashko@ti.com> - 2016-09-08 14:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 14:20 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-08 14:30 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Arnd Bergmann <arnd@arndb.de> - 2016-09-08 15:00 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-09 03:40 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Grygorii Strashko <grygorii.strashko@ti.com> - 2016-09-08 15:10 +0200
Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev Peter Chen <hzpeterchen@gmail.com> - 2016-09-09 04:00 +0200
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-06 12:50 +0200 |
| Message-ID | <sem6Z-SU-11@gated-at.bofh.it> |
| In reply to | #1477104 |
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
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-09-06 13:00 +0200 |
| Message-ID | <semgF-Wy-7@gated-at.bofh.it> |
| In reply to | #1477270 |
[Multipart message — attachments visible in raw view] — view raw
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-06 15:30 +0200 |
| Message-ID | <seoBQ-2y1-43@gated-at.bofh.it> |
| In reply to | #1477276 |
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
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-09-07 09:00 +0200 |
| Message-ID | <seEZX-4FR-9@gated-at.bofh.it> |
| In reply to | #1477381 |
[Multipart message — attachments visible in raw view] — view raw
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-09-07 09:50 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seFMm-5cY-25@gated-at.bofh.it> |
| In reply to | #1477381 |
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-07 11:00 +0200 |
| Message-ID | <seGS5-5U1-21@gated-at.bofh.it> |
| In reply to | #1478029 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-09-07 11:30 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seHl7-6jf-5@gated-at.bofh.it> |
| In reply to | #1478091 |
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
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@armlinux.org.uk> |
|---|---|
| Date | 2016-09-07 11:40 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seHuN-6ml-19@gated-at.bofh.it> |
| In reply to | #1478102 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-09-07 12:20 +0200 |
| Message-ID | <seI7w-6ST-17@gated-at.bofh.it> |
| In reply to | #1478118 |
[Multipart message — attachments visible in raw view] — view raw
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-06 12:40 +0200 |
| Message-ID | <selXj-PI-1@gated-at.bofh.it> |
| In reply to | #1477099 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-09-07 08:40 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seEGB-4zn-7@gated-at.bofh.it> |
| In reply to | #1477260 |
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-07 10:50 +0200 |
| Message-ID | <seGIp-5QI-1@gated-at.bofh.it> |
| In reply to | #1477987 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-09-07 12:00 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seHOa-6t1-9@gated-at.bofh.it> |
| In reply to | #1478081 |
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
[toc] | [prev] | [next] | [standalone]
| From | Robin Murphy <robin.murphy@arm.com> |
|---|---|
| Date | 2016-09-07 12:40 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seIqS-6Zc-29@gated-at.bofh.it> |
| In reply to | #1478137 |
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
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-09-07 12:50 +0200 |
| Message-ID | <seIAy-72R-13@gated-at.bofh.it> |
| In reply to | #1478162 |
[Multipart message — attachments visible in raw view] — view raw
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
[toc] | [prev] | [next] | [standalone]
| From | Felipe Balbi <balbi@kernel.org> |
|---|---|
| Date | 2016-09-07 12:30 +0200 |
| Message-ID | <seIhc-6W3-35@gated-at.bofh.it> |
| In reply to | #1478081 |
[Multipart message — attachments visible in raw view] — view raw
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-07 17:30 +0200 |
| Message-ID | <seMXv-1t1-5@gated-at.bofh.it> |
| In reply to | #1478151 |
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,
[toc] | [prev] | [next] | [standalone]
| From | Alan Stern <stern@rowland.harvard.edu> |
|---|---|
| Date | 2016-09-07 18:10 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seNAe-1Vy-15@gated-at.bofh.it> |
| In reply to | #1478410 |
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
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-09-07 21:50 +0200 |
| Message-ID | <seR17-44c-3@gated-at.bofh.it> |
| In reply to | #1478457 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <hzpeterchen@gmail.com> |
|---|---|
| Date | 2016-09-08 03:20 +0200 |
| Subject | Re: [PATCH] usb: dwc3: host: inherit dma configuration from parent dev |
| Message-ID | <seWau-7zT-9@gated-at.bofh.it> |
| In reply to | #1478410 |
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
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | linux.kernel
csiph-web