aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/r8a66597-udc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/r8a66597-udc.c')
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c120
1 files changed, 46 insertions, 74 deletions
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 68a826a1b86..b698a490cc7 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -459,7 +459,7 @@ static int alloc_pipe_config(struct r8a66597_ep *ep,
unsigned char *counter;
int ret;
- ep->desc = desc;
+ ep->ep.desc = desc;
if (ep->pipenum) /* already allocated pipe */
return 0;
@@ -648,7 +648,7 @@ static int sudmac_alloc_channel(struct r8a66597 *r8a66597,
/* set SUDMAC parameters */
dma = &r8a66597->dma;
dma->used = 1;
- if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+ if (ep->ep.desc->bEndpointAddress & USB_DIR_IN) {
dma->dir = 1;
} else {
dma->dir = 0;
@@ -663,11 +663,7 @@ static int sudmac_alloc_channel(struct r8a66597 *r8a66597,
ep->fifoctr = D0FIFOCTR;
/* dma mapping */
- req->req.dma = dma_map_single(r8a66597_to_dev(ep->r8a66597),
- req->req.buf, req->req.length,
- dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-
- return 0;
+ return usb_gadget_map_request(&r8a66597->gadget, &req->req, dma->dir);
}
static void sudmac_free_channel(struct r8a66597 *r8a66597,
@@ -677,9 +673,7 @@ static void sudmac_free_channel(struct r8a66597 *r8a66597,
if (!r8a66597_is_sudmac(r8a66597))
return;
- dma_unmap_single(r8a66597_to_dev(ep->r8a66597),
- req->req.dma, req->req.length,
- ep->dma->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ usb_gadget_unmap_request(&r8a66597->gadget, &req->req, ep->dma->dir);
r8a66597_bclr(r8a66597, DREQE, ep->fifosel);
r8a66597_change_curpipe(r8a66597, 0, 0, ep->fifosel);
@@ -776,7 +770,7 @@ static void start_packet_read(struct r8a66597_ep *ep,
static void start_packet(struct r8a66597_ep *ep, struct r8a66597_request *req)
{
- if (ep->desc->bEndpointAddress & USB_DIR_IN)
+ if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
start_packet_write(ep, req);
else
start_packet_read(ep, req);
@@ -936,7 +930,7 @@ __acquires(r8a66597->lock)
if (restart) {
req = get_request_from_ep(ep);
- if (ep->desc)
+ if (ep->ep.desc)
start_packet(ep, req);
}
}
@@ -1122,7 +1116,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597, u16 status, u16 enb)
r8a66597_write(r8a66597, ~check, BRDYSTS);
ep = r8a66597->pipenum2ep[pipenum];
req = get_request_from_ep(ep);
- if (ep->desc->bEndpointAddress & USB_DIR_IN)
+ if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
irq_packet_write(ep, req);
else
irq_packet_read(ep, req);
@@ -1176,7 +1170,7 @@ __acquires(r8a66597->lock)
switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE:
- status = 1 << USB_DEVICE_SELF_POWERED;
+ status = r8a66597->device_status;
break;
case USB_RECIP_INTERFACE:
status = 0;
@@ -1475,11 +1469,11 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597)
u16 savepipe;
u16 mask0;
+ spin_lock(&r8a66597->lock);
+
if (r8a66597_is_sudmac(r8a66597))
r8a66597_sudmac_irq(r8a66597);
- spin_lock(&r8a66597->lock);
-
intsts0 = r8a66597_read(r8a66597, INTSTS0);
intenb0 = r8a66597_read(r8a66597, INTENB0);
@@ -1633,7 +1627,7 @@ static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
req->req.actual = 0;
req->req.status = -EINPROGRESS;
- if (ep->desc == NULL) /* control */
+ if (ep->ep.desc == NULL) /* control */
start_ep0(ep, req);
else {
if (request && !ep->busy)
@@ -1698,7 +1692,7 @@ static int r8a66597_set_wedge(struct usb_ep *_ep)
ep = container_of(_ep, struct r8a66597_ep, ep);
- if (!ep || !ep->desc)
+ if (!ep || !ep->ep.desc)
return -EINVAL;
spin_lock_irqsave(&ep->r8a66597->lock, flags);
@@ -1718,6 +1712,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)
if (list_empty(&ep->queue) && !ep->busy) {
pipe_stop(ep->r8a66597, ep->pipenum);
r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
+ r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr);
+ r8a66597_write(ep->r8a66597, 0, ep->pipectr);
}
spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
}
@@ -1742,26 +1738,16 @@ static int r8a66597_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver)
{
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
- int retval;
if (!driver
- || driver->speed != USB_SPEED_HIGH
+ || driver->max_speed < USB_SPEED_HIGH
|| !driver->setup)
return -EINVAL;
if (!r8a66597)
return -ENODEV;
/* hook up the driver */
- driver->driver.bus = NULL;
r8a66597->driver = driver;
- r8a66597->gadget.dev.driver = &driver->driver;
-
- retval = device_add(&r8a66597->gadget.dev);
- if (retval) {
- dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n",
- retval);
- goto error;
- }
init_controller(r8a66597);
r8a66597_bset(r8a66597, VBSE, INTENB0);
@@ -1775,12 +1761,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
}
return 0;
-
-error:
- r8a66597->driver = NULL;
- r8a66597->gadget.dev.driver = NULL;
-
- return retval;
}
static int r8a66597_stop(struct usb_gadget *gadget,
@@ -1794,7 +1774,6 @@ static int r8a66597_stop(struct usb_gadget *gadget,
disable_controller(r8a66597);
spin_unlock_irqrestore(&r8a66597->lock, flags);
- device_del(&r8a66597->gadget.dev);
r8a66597->driver = NULL;
return 0;
}
@@ -1821,16 +1800,29 @@ static int r8a66597_pullup(struct usb_gadget *gadget, int is_on)
return 0;
}
-static struct usb_gadget_ops r8a66597_gadget_ops = {
+static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self)
+{
+ struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
+
+ if (is_self)
+ r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED;
+ else
+ r8a66597->device_status &= ~(1 << USB_DEVICE_SELF_POWERED);
+
+ return 0;
+}
+
+static const struct usb_gadget_ops r8a66597_gadget_ops = {
.get_frame = r8a66597_get_frame,
.udc_start = r8a66597_start,
.udc_stop = r8a66597_stop,
.pullup = r8a66597_pullup,
+ .set_selfpowered = r8a66597_set_selfpowered,
};
static int __exit r8a66597_remove(struct platform_device *pdev)
{
- struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
+ struct r8a66597 *r8a66597 = platform_get_drvdata(pdev);
usb_del_gadget_udc(&r8a66597->gadget);
del_timer_sync(&r8a66597->timer);
@@ -1839,12 +1831,12 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
iounmap(r8a66597->sudmac_reg);
free_irq(platform_get_irq(pdev, 0), r8a66597);
r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
-#ifdef CONFIG_HAVE_CLK
+
if (r8a66597->pdata->on_chip) {
- clk_disable(r8a66597->clk);
+ clk_disable_unprepare(r8a66597->clk);
clk_put(r8a66597->clk);
}
-#endif
+
kfree(r8a66597);
return 0;
}
@@ -1875,9 +1867,7 @@ static int __init r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597,
static int __init r8a66597_probe(struct platform_device *pdev)
{
-#ifdef CONFIG_HAVE_CLK
char clk_name[8];
-#endif
struct resource *res, *ires;
int irq;
void __iomem *reg = NULL;
@@ -1914,22 +1904,16 @@ static int __init r8a66597_probe(struct platform_device *pdev)
r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
if (r8a66597 == NULL) {
ret = -ENOMEM;
- dev_err(&pdev->dev, "kzalloc error\n");
goto clean_up;
}
spin_lock_init(&r8a66597->lock);
- dev_set_drvdata(&pdev->dev, r8a66597);
- r8a66597->pdata = pdev->dev.platform_data;
+ platform_set_drvdata(pdev, r8a66597);
+ r8a66597->pdata = dev_get_platdata(&pdev->dev);
r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
r8a66597->gadget.ops = &r8a66597_gadget_ops;
- device_initialize(&r8a66597->gadget.dev);
- dev_set_name(&r8a66597->gadget.dev, "gadget");
- r8a66597->gadget.is_dualspeed = 1;
- r8a66597->gadget.dev.parent = &pdev->dev;
- r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
- r8a66597->gadget.dev.release = pdev->dev.release;
+ r8a66597->gadget.max_speed = USB_SPEED_HIGH;
r8a66597->gadget.name = udc_name;
init_timer(&r8a66597->timer);
@@ -1937,7 +1921,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
r8a66597->timer.data = (unsigned long)r8a66597;
r8a66597->reg = reg;
-#ifdef CONFIG_HAVE_CLK
if (r8a66597->pdata->on_chip) {
snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
r8a66597->clk = clk_get(&pdev->dev, clk_name);
@@ -1947,9 +1930,9 @@ static int __init r8a66597_probe(struct platform_device *pdev)
ret = PTR_ERR(r8a66597->clk);
goto clean_up;
}
- clk_enable(r8a66597->clk);
+ clk_prepare_enable(r8a66597->clk);
}
-#endif
+
if (r8a66597->pdata->sudmac) {
ret = r8a66597_sudmac_ioremap(r8a66597, pdev);
if (ret < 0)
@@ -1980,9 +1963,9 @@ static int __init r8a66597_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ep->queue);
ep->ep.name = r8a66597_ep_name[i];
ep->ep.ops = &r8a66597_ep_ops;
- ep->ep.maxpacket = 512;
+ usb_ep_set_maxpacket_limit(&ep->ep, 512);
}
- r8a66597->ep[0].ep.maxpacket = 64;
+ usb_ep_set_maxpacket_limit(&r8a66597->ep[0].ep, 64);
r8a66597->ep[0].pipenum = 0;
r8a66597->ep[0].fifoaddr = CFIFO;
r8a66597->ep[0].fifosel = CFIFOSEL;
@@ -1993,8 +1976,10 @@ static int __init r8a66597_probe(struct platform_device *pdev)
r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep,
GFP_KERNEL);
- if (r8a66597->ep0_req == NULL)
+ if (r8a66597->ep0_req == NULL) {
+ ret = -ENOMEM;
goto clean_up3;
+ }
r8a66597->ep0_req->complete = nop_completion;
ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
@@ -2009,12 +1994,10 @@ err_add_udc:
clean_up3:
free_irq(irq, r8a66597);
clean_up2:
-#ifdef CONFIG_HAVE_CLK
if (r8a66597->pdata->on_chip) {
- clk_disable(r8a66597->clk);
+ clk_disable_unprepare(r8a66597->clk);
clk_put(r8a66597->clk);
}
-#endif
clean_up:
if (r8a66597) {
if (r8a66597->sudmac_reg)
@@ -2037,21 +2020,10 @@ static struct platform_driver r8a66597_driver = {
.name = (char *) udc_name,
},
};
-MODULE_ALIAS("platform:r8a66597_udc");
-
-static int __init r8a66597_udc_init(void)
-{
- return platform_driver_probe(&r8a66597_driver, r8a66597_probe);
-}
-module_init(r8a66597_udc_init);
-static void __exit r8a66597_udc_cleanup(void)
-{
- platform_driver_unregister(&r8a66597_driver);
-}
-module_exit(r8a66597_udc_cleanup);
+module_platform_driver_probe(r8a66597_driver, r8a66597_probe);
MODULE_DESCRIPTION("R8A66597 USB gadget driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yoshihiro Shimoda");
-
+MODULE_ALIAS("platform:r8a66597_udc");