aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_gadget.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-01 12:20:28 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-01 12:20:28 -0500
commitf9b0f5170918695891f42645737682ccb452ee13 (patch)
tree75eaab0ff54f8aadaa6375df140cc9d685f78d95 /drivers/usb/renesas_usbhs/mod_gadget.c
parent8062d94a545457a83d5291bd62c3bfd14200bba0 (diff)
parent6440093f5eae9842feb06e40d41c3bd569b6b461 (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.c79
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 */
168static int usbhsg_dma_map(struct device *dev, 168static 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
195static 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
217static 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
905static void usbhs_mod_gadget_release(struct device *pdev)
906{
907 /* do nothing */
908}
909
944int usbhs_mod_gadget_probe(struct usbhs_priv *priv) 910int 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;