diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 12:20:28 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 12:20:28 -0500 |
commit | f9b0f5170918695891f42645737682ccb452ee13 (patch) | |
tree | 75eaab0ff54f8aadaa6375df140cc9d685f78d95 /drivers/usb/renesas_usbhs/mod_gadget.c | |
parent | 8062d94a545457a83d5291bd62c3bfd14200bba0 (diff) | |
parent | 6440093f5eae9842feb06e40d41c3bd569b6b461 (diff) |
Merge tag 'gadget-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB: Gadget: changes for 3.4
This merge is rather big. Here's what it contains:
For am5536udc we have just simple coding style fixes. Nothing that has any
potential to cause any issues going forward.
With mv_udc, there's only one single change removing an unneeded NULL check.
at91_udc also only saw a single change this merge window, and that's only
removing a duplicated header.
The Renesas controller has a few more involved changes. Support for SUDMAC was
added, there's now a special handling of IRQ resources for when the IRQ line is
shared between Renesas controller and SUDMAC, we also had a bug fix where
Renesas controller would sleep in atomic context while doing DMA transfers from
a tasklet. There were also a set of minor cleanups.
The FSL UDC also had a scheduling in atomic context bug fix, but that's all.
Thanks to Sebastian, the dummy_hcd now works better than ever with support for
scatterlists and streams. Sebastian also added SuperSpeed descriptors to the
serial gadgets.
The highlight on this merge is the addition of a generic API for mapping and
unmapping usb_requests. This will avoid code duplication on all UDC controllers
and also kills all the defines for DMA_ADDR_INVALID which UDC controllers
sprinkled around. A few of the UDC controllers were already converted to use
this new API.
Conflicts:
drivers/usb/dwc3/gadget.c
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 79 |
1 files changed, 23 insertions, 56 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 7542aa94a462..00bd2a5e0362 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -165,69 +165,32 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep, | |||
165 | /* | 165 | /* |
166 | * dma map/unmap | 166 | * dma map/unmap |
167 | */ | 167 | */ |
168 | static int usbhsg_dma_map(struct device *dev, | 168 | static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) |
169 | struct usbhs_pkt *pkt, | ||
170 | enum dma_data_direction dir) | ||
171 | { | ||
172 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); | ||
173 | struct usb_request *req = &ureq->req; | ||
174 | |||
175 | if (pkt->dma != DMA_ADDR_INVALID) { | ||
176 | dev_err(dev, "dma is already mapped\n"); | ||
177 | return -EIO; | ||
178 | } | ||
179 | |||
180 | if (req->dma == DMA_ADDR_INVALID) { | ||
181 | pkt->dma = dma_map_single(dev, pkt->buf, pkt->length, dir); | ||
182 | } else { | ||
183 | dma_sync_single_for_device(dev, req->dma, req->length, dir); | ||
184 | pkt->dma = req->dma; | ||
185 | } | ||
186 | |||
187 | if (dma_mapping_error(dev, pkt->dma)) { | ||
188 | dev_err(dev, "dma mapping error %llx\n", (u64)pkt->dma); | ||
189 | return -EIO; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int usbhsg_dma_unmap(struct device *dev, | ||
196 | struct usbhs_pkt *pkt, | ||
197 | enum dma_data_direction dir) | ||
198 | { | 169 | { |
199 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); | 170 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); |
200 | struct usb_request *req = &ureq->req; | 171 | struct usb_request *req = &ureq->req; |
201 | |||
202 | if (pkt->dma == DMA_ADDR_INVALID) { | ||
203 | dev_err(dev, "dma is not mapped\n"); | ||
204 | return -EIO; | ||
205 | } | ||
206 | |||
207 | if (req->dma == DMA_ADDR_INVALID) | ||
208 | dma_unmap_single(dev, pkt->dma, pkt->length, dir); | ||
209 | else | ||
210 | dma_sync_single_for_cpu(dev, req->dma, req->length, dir); | ||
211 | |||
212 | pkt->dma = DMA_ADDR_INVALID; | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) | ||
218 | { | ||
219 | struct usbhs_pipe *pipe = pkt->pipe; | 172 | struct usbhs_pipe *pipe = pkt->pipe; |
220 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); | 173 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); |
221 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 174 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
222 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
223 | enum dma_data_direction dir; | 175 | enum dma_data_direction dir; |
176 | int ret = 0; | ||
224 | 177 | ||
225 | dir = usbhs_pipe_is_dir_in(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 178 | dir = usbhs_pipe_is_dir_host(pipe); |
226 | 179 | ||
227 | if (map) | 180 | if (map) { |
228 | return usbhsg_dma_map(dev, pkt, dir); | 181 | /* it can not use scatter/gather */ |
229 | else | 182 | WARN_ON(req->num_sgs); |
230 | return usbhsg_dma_unmap(dev, pkt, dir); | 183 | |
184 | ret = usb_gadget_map_request(&gpriv->gadget, req, dir); | ||
185 | if (ret < 0) | ||
186 | return ret; | ||
187 | |||
188 | pkt->dma = req->dma; | ||
189 | } else { | ||
190 | usb_gadget_unmap_request(&gpriv->gadget, req, dir); | ||
191 | } | ||
192 | |||
193 | return ret; | ||
231 | } | 194 | } |
232 | 195 | ||
233 | /* | 196 | /* |
@@ -657,8 +620,6 @@ static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, | |||
657 | 620 | ||
658 | usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); | 621 | usbhs_pkt_init(usbhsg_ureq_to_pkt(ureq)); |
659 | 622 | ||
660 | ureq->req.dma = DMA_ADDR_INVALID; | ||
661 | |||
662 | return &ureq->req; | 623 | return &ureq->req; |
663 | } | 624 | } |
664 | 625 | ||
@@ -941,6 +902,11 @@ static int usbhsg_stop(struct usbhs_priv *priv) | |||
941 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | 902 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
942 | } | 903 | } |
943 | 904 | ||
905 | static void usbhs_mod_gadget_release(struct device *pdev) | ||
906 | { | ||
907 | /* do nothing */ | ||
908 | } | ||
909 | |||
944 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | 910 | int usbhs_mod_gadget_probe(struct usbhs_priv *priv) |
945 | { | 911 | { |
946 | struct usbhsg_gpriv *gpriv; | 912 | struct usbhsg_gpriv *gpriv; |
@@ -989,6 +955,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
989 | */ | 955 | */ |
990 | dev_set_name(&gpriv->gadget.dev, "gadget"); | 956 | dev_set_name(&gpriv->gadget.dev, "gadget"); |
991 | gpriv->gadget.dev.parent = dev; | 957 | gpriv->gadget.dev.parent = dev; |
958 | gpriv->gadget.dev.release = usbhs_mod_gadget_release; | ||
992 | gpriv->gadget.name = "renesas_usbhs_udc"; | 959 | gpriv->gadget.name = "renesas_usbhs_udc"; |
993 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 960 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
994 | gpriv->gadget.max_speed = USB_SPEED_HIGH; | 961 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |