summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/udc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc')
-rw-r--r--drivers/usb/gadget/udc/Kconfig14
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.c240
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.h10
-rw-r--r--drivers/usb/gadget/udc/core.c45
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c2
-rw-r--r--drivers/usb/gadget/udc/fotg210-udc.c4
-rw-r--r--drivers/usb/gadget/udc/fsl_qe_udc.c2
-rw-r--r--drivers/usb/gadget/udc/fsl_udc_core.c16
-rw-r--r--drivers/usb/gadget/udc/fusb300_udc.c2
-rw-r--r--drivers/usb/gadget/udc/goku_udc.c2
-rw-r--r--drivers/usb/gadget/udc/gr_udc.c2
-rw-r--r--drivers/usb/gadget/udc/m66592-udc.c2
-rw-r--r--drivers/usb/gadget/udc/mv_u3d_core.c2
-rw-r--r--drivers/usb/gadget/udc/mv_udc_core.c2
-rw-r--r--drivers/usb/gadget/udc/net2272.c4
-rw-r--r--drivers/usb/gadget/udc/net2280.c25
-rw-r--r--drivers/usb/gadget/udc/omap_udc.c2
-rw-r--r--drivers/usb/gadget/udc/pch_udc.c1
-rw-r--r--drivers/usb/gadget/udc/pxa27x_udc.c7
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.c2
-rw-r--r--drivers/usb/gadget/udc/renesas_usb3.c4
-rw-r--r--drivers/usb/gadget/udc/s3c-hsudc.c2
22 files changed, 306 insertions, 86 deletions
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 658b8da60915..4b69f28a9af9 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -60,6 +60,20 @@ config USB_ATMEL_USBA
USBA is the integrated high-speed USB Device controller on
the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
+ The fifo_mode parameter is used to select endpoint allocation mode.
+ fifo_mode = 0 is used to let the driver autoconfigure the endpoints.
+ In this case 2 banks are allocated for isochronous endpoints and
+ only one bank is allocated for the rest of the endpoints.
+
+ fifo_mode = 1 is a generic maximum fifo size (1024 bytes) configuration
+ allowing the usage of ep1 - ep6
+
+ fifo_mode = 2 is a generic performance maximum fifo size (1024 bytes)
+ configuration allowing the usage of ep1 - ep3
+
+ fifo_mode = 3 is a balanced performance configuration allowing the
+ the usage of ep1 - ep8
+
config USB_BCM63XX_UDC
tristate "Broadcom BCM63xx Peripheral Controller"
depends on BCM63XX
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index 12c7687216e6..2035906b8ced 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -20,6 +20,7 @@
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/ctype.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/atmel_usba_udc.h>
@@ -318,6 +319,91 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc)
}
#endif
+static ushort fifo_mode;
+
+/* "modprobe ... fifo_mode=1" etc */
+module_param(fifo_mode, ushort, 0x0);
+MODULE_PARM_DESC(fifo_mode, "Endpoint configuration mode");
+
+/* mode 0 - uses autoconfig */
+
+/* mode 1 - fits in 8KB, generic max fifo configuration */
+static struct usba_fifo_cfg mode_1_cfg[] = {
+{ .hw_ep_num = 0, .fifo_size = 64, .nr_banks = 1, },
+{ .hw_ep_num = 1, .fifo_size = 1024, .nr_banks = 2, },
+{ .hw_ep_num = 2, .fifo_size = 1024, .nr_banks = 1, },
+{ .hw_ep_num = 3, .fifo_size = 1024, .nr_banks = 1, },
+{ .hw_ep_num = 4, .fifo_size = 1024, .nr_banks = 1, },
+{ .hw_ep_num = 5, .fifo_size = 1024, .nr_banks = 1, },
+{ .hw_ep_num = 6, .fifo_size = 1024, .nr_banks = 1, },
+};
+
+/* mode 2 - fits in 8KB, performance max fifo configuration */
+static struct usba_fifo_cfg mode_2_cfg[] = {
+{ .hw_ep_num = 0, .fifo_size = 64, .nr_banks = 1, },
+{ .hw_ep_num = 1, .fifo_size = 1024, .nr_banks = 3, },
+{ .hw_ep_num = 2, .fifo_size = 1024, .nr_banks = 2, },
+{ .hw_ep_num = 3, .fifo_size = 1024, .nr_banks = 2, },
+};
+
+/* mode 3 - fits in 8KB, mixed fifo configuration */
+static struct usba_fifo_cfg mode_3_cfg[] = {
+{ .hw_ep_num = 0, .fifo_size = 64, .nr_banks = 1, },
+{ .hw_ep_num = 1, .fifo_size = 1024, .nr_banks = 2, },
+{ .hw_ep_num = 2, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 3, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 4, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 5, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 6, .fifo_size = 512, .nr_banks = 2, },
+};
+
+/* mode 4 - fits in 8KB, custom fifo configuration */
+static struct usba_fifo_cfg mode_4_cfg[] = {
+{ .hw_ep_num = 0, .fifo_size = 64, .nr_banks = 1, },
+{ .hw_ep_num = 1, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 2, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 3, .fifo_size = 8, .nr_banks = 2, },
+{ .hw_ep_num = 4, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 5, .fifo_size = 512, .nr_banks = 2, },
+{ .hw_ep_num = 6, .fifo_size = 16, .nr_banks = 2, },
+{ .hw_ep_num = 7, .fifo_size = 8, .nr_banks = 2, },
+{ .hw_ep_num = 8, .fifo_size = 8, .nr_banks = 2, },
+};
+/* Add additional configurations here */
+
+int usba_config_fifo_table(struct usba_udc *udc)
+{
+ int n;
+
+ switch (fifo_mode) {
+ default:
+ fifo_mode = 0;
+ case 0:
+ udc->fifo_cfg = NULL;
+ n = 0;
+ break;
+ case 1:
+ udc->fifo_cfg = mode_1_cfg;
+ n = ARRAY_SIZE(mode_1_cfg);
+ break;
+ case 2:
+ udc->fifo_cfg = mode_2_cfg;
+ n = ARRAY_SIZE(mode_2_cfg);
+ break;
+ case 3:
+ udc->fifo_cfg = mode_3_cfg;
+ n = ARRAY_SIZE(mode_3_cfg);
+ break;
+ case 4:
+ udc->fifo_cfg = mode_4_cfg;
+ n = ARRAY_SIZE(mode_4_cfg);
+ break;
+ }
+ DBG(DBG_HW, "Setup fifo_mode %d\n", fifo_mode);
+
+ return n;
+}
+
static inline u32 usba_int_enb_get(struct usba_udc *udc)
{
return udc->int_enb_cache;
@@ -524,7 +610,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
{
struct usba_ep *ep = to_usba_ep(_ep);
struct usba_udc *udc = ep->udc;
- unsigned long flags, ept_cfg, maxpacket;
+ unsigned long flags, maxpacket;
unsigned int nr_trans;
DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc);
@@ -543,24 +629,17 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
ep->is_isoc = 0;
ep->is_in = 0;
- if (maxpacket <= 8)
- ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8);
- else
- /* LSB is bit 1, not 0 */
- ept_cfg = USBA_BF(EPT_SIZE, fls(maxpacket - 1) - 3);
-
- DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n",
- ep->ep.name, ept_cfg, maxpacket);
+ DBG(DBG_ERR, "%s: EPT_CFG = 0x%lx (maxpacket = %lu)\n",
+ ep->ep.name, ep->ept_cfg, maxpacket);
if (usb_endpoint_dir_in(desc)) {
ep->is_in = 1;
- ept_cfg |= USBA_EPT_DIR_IN;
+ ep->ept_cfg |= USBA_EPT_DIR_IN;
}
switch (usb_endpoint_type(desc)) {
case USB_ENDPOINT_XFER_CONTROL:
- ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL);
- ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE);
+ ep->ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL);
break;
case USB_ENDPOINT_XFER_ISOC:
if (!ep->can_isoc) {
@@ -578,24 +657,15 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
return -EINVAL;
ep->is_isoc = 1;
- ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO);
+ ep->ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO);
+ ep->ept_cfg |= USBA_BF(NB_TRANS, nr_trans);
- /*
- * Do triple-buffering on high-bandwidth iso endpoints.
- */
- if (nr_trans > 1 && ep->nr_banks == 3)
- ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_TRIPLE);
- else
- ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE);
- ept_cfg |= USBA_BF(NB_TRANS, nr_trans);
break;
case USB_ENDPOINT_XFER_BULK:
- ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK);
- ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE);
+ ep->ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK);
break;
case USB_ENDPOINT_XFER_INT:
- ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT);
- ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE);
+ ep->ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT);
break;
}
@@ -604,7 +674,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
ep->ep.desc = desc;
ep->ep.maxpacket = maxpacket;
- usba_ep_writel(ep, CFG, ept_cfg);
+ usba_ep_writel(ep, CFG, ep->ept_cfg);
usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE);
if (ep->can_dma) {
@@ -1006,12 +1076,81 @@ static int atmel_usba_start(struct usb_gadget *gadget,
struct usb_gadget_driver *driver);
static int atmel_usba_stop(struct usb_gadget *gadget);
+static struct usb_ep *atmel_usba_match_ep(
+ struct usb_gadget *gadget,
+ struct usb_endpoint_descriptor *desc,
+ struct usb_ss_ep_comp_descriptor *ep_comp
+)
+{
+ struct usb_ep *_ep;
+ struct usba_ep *ep;
+
+ /* Look at endpoints until an unclaimed one looks usable */
+ list_for_each_entry(_ep, &gadget->ep_list, ep_list) {
+ if (usb_gadget_ep_match_desc(gadget, _ep, desc, ep_comp))
+ goto found_ep;
+ }
+ /* Fail */
+ return NULL;
+
+found_ep:
+
+ if (fifo_mode == 0) {
+ /* Optimize hw fifo size based on ep type and other info */
+ ep = to_usba_ep(_ep);
+
+ switch (usb_endpoint_type(desc)) {
+
+ case USB_ENDPOINT_XFER_CONTROL:
+ break;
+
+ case USB_ENDPOINT_XFER_ISOC:
+ ep->fifo_size = 1024;
+ ep->nr_banks = 2;
+ break;
+
+ case USB_ENDPOINT_XFER_BULK:
+ ep->fifo_size = 512;
+ ep->nr_banks = 1;
+ break;
+
+ case USB_ENDPOINT_XFER_INT:
+ if (desc->wMaxPacketSize == 0)
+ ep->fifo_size =
+ roundup_pow_of_two(_ep->maxpacket_limit);
+ else
+ ep->fifo_size =
+ roundup_pow_of_two(le16_to_cpu(desc->wMaxPacketSize));
+ ep->nr_banks = 1;
+ break;
+ }
+
+ /* It might be a little bit late to set this */
+ usb_ep_set_maxpacket_limit(&ep->ep, ep->fifo_size);
+
+ /* Generate ept_cfg basd on FIFO size and number of banks */
+ if (ep->fifo_size <= 8)
+ ep->ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8);
+ else
+ /* LSB is bit 1, not 0 */
+ ep->ept_cfg =
+ USBA_BF(EPT_SIZE, fls(ep->fifo_size - 1) - 3);
+
+ ep->ept_cfg |= USBA_BF(BK_NUMBER, ep->nr_banks);
+
+ ep->udc->configured_ep++;
+ }
+
+return _ep;
+}
+
static const struct usb_gadget_ops usba_udc_ops = {
.get_frame = usba_udc_get_frame,
.wakeup = usba_udc_wakeup,
.set_selfpowered = usba_udc_set_selfpowered,
.udc_start = atmel_usba_start,
.udc_stop = atmel_usba_stop,
+ .match_ep = atmel_usba_match_ep,
};
static struct usb_endpoint_descriptor usba_ep0_desc = {
@@ -1678,7 +1817,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
}
if (status & USBA_END_OF_RESET) {
- struct usba_ep *ep0;
+ struct usba_ep *ep0, *ep;
+ int i, n;
usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
generate_bias_pulse(udc);
@@ -1717,6 +1857,16 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED))
dev_dbg(&udc->pdev->dev,
"ODD: EP0 configuration is invalid!\n");
+
+ /* Preallocate other endpoints */
+ n = fifo_mode ? udc->num_ep : udc->configured_ep;
+ for (i = 1; i < n; i++) {
+ ep = &udc->usba_ep[i];
+ usba_ep_writel(ep, CFG, ep->ept_cfg);
+ if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED))
+ dev_dbg(&udc->pdev->dev,
+ "ODD: EP%d configuration is invalid!\n", i);
+ }
}
spin_unlock(&udc->lock);
@@ -1864,6 +2014,9 @@ static int atmel_usba_stop(struct usb_gadget *gadget)
if (gpio_is_valid(udc->vbus_pin))
disable_irq(gpio_to_irq(udc->vbus_pin));
+ if (fifo_mode == 0)
+ udc->configured_ep = 1;
+
usba_stop(udc);
udc->driver = NULL;
@@ -1931,9 +2084,13 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
&flags);
udc->vbus_pin_inverted = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
- pp = NULL;
- while ((pp = of_get_next_child(np, pp)))
- udc->num_ep++;
+ if (fifo_mode == 0) {
+ pp = NULL;
+ while ((pp = of_get_next_child(np, pp)))
+ udc->num_ep++;
+ udc->configured_ep = 1;
+ } else
+ udc->num_ep = usba_config_fifo_table(udc);
eps = devm_kzalloc(&pdev->dev, sizeof(struct usba_ep) * udc->num_ep,
GFP_KERNEL);
@@ -1946,7 +2103,7 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
pp = NULL;
i = 0;
- while ((pp = of_get_next_child(np, pp))) {
+ while ((pp = of_get_next_child(np, pp)) && i < udc->num_ep) {
ep = &eps[i];
ret = of_property_read_u32(pp, "reg", &val);
@@ -1954,21 +2111,21 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
dev_err(&pdev->dev, "of_probe: reg error(%d)\n", ret);
goto err;
}
- ep->index = val;
+ ep->index = fifo_mode ? udc->fifo_cfg[i].hw_ep_num : val;
ret = of_property_read_u32(pp, "atmel,fifo-size", &val);
if (ret) {
dev_err(&pdev->dev, "of_probe: fifo-size error(%d)\n", ret);
goto err;
}
- ep->fifo_size = val;
+ ep->fifo_size = fifo_mode ? udc->fifo_cfg[i].fifo_size : val;
ret = of_property_read_u32(pp, "atmel,nb-banks", &val);
if (ret) {
dev_err(&pdev->dev, "of_probe: nb-banks error(%d)\n", ret);
goto err;
}
- ep->nr_banks = val;
+ ep->nr_banks = fifo_mode ? udc->fifo_cfg[i].nr_banks : val;
ep->can_dma = of_property_read_bool(pp, "atmel,can-dma");
ep->can_isoc = of_property_read_bool(pp, "atmel,can-isoc");
@@ -2000,6 +2157,21 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
ep->ep.caps.dir_in = true;
ep->ep.caps.dir_out = true;
+ if (fifo_mode != 0) {
+ /*
+ * Generate ept_cfg based on FIFO size and
+ * banks number
+ */
+ if (ep->fifo_size <= 8)
+ ep->ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8);
+ else
+ /* LSB is bit 1, not 0 */
+ ep->ept_cfg =
+ USBA_BF(EPT_SIZE, fls(ep->fifo_size - 1) - 3);
+
+ ep->ept_cfg |= USBA_BF(BK_NUMBER, ep->nr_banks);
+ }
+
if (i)
list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h
index b03b2ebfc53a..9551b704bfd3 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.h
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.h
@@ -275,6 +275,12 @@ struct usba_dma_desc {
u32 ctrl;
};
+struct usba_fifo_cfg {
+ u8 hw_ep_num;
+ u16 fifo_size;
+ u8 nr_banks;
+};
+
struct usba_ep {
int state;
void __iomem *ep_regs;
@@ -293,7 +299,7 @@ struct usba_ep {
unsigned int can_isoc:1;
unsigned int is_isoc:1;
unsigned int is_in:1;
-
+ unsigned long ept_cfg;
#ifdef CONFIG_USB_GADGET_DEBUG_FS
u32 last_dma_status;
struct dentry *debugfs_dir;
@@ -338,6 +344,8 @@ struct usba_udc {
int vbus_pin;
int vbus_pin_inverted;
int num_ep;
+ int configured_ep;
+ struct usba_fifo_cfg *fifo_cfg;
struct clk *pclk;
struct clk *hclk;
struct usba_ep *usba_ep;
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 0402177f93cd..d685d82dcf48 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1080,6 +1080,24 @@ static void usb_udc_nop_release(struct device *dev)
dev_vdbg(dev, "%s\n", __func__);
}
+/* should be called with udc_lock held */
+static int check_pending_gadget_drivers(struct usb_udc *udc)
+{
+ struct usb_gadget_driver *driver;
+ int ret = 0;
+
+ list_for_each_entry(driver, &gadget_driver_pending_list, pending)
+ if (!driver->udc_name || strcmp(driver->udc_name,
+ dev_name(&udc->dev)) == 0) {
+ ret = udc_bind_to_driver(udc, driver);
+ if (ret != -EPROBE_DEFER)
+ list_del(&driver->pending);
+ break;
+ }
+
+ return ret;
+}
+
/**
* 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
@@ -1093,7 +1111,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
{
struct usb_udc *udc;
- struct usb_gadget_driver *driver;
int ret = -ENOMEM;
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -1136,17 +1153,9 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
udc->vbus = true;
/* pick up one of pending gadget drivers */
- list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
- if (!driver->udc_name || strcmp(driver->udc_name,
- dev_name(&udc->dev)) == 0) {
- ret = udc_bind_to_driver(udc, driver);
- if (ret != -EPROBE_DEFER)
- list_del(&driver->pending);
- if (ret)
- goto err5;
- break;
- }
- }
+ ret = check_pending_gadget_drivers(udc);
+ if (ret)
+ goto err5;
mutex_unlock(&udc_lock);
@@ -1356,14 +1365,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
return -EINVAL;
mutex_lock(&udc_lock);
- list_for_each_entry(udc, &udc_list, list)
+ list_for_each_entry(udc, &udc_list, list) {
if (udc->driver == driver) {
usb_gadget_remove_driver(udc);
usb_gadget_set_state(udc->gadget,
- USB_STATE_NOTATTACHED);
+ USB_STATE_NOTATTACHED);
+
+ /* Maybe there is someone waiting for this UDC? */
+ check_pending_gadget_drivers(udc);
+ /*
+ * For now we ignore bind errors as probably it's
+ * not a valid reason to fail other's gadget unbind
+ */
ret = 0;
break;
}
+ }
if (ret) {
list_del(&driver->pending);
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index c60abe3a68f9..8cabc5944d5f 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -1031,6 +1031,8 @@ static int dummy_udc_probe(struct platform_device *pdev)
int rc;
dum = *((void **)dev_get_platdata(&pdev->dev));
+ /* Clear usb_gadget region for new registration to udc-core */
+ memzero_explicit(&dum->gadget, sizeof(struct usb_gadget));
dum->gadget.name = gadget_name;
dum->gadget.ops = &dummy_ops;
dum->gadget.max_speed = USB_SPEED_SUPER;
diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c
index 6ba122cc7490..78d0204e3e20 100644
--- a/drivers/usb/gadget/udc/fotg210-udc.c
+++ b/drivers/usb/gadget/udc/fotg210-udc.c
@@ -527,7 +527,7 @@ static void fotg210_ep_fifo_flush(struct usb_ep *_ep)
{
}
-static struct usb_ep_ops fotg210_ep_ops = {
+static const struct usb_ep_ops fotg210_ep_ops = {
.enable = fotg210_ep_enable,
.disable = fotg210_ep_disable,
@@ -1058,7 +1058,7 @@ static int fotg210_udc_stop(struct usb_gadget *g)
return 0;
}
-static struct usb_gadget_ops fotg210_gadget_ops = {
+static const struct usb_gadget_ops fotg210_gadget_ops = {
.udc_start = fotg210_udc_start,
.udc_stop = fotg210_udc_stop,
};
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c
index 4fff51b8a18e..303328ce59ee 100644
--- a/drivers/usb/gadget/udc/fsl_qe_udc.c
+++ b/drivers/usb/gadget/udc/fsl_qe_udc.c
@@ -1847,7 +1847,7 @@ out:
return status;
}
-static struct usb_ep_ops qe_ep_ops = {
+static const struct usb_ep_ops qe_ep_ops = {
.enable = qe_ep_enable,
.disable = qe_ep_disable,
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
index 71094e479a96..b76fcdb763a0 100644
--- a/drivers/usb/gadget/udc/fsl_udc_core.c
+++ b/drivers/usb/gadget/udc/fsl_udc_core.c
@@ -520,7 +520,7 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
/* Setup qh structure and ep register for ep0. */
static void ep0_setup(struct fsl_udc *udc)
{
- /* the intialization of an ep includes: fields in QH, Regs,
+ /* the initialization of an ep includes: fields in QH, Regs,
* fsl_ep struct */
struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL,
USB_MAX_CTRL_PAYLOAD, 0, 0);
@@ -1118,7 +1118,7 @@ static void fsl_ep_fifo_flush(struct usb_ep *_ep)
} while (fsl_readl(&dr_regs->endptstatus) & bits);
}
-static struct usb_ep_ops fsl_ep_ops = {
+static const struct usb_ep_ops fsl_ep_ops = {
.enable = fsl_ep_enable,
.disable = fsl_ep_disable,
@@ -1248,6 +1248,12 @@ static const struct usb_gadget_ops fsl_gadget_ops = {
.udc_stop = fsl_udc_stop,
};
+/*
+ * Empty complete function used by this driver to fill in the req->complete
+ * field when creating a request since the complete field is mandatory.
+ */
+static void fsl_noop_complete(struct usb_ep *ep, struct usb_request *req) { }
+
/* Set protocol stall on ep0, protocol stall will automatically be cleared
on new transaction */
static void ep0stall(struct fsl_udc *udc)
@@ -1282,7 +1288,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
req->req.length = 0;
req->req.status = -EINPROGRESS;
req->req.actual = 0;
- req->req.complete = NULL;
+ req->req.complete = fsl_noop_complete;
req->dtd_count = 0;
ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
@@ -1365,7 +1371,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
req->req.length = 2;
req->req.status = -EINPROGRESS;
req->req.actual = 0;
- req->req.complete = NULL;
+ req->req.complete = fsl_noop_complete;
req->dtd_count = 0;
ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
@@ -2343,7 +2349,7 @@ static int struct_ep_setup(struct fsl_udc *udc, unsigned char index,
}
/* Driver probe function
- * all intialization operations implemented here except enabling usb_intr reg
+ * all initialization operations implemented here except enabling usb_intr reg
* board setup should have been done in the platform code
*/
static int fsl_udc_probe(struct platform_device *pdev)
diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c
index 42ff308578df..e0c1b0099265 100644
--- a/drivers/usb/gadget/udc/fusb300_udc.c
+++ b/drivers/usb/gadget/udc/fusb300_udc.c
@@ -518,7 +518,7 @@ static void fusb300_fifo_flush(struct usb_ep *_ep)
{
}
-static struct usb_ep_ops fusb300_ep_ops = {
+static const struct usb_ep_ops fusb300_ep_ops = {
.enable = fusb300_enable,
.disable = fusb300_disable,
diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c
index 5107987bd353..8433c22900dc 100644
--- a/drivers/usb/gadget/udc/goku_udc.c
+++ b/drivers/usb/gadget/udc/goku_udc.c
@@ -968,7 +968,7 @@ static void goku_fifo_flush(struct usb_ep *_ep)
command(regs, COMMAND_FIFO_CLEAR, ep->num);
}
-static struct usb_ep_ops goku_ep_ops = {
+static const struct usb_ep_ops goku_ep_ops = {
.enable = goku_ep_enable,
.disable = goku_ep_disable,
diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c
index b16f8af34050..1f9941145746 100644
--- a/drivers/usb/gadget/udc/gr_udc.c
+++ b/drivers/usb/gadget/udc/gr_udc.c
@@ -1841,7 +1841,7 @@ static void gr_fifo_flush(struct usb_ep *_ep)
spin_unlock(&ep->dev->lock);
}
-static struct usb_ep_ops gr_ep_ops = {
+static const struct usb_ep_ops gr_ep_ops = {
.enable = gr_ep_enable,
.disable = gr_ep_disable,
diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c
index de3e03483659..46ce7bc15f2b 100644
--- a/drivers/usb/gadget/udc/m66592-udc.c
+++ b/drivers/usb/gadget/udc/m66592-udc.c
@@ -1436,7 +1436,7 @@ static void m66592_fifo_flush(struct usb_ep *_ep)
spin_unlock_irqrestore(&ep->m66592->lock, flags);
}
-static struct usb_ep_ops m66592_ep_ops = {
+static const struct usb_ep_ops m66592_ep_ops = {
.enable = m66592_enable,
.disable = m66592_disable,
diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c
index 8d726bd767fd..d365449a295a 100644
--- a/drivers/usb/gadget/udc/mv_u3d_core.c
+++ b/drivers/usb/gadget/udc/mv_u3d_core.c
@@ -995,7 +995,7 @@ static int mv_u3d_ep_set_wedge(struct usb_ep *_ep)
return mv_u3d_ep_set_halt_wedge(_ep, 1, 1);
}
-static struct usb_ep_ops mv_u3d_ep_ops = {
+static const struct usb_ep_ops mv_u3d_ep_ops = {
.enable = mv_u3d_ep_enable,
.disable = mv_u3d_ep_disable,
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c
index d82a91bddbd9..27ebb0d5449d 100644
--- a/drivers/usb/gadget/udc/mv_udc_core.c
+++ b/drivers/usb/gadget/udc/mv_udc_core.c
@@ -946,7 +946,7 @@ static int mv_ep_set_wedge(struct usb_ep *_ep)
return mv_ep_set_halt_wedge(_ep, 1, 1);
}
-static struct usb_ep_ops mv_ep_ops = {
+static const struct usb_ep_ops mv_ep_ops = {
.enable = mv_ep_enable,
.disable = mv_ep_disable,
diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c
index 078c91d546e0..7dc0102abdfe 100644
--- a/drivers/usb/gadget/udc/net2272.c
+++ b/drivers/usb/gadget/udc/net2272.c
@@ -181,7 +181,7 @@ static void net2272_dequeue_all(struct net2272_ep *);
static int net2272_kick_dma(struct net2272_ep *, struct net2272_request *);
static int net2272_fifo_status(struct usb_ep *);
-static struct usb_ep_ops net2272_ep_ops;
+static const struct usb_ep_ops net2272_ep_ops;
/*---------------------------------------------------------------------------*/
@@ -1067,7 +1067,7 @@ net2272_fifo_flush(struct usb_ep *_ep)
net2272_ep_write(ep, EP_STAT1, 1 << BUFFER_FLUSH);
}
-static struct usb_ep_ops net2272_ep_ops = {
+static const struct usb_ep_ops net2272_ep_ops = {
.enable = net2272_enable,
.disable = net2272_disable,
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index 85504419ab31..3828c2ec8623 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -1146,15 +1146,15 @@ static int scan_dma_completions(struct net2280_ep *ep)
*/
while (!list_empty(&ep->queue)) {
struct net2280_request *req;
- u32 tmp;
+ u32 req_dma_count;
req = list_entry(ep->queue.next,
struct net2280_request, queue);
if (!req->valid)
break;
rmb();
- tmp = le32_to_cpup(&req->td->dmacount);
- if ((tmp & BIT(VALID_BIT)) != 0)
+ req_dma_count = le32_to_cpup(&req->td->dmacount);
+ if ((req_dma_count & BIT(VALID_BIT)) != 0)
break;
/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
@@ -1163,40 +1163,41 @@ static int scan_dma_completions(struct net2280_ep *ep)
*/
if (unlikely(req->td->dmadesc == 0)) {
/* paranoia */
- tmp = readl(&ep->dma->dmacount);
- if (tmp & DMA_BYTE_COUNT_MASK)
+ u32 const ep_dmacount = readl(&ep->dma->dmacount);
+
+ if (ep_dmacount & DMA_BYTE_COUNT_MASK)
break;
/* single transfer mode */
- dma_done(ep, req, tmp, 0);
+ dma_done(ep, req, req_dma_count, 0);
num_completed++;
break;
} else if (!ep->is_in &&
(req->req.length % ep->ep.maxpacket) &&
!(ep->dev->quirks & PLX_PCIE)) {
- tmp = readl(&ep->regs->ep_stat);
+ u32 const ep_stat = readl(&ep->regs->ep_stat);
/* AVOID TROUBLE HERE by not issuing short reads from
* your gadget driver. That helps avoids errata 0121,
* 0122, and 0124; not all cases trigger the warning.
*/
- if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) {
+ if ((ep_stat & BIT(NAK_OUT_PACKETS)) == 0) {
ep_warn(ep->dev, "%s lost packet sync!\n",
ep->ep.name);
req->req.status = -EOVERFLOW;
} else {
- tmp = readl(&ep->regs->ep_avail);
- if (tmp) {
+ u32 const ep_avail = readl(&ep->regs->ep_avail);
+ if (ep_avail) {
/* fifo gets flushed later */
ep->out_overflow = 1;
ep_dbg(ep->dev,
"%s dma, discard %d len %d\n",
- ep->ep.name, tmp,
+ ep->ep.name, ep_avail,
req->req.length);
req->req.status = -EOVERFLOW;
}
}
}
- dma_done(ep, req, tmp, 0);
+ dma_done(ep, req, req_dma_count, 0);
num_completed++;
}
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
index a8709f9e5648..f05ba6825bfe 100644
--- a/drivers/usb/gadget/udc/omap_udc.c
+++ b/drivers/usb/gadget/udc/omap_udc.c
@@ -1112,7 +1112,7 @@ done:
return status;
}
-static struct usb_ep_ops omap_ep_ops = {
+static const struct usb_ep_ops omap_ep_ops = {
.enable = omap_ep_enable,
.disable = omap_ep_disable,
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c
index a97da645c1b9..8a365aad66fe 100644
--- a/drivers/usb/gadget/udc/pch_udc.c
+++ b/drivers/usb/gadget/udc/pch_udc.c
@@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
td = phys_to_virt(addr);
addr2 = (dma_addr_t)td->next;
pci_pool_free(dev->data_requests, td, addr);
- td->next = 0x00;
addr = addr2;
}
req->chain_len = 1;
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c
index 7fa60f5b7ae4..832c4fdbe985 100644
--- a/drivers/usb/gadget/udc/pxa27x_udc.c
+++ b/drivers/usb/gadget/udc/pxa27x_udc.c
@@ -1473,7 +1473,7 @@ static int pxa_ep_disable(struct usb_ep *_ep)
return 0;
}
-static struct usb_ep_ops pxa_ep_ops = {
+static const struct usb_ep_ops pxa_ep_ops = {
.enable = pxa_ep_enable,
.disable = pxa_ep_disable,
@@ -2534,9 +2534,10 @@ static int pxa_udc_remove(struct platform_device *_dev)
usb_del_gadget_udc(&udc->gadget);
pxa_cleanup_debugfs(udc);
- if (!IS_ERR_OR_NULL(udc->transceiver))
+ if (!IS_ERR_OR_NULL(udc->transceiver)) {
usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy);
- usb_put_phy(udc->transceiver);
+ usb_put_phy(udc->transceiver);
+ }
udc->transceiver = NULL;
the_controller = NULL;
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c
index f2c8862093a2..118ad70f1af0 100644
--- a/drivers/usb/gadget/udc/r8a66597-udc.c
+++ b/drivers/usb/gadget/udc/r8a66597-udc.c
@@ -1706,7 +1706,7 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)
spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
}
-static struct usb_ep_ops r8a66597_ep_ops = {
+static const struct usb_ep_ops r8a66597_ep_ops = {
.enable = r8a66597_enable,
.disable = r8a66597_disable,
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index fb8fc34827ab..2218f91e92a6 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -1791,7 +1791,7 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev,
dev_dbg(dev, "%s: num_usb3_eps = %d\n", __func__, usb3->num_usb3_eps);
/*
- * This driver prepares pipes as the followings:
+ * This driver prepares pipes as follows:
* - odd pipes = IN pipe
* - even pipes = OUT pipe (except pipe 0)
*/
@@ -1841,7 +1841,7 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev,
memset(basead, 0, sizeof(basead));
/*
- * This driver prepares pipes as the followings:
+ * This driver prepares pipes as follows:
* - all pipes = the same size as "ramsize_per_pipe"
* Please refer to the "Method of Specifying RAM Mapping"
*/
diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c
index 82a9e2a3bedc..42587b738a1f 100644
--- a/drivers/usb/gadget/udc/s3c-hsudc.c
+++ b/drivers/usb/gadget/udc/s3c-hsudc.c
@@ -954,7 +954,7 @@ static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
return 0;
}
-static struct usb_ep_ops s3c_hsudc_ep_ops = {
+static const struct usb_ep_ops s3c_hsudc_ep_ops = {
.enable = s3c_hsudc_ep_enable,
.disable = s3c_hsudc_ep_disable,
.alloc_request = s3c_hsudc_alloc_request,