summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-09-26 08:34:50 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-09-26 21:36:54 +0200
commit18d588da7422ea9f35d5c71b34467b60dacdaa20 (patch)
treec8ae45d127bf30868110f3bdcbd8dd41b87cc7f0
parent01beb0d5f2538a57ec7757d2cc2849765ab41d4f (diff)
downloadbarebox-18d588da7422ea9f35d5c71b34467b60dacdaa20.tar.gz
barebox-18d588da7422ea9f35d5c71b34467b60dacdaa20.tar.xz
USB: gadget: put poller into core
Instead of letting each driver implement usb_gadget_poll directly implement this function in the core which then calls into the drivers. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/usb/gadget/at91_udc.c23
-rw-r--r--drivers/usb/gadget/fsl_udc.c44
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c27
-rw-r--r--drivers/usb/gadget/udc-core.c34
-rw-r--r--include/usb/gadget.h1
5 files changed, 55 insertions, 74 deletions
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 2b19be94f0..a6745cb725 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -21,7 +21,6 @@
#include <clock.h>
#include <usb/ch9.h>
#include <usb/gadget.h>
-#include <poller.h>
#include <gpio.h>
#include <linux/list.h>
@@ -1257,6 +1256,8 @@ static int at91_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *dr
return 0;
}
+static void at91_udc_gadget_poll(struct usb_gadget *gadget);
+
static const struct usb_gadget_ops at91_udc_ops = {
.get_frame = at91_get_frame,
.wakeup = at91_wakeup,
@@ -1271,6 +1272,7 @@ static const struct usb_gadget_ops at91_udc_ops = {
/* .vbus_power = at91_vbus_power, */
.udc_start = at91_udc_start,
.udc_stop = at91_udc_stop,
+ .udc_poll = at91_udc_gadget_poll,
};
/*-------------------------------------------------------------------------*/
@@ -1350,13 +1352,13 @@ static int at91_udc_vbus_set(struct param_d *p, void *priv)
return -EROFS;
}
-int usb_gadget_poll(void)
+static void at91_udc_gadget_poll(struct usb_gadget *gadget)
{
struct at91_udc *udc = &controller;
u32 value;
if (!udc->udp_baseaddr)
- return -ENODEV;
+ return;
if (gpio_is_valid(udc->board.vbus_pin)) {
value = gpio_get_value(udc->board.vbus_pin);
@@ -1365,27 +1367,16 @@ int usb_gadget_poll(void)
udc->gpio_vbus_val = value;
if (!value)
- return 0;
+ return;
}
value = at91_udp_read(udc, AT91_UDP_ISR) & (~(AT91_UDP_SOFINT));
if (value)
at91_udc_irq(udc);
-
- return value;
}
/*-------------------------------------------------------------------------*/
-static void at91_udc_poller(struct poller_struct *poller)
-{
- usb_gadget_poll();
-}
-
-static struct poller_struct poller = {
- .func = at91_udc_poller
-};
-
static int __init at91udc_probe(struct device_d *dev)
{
struct at91_udc *udc = &controller;
@@ -1480,8 +1471,6 @@ static int __init at91udc_probe(struct device_d *dev)
udc->vbus = 1;
}
- poller_register(&poller);
-
retval = usb_add_gadget_udc_release(dev, &udc->gadget, NULL);
if (retval)
goto fail0a;
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 5a625d19ca..324d3282d7 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -7,7 +7,6 @@
#include <usb/gadget.h>
#include <usb/fsl_usb2.h>
#include <io.h>
-#include <poller.h>
#include <asm/byteorder.h>
/* ### define USB registers here
@@ -1937,18 +1936,17 @@ static void dtd_complete_irq(struct fsl_udc *udc)
/*
* USB device controller interrupt handler
*/
-int usb_gadget_poll(void)
+static void fsl_udc_gadget_poll(struct usb_gadget *gadget)
{
struct fsl_udc *udc = udc_controller;
u32 irq_src;
- int status = 0;
if (!udc)
- return -ENODEV;
+ return;
/* Disable ISR for OTG host mode */
if (udc->stopped)
- return -EIO;
+ return;
irq_src = readl(&dr_regs->usbsts) & readl(&dr_regs->usbintr);
/* Clear notification bits */
@@ -1961,43 +1959,27 @@ int usb_gadget_poll(void)
tripwire_handler(udc, 0,
(u8 *) (&udc->local_setup_buff));
setup_received_irq(udc, &udc->local_setup_buff);
- status = 1;
}
/* completion of dtd */
- if (readl(&dr_regs->endptcomplete)) {
+ if (readl(&dr_regs->endptcomplete))
dtd_complete_irq(udc);
- status = 1;
- }
- }
-
- /* SOF (for ISO transfer) */
- if (irq_src & USB_STS_SOF) {
- status = 1;
}
/* Port Change */
- if (irq_src & USB_STS_PORT_CHANGE) {
+ if (irq_src & USB_STS_PORT_CHANGE)
port_change_irq(udc);
- status = 1;
- }
/* Reset Received */
- if (irq_src & USB_STS_RESET) {
+ if (irq_src & USB_STS_RESET)
reset_irq(udc);
- status = 1;
- }
/* Sleep Enable (Suspend) */
- if (irq_src & USB_STS_SUSPEND) {
+ if (irq_src & USB_STS_SUSPEND)
udc->driver->disconnect(&udc_controller->gadget);
- status = 1;
- }
if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR))
printf("Error IRQ %x\n", irq_src);
-
- return status;
}
/*----------------------------------------------------------------*
@@ -2196,6 +2178,7 @@ static struct usb_gadget_ops fsl_gadget_ops = {
.pullup = fsl_pullup,
.udc_start = fsl_udc_start,
.udc_stop = fsl_udc_stop,
+ .udc_poll = fsl_udc_gadget_poll,
};
/*----------------------------------------------------------------
@@ -2233,15 +2216,6 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index,
return 0;
}
-static void fsl_udc_poller(struct poller_struct *poller)
-{
- usb_gadget_poll();
-}
-
-static struct poller_struct poller = {
- .func = fsl_udc_poller
-};
-
int ci_udc_register(struct device_d *dev, void __iomem *regs)
{
int ret, i;
@@ -2304,8 +2278,6 @@ int ci_udc_register(struct device_d *dev, void __iomem *regs)
struct_ep_setup(udc_controller, i * 2 + 1, name, 1);
}
- poller_register(&poller);
-
ret = usb_add_gadget_udc_release(dev, &udc_controller->gadget,
NULL);
if (ret)
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 6cc4dd7bda..3db3480cad 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -23,7 +23,6 @@
#include <io.h>
#include <gpio.h>
#include <init.h>
-#include <poller.h>
#include <usb/ch9.h>
#include <usb/gadget.h>
@@ -884,6 +883,7 @@ static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
static int pxa_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver);
static int pxa_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *driver);
+static void pxa_udc_gadget_poll(struct usb_gadget *gadget);
static const struct usb_gadget_ops pxa_udc_ops = {
.get_frame = pxa_udc_get_frame,
@@ -892,6 +892,7 @@ static const struct usb_gadget_ops pxa_udc_ops = {
.vbus_session = pxa_udc_vbus_session,
.udc_start = pxa_udc_start,
.udc_stop = pxa_udc_stop,
+ .udc_poll = pxa_udc_gadget_poll,
};
static void clk_enable(void)
@@ -1366,14 +1367,13 @@ static void irq_udc_reset(struct pxa_udc *udc)
ep0_idle(udc);
}
-int usb_gadget_poll(void)
+static void pxa_udc_gadget_poll(struct usb_gadget *gadget)
{
- struct pxa_udc *udc = the_controller;
+ struct pxa_udc *udc = to_gadget_udc(gadget);
u32 udcisr0 = udc_readl(udc, UDCISR0);
u32 udcisr1 = udc_readl(udc, UDCISR1);
u32 udccr = udc_readl(udc, UDCCR);
u32 udcisr1_spec;
- int ret = 0;
udc->vbus_sensed = udc->mach->udc_is_connected();
if (should_enable_udc(udc))
@@ -1384,7 +1384,7 @@ int usb_gadget_poll(void)
}
if (!udc->enabled)
- return -EIO;
+ return;
dev_dbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, "
"UDCCR:0x%08x\n", udcisr0, udcisr1, udccr);
@@ -1398,15 +1398,9 @@ int usb_gadget_poll(void)
irq_udc_reconfig(udc);
if (unlikely(udcisr1_spec & UDCISR1_IRRS))
irq_udc_reset(udc);
- if (udcisr1_spec)
- ret = 1;
- if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK)) {
+ if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK))
irq_handle_data(udc);
- ret = 1;
- }
-
- return ret;
}
static struct pxa_udc memory = {
@@ -1453,14 +1447,6 @@ static struct pxa_udc memory = {
}
};
-static void pxa27x_udc_poller(struct poller_struct *poller)
-{
- usb_gadget_poll();
-}
-static struct poller_struct poller = {
- .func = pxa27x_udc_poller
-};
-
static int __init pxa_udc_probe(struct device_d *dev)
{
struct pxa_udc *udc = &memory;
@@ -1484,7 +1470,6 @@ static int __init pxa_udc_probe(struct device_d *dev)
the_controller = udc;
udc_init_data(udc);
pxa_eps_setup(udc);
- poller_register(&poller);
ret = usb_add_gadget_udc_release(dev, &udc->gadget, NULL);
if (ret)
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 2f62177cac..4f001e102f 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -20,6 +20,7 @@
#include <common.h>
#include <driver.h>
#include <init.h>
+#include <poller.h>
#include <usb/ch9.h>
#include <usb/gadget.h>
@@ -38,6 +39,7 @@ struct usb_udc {
struct usb_gadget *gadget;
struct device_d dev;
struct list_head list;
+ struct poller_struct poller;
};
static LIST_HEAD(udc_list);
@@ -146,6 +148,18 @@ static inline void usb_gadget_udc_stop(struct usb_gadget *gadget,
gadget->ops->udc_stop(gadget, driver);
}
+int usb_gadget_poll(void)
+{
+ struct usb_udc *udc;
+
+ list_for_each_entry(udc, &udc_list, list) {
+ if (udc->gadget->ops->udc_poll)
+ udc->gadget->ops->udc_poll(udc->gadget);
+ }
+
+ return 0;
+}
+
/**
* usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
* @parent: the parent device to this udc. Usually the controller driver's
@@ -223,6 +237,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
udc->gadget->name);
+ if (udc->gadget->ops->udc_poll)
+ poller_unregister(&udc->poller);
+
usb_gadget_disconnect(udc->gadget);
udc->driver->disconnect(udc->gadget);
udc->driver->unbind(udc->gadget);
@@ -267,6 +284,13 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
/* ------------------------------------------------------------------------- */
+static void udc_poll_driver(struct poller_struct *poller)
+{
+ struct usb_udc *udc = container_of(poller, struct usb_udc, poller);
+
+ udc->gadget->ops->udc_poll(udc->gadget);
+}
+
static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
{
int ret;
@@ -278,6 +302,13 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
udc->dev.driver = &driver->driver;
udc->gadget->dev.driver = &driver->driver;
+ if (udc->gadget->ops->udc_poll) {
+ udc->poller.func = udc_poll_driver;
+ ret = poller_register(&udc->poller);
+ if (ret)
+ return ret;
+ }
+
ret = driver->bind(udc->gadget, driver);
if (ret)
goto err1;
@@ -291,6 +322,9 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
return 0;
err1:
+ if (udc->gadget->ops->udc_poll)
+ poller_unregister(&udc->poller);
+
if (ret != -EISNAM)
dev_err(&udc->dev, "failed to start %s: %d\n",
udc->driver->function, ret);
diff --git a/include/usb/gadget.h b/include/usb/gadget.h
index 7106f9d788..f663e98abf 100644
--- a/include/usb/gadget.h
+++ b/include/usb/gadget.h
@@ -483,6 +483,7 @@ struct usb_gadget_ops {
struct usb_gadget_driver *);
int (*udc_stop)(struct usb_gadget *,
struct usb_gadget_driver *);
+ void (*udc_poll)(struct usb_gadget *);
};
/**