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/Kconfig5
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c533
-rw-r--r--drivers/usb/gadget/udc/at91_udc.h10
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.c162
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.h9
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_core.c1
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_ep.c10
-rw-r--r--drivers/usb/gadget/udc/bdc/bdc_udc.c1
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c9
-rw-r--r--drivers/usb/gadget/udc/fsl_qe_udc.c2
-rw-r--r--drivers/usb/gadget/udc/fsl_udc_core.c5
-rw-r--r--drivers/usb/gadget/udc/lpc32xx_udc.c12
-rw-r--r--drivers/usb/gadget/udc/mv_udc_core.c3
-rw-r--r--drivers/usb/gadget/udc/net2272.c7
-rw-r--r--drivers/usb/gadget/udc/net2272.h1
-rw-r--r--drivers/usb/gadget/udc/net2280.c533
-rw-r--r--drivers/usb/gadget/udc/net2280.h24
-rw-r--r--drivers/usb/gadget/udc/omap_udc.c1
-rw-r--r--drivers/usb/gadget/udc/pch_udc.c1
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.c2
-rw-r--r--drivers/usb/gadget/udc/pxa27x_udc.c2
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.c1
-rw-r--r--drivers/usb/gadget/udc/s3c2410_udc.c21
-rw-r--r--drivers/usb/gadget/udc/udc-core.c2
-rw-r--r--drivers/usb/gadget/udc/udc-xilinx.c4
25 files changed, 564 insertions, 797 deletions
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index b8e213eb36cc..9a3a6b00391a 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -32,6 +32,7 @@ menu "USB Peripheral Controller"
config USB_AT91
tristate "Atmel AT91 USB Device Port"
depends on ARCH_AT91
+ depends on OF || COMPILE_TEST
help
Many Atmel AT91 processors (such as the AT91RM2000) have a
full speed USB Device Port with support for five configurable
@@ -198,7 +199,7 @@ config USB_S3C2410
S3C2440 processors.
config USB_S3C2410_DEBUG
- boolean "S3C2410 udc debug messages"
+ bool "S3C2410 udc debug messages"
depends on USB_S3C2410
config USB_S3C_HSUDC
@@ -287,7 +288,7 @@ config USB_NET2272
gadget drivers to also be dynamically linked.
config USB_NET2272_DMA
- boolean "Support external DMA controller"
+ bool "Support external DMA controller"
depends on USB_NET2272 && HAS_DMA
help
The NET2272 part can optionally support an external DMA
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index c862656d18b8..2fbedca3c2b4 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -31,16 +31,9 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_data/atmel.h>
-
-#include <asm/byteorder.h>
-#include <mach/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/gpio.h>
-
-#include <mach/cpu.h>
-#include <mach/at91sam9261_matrix.h>
-#include <mach/at91_matrix.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/atmel-matrix.h>
#include "at91_udc.h"
@@ -66,7 +59,15 @@
#define DRIVER_VERSION "3 May 2006"
static const char driver_name [] = "at91_udc";
-static const char ep0name[] = "ep0";
+static const char * const ep_names[] = {
+ "ep0",
+ "ep1",
+ "ep2",
+ "ep3-int",
+ "ep4",
+ "ep5",
+};
+#define ep0name ep_names[0]
#define VBUS_POLL_TIMEOUT msecs_to_jiffies(1000)
@@ -176,7 +177,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
udc->enabled
? (udc->vbus ? "active" : "enabled")
: "disabled",
- udc->selfpowered ? "self" : "VBUS",
+ udc->gadget.is_selfpowered ? "self" : "VBUS",
udc->suspended ? ", suspended" : "",
udc->driver ? udc->driver->driver.name : "(none)");
@@ -895,8 +896,6 @@ static void clk_on(struct at91_udc *udc)
return;
udc->clocked = 1;
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_enable(udc->uclk);
clk_enable(udc->iclk);
clk_enable(udc->fclk);
}
@@ -909,8 +908,6 @@ static void clk_off(struct at91_udc *udc)
udc->gadget.speed = USB_SPEED_UNKNOWN;
clk_disable(udc->fclk);
clk_disable(udc->iclk);
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_disable(udc->uclk);
}
/*
@@ -919,8 +916,6 @@ static void clk_off(struct at91_udc *udc)
*/
static void pullup(struct at91_udc *udc, int is_on)
{
- int active = !udc->board.pullup_active_low;
-
if (!udc->enabled || !udc->vbus)
is_on = 0;
DBG("%sactive\n", is_on ? "" : "in");
@@ -929,40 +924,15 @@ static void pullup(struct at91_udc *udc, int is_on)
clk_on(udc);
at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
at91_udp_write(udc, AT91_UDP_TXVC, 0);
- if (cpu_is_at91rm9200())
- gpio_set_value(udc->board.pullup_pin, active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
- u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-
- txvc |= AT91_UDP_TXVC_PUON;
- at91_udp_write(udc, AT91_UDP_TXVC, txvc);
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- u32 usbpucr;
-
- usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
- usbpucr |= AT91_MATRIX_USBPUCR_PUON;
- at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
- }
} else {
stop_activity(udc);
at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
- if (cpu_is_at91rm9200())
- gpio_set_value(udc->board.pullup_pin, !active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
- u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-
- txvc &= ~AT91_UDP_TXVC_PUON;
- at91_udp_write(udc, AT91_UDP_TXVC, txvc);
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- u32 usbpucr;
-
- usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
- usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
- at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
- }
clk_off(udc);
}
+
+ if (udc->caps && udc->caps->pullup)
+ udc->caps->pullup(udc, is_on);
}
/* vbus is here! turn everything on that's ready */
@@ -1000,7 +970,7 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on)
unsigned long flags;
spin_lock_irqsave(&udc->lock, flags);
- udc->selfpowered = (is_on != 0);
+ gadget->is_selfpowered = (is_on != 0);
spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -1149,7 +1119,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
*/
case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
| USB_REQ_GET_STATUS:
- tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
+ tmp = (udc->gadget.is_selfpowered << USB_DEVICE_SELF_POWERED);
if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
PACKET("get device status\n");
@@ -1535,74 +1505,6 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
/*-------------------------------------------------------------------------*/
-static struct at91_udc controller = {
- .gadget = {
- .ops = &at91_udc_ops,
- .ep0 = &controller.ep[0].ep,
- .name = driver_name,
- },
- .ep[0] = {
- .ep = {
- .name = ep0name,
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .maxpacket = 8,
- .int_mask = 1 << 0,
- },
- .ep[1] = {
- .ep = {
- .name = "ep1",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 64,
- .int_mask = 1 << 1,
- },
- .ep[2] = {
- .ep = {
- .name = "ep2",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 64,
- .int_mask = 1 << 2,
- },
- .ep[3] = {
- .ep = {
- /* could actually do bulk too */
- .name = "ep3-int",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .maxpacket = 8,
- .int_mask = 1 << 3,
- },
- .ep[4] = {
- .ep = {
- .name = "ep4",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 256,
- .int_mask = 1 << 4,
- },
- .ep[5] = {
- .ep = {
- .name = "ep5",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 256,
- .int_mask = 1 << 5,
- },
- /* ep6 and ep7 are also reserved (custom silicon might use them) */
-};
-
static void at91_vbus_update(struct at91_udc *udc, unsigned value)
{
value ^= udc->board.vbus_active_low;
@@ -1653,7 +1555,7 @@ static int at91_start(struct usb_gadget *gadget,
udc->driver = driver;
udc->gadget.dev.of_node = udc->pdev->dev.of_node;
udc->enabled = 1;
- udc->selfpowered = 1;
+ udc->gadget.is_selfpowered = 1;
return 0;
}
@@ -1687,12 +1589,202 @@ static void at91udc_shutdown(struct platform_device *dev)
spin_unlock_irqrestore(&udc->lock, flags);
}
-static void at91udc_of_init(struct at91_udc *udc,
- struct device_node *np)
+static int at91rm9200_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int ret;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ case 3:
+ ep->maxpacket = 8;
+ break;
+ case 1 ... 2:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ if (!gpio_is_valid(udc->board.pullup_pin)) {
+ DBG("no D+ pullup?\n");
+ return -ENODEV;
+ }
+
+ ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin,
+ "udc_pullup");
+ if (ret) {
+ DBG("D+ pullup is busy\n");
+ return ret;
+ }
+
+ gpio_direction_output(udc->board.pullup_pin,
+ udc->board.pullup_active_low);
+
+ return 0;
+}
+
+static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ int active = !udc->board.pullup_active_low;
+
+ if (is_on)
+ gpio_set_value(udc->board.pullup_pin, active);
+ else
+ gpio_set_value(udc->board.pullup_pin, !active);
+}
+
+static const struct at91_udc_caps at91rm9200_udc_caps = {
+ .init = at91rm9200_udc_init,
+ .pullup = at91rm9200_udc_pullup,
+};
+
+static int at91sam9260_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0 ... 3:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 512;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void at91sam9260_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+ if (is_on)
+ txvc |= AT91_UDP_TXVC_PUON;
+ else
+ txvc &= ~AT91_UDP_TXVC_PUON;
+
+ at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+}
+
+static const struct at91_udc_caps at91sam9260_udc_caps = {
+ .init = at91sam9260_udc_init,
+ .pullup = at91sam9260_udc_pullup,
+};
+
+static int at91sam9261_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ ep->maxpacket = 8;
+ break;
+ case 1 ... 3:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node,
+ "atmel,matrix");
+ if (IS_ERR(udc->matrix))
+ return PTR_ERR(udc->matrix);
+
+ return 0;
+}
+
+static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ u32 usbpucr = 0;
+
+ if (is_on)
+ usbpucr = AT91_MATRIX_USBPUCR_PUON;
+
+ regmap_update_bits(udc->matrix, AT91SAM9261_MATRIX_USBPUCR,
+ AT91_MATRIX_USBPUCR_PUON, usbpucr);
+}
+
+static const struct at91_udc_caps at91sam9261_udc_caps = {
+ .init = at91sam9261_udc_init,
+ .pullup = at91sam9261_udc_pullup,
+};
+
+static int at91sam9263_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ ep->maxpacket = 64;
+ break;
+ case 4:
+ case 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static const struct at91_udc_caps at91sam9263_udc_caps = {
+ .init = at91sam9263_udc_init,
+ .pullup = at91sam9260_udc_pullup,
+};
+
+static const struct of_device_id at91_udc_dt_ids[] = {
+ {
+ .compatible = "atmel,at91rm9200-udc",
+ .data = &at91rm9200_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9260-udc",
+ .data = &at91sam9260_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9261-udc",
+ .data = &at91sam9261_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9263-udc",
+ .data = &at91sam9263_udc_caps,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
+
+static void at91udc_of_init(struct at91_udc *udc, struct device_node *np)
{
struct at91_udc_data *board = &udc->board;
- u32 val;
+ const struct of_device_id *match;
enum of_gpio_flags flags;
+ u32 val;
if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
board->vbus_polled = 1;
@@ -1705,6 +1797,10 @@ static void at91udc_of_init(struct at91_udc *udc,
&flags);
board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
+ match = of_match_node(at91_udc_dt_ids, np);
+ if (match)
+ udc->caps = match->data;
}
static int at91udc_probe(struct platform_device *pdev)
@@ -1713,97 +1809,67 @@ static int at91udc_probe(struct platform_device *pdev)
struct at91_udc *udc;
int retval;
struct resource *res;
+ struct at91_ep *ep;
+ int i;
- if (!dev_get_platdata(dev) && !pdev->dev.of_node) {
- /* small (so we copy it) but critical! */
- DBG("missing platform_data\n");
- return -ENODEV;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
-
- if (!request_mem_region(res->start, resource_size(res), driver_name)) {
- DBG("someone's using UDC memory\n");
- return -EBUSY;
- }
+ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL);
+ if (!udc)
+ return -ENOMEM;
/* init software state */
- udc = &controller;
udc->gadget.dev.parent = dev;
- if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
- at91udc_of_init(udc, pdev->dev.of_node);
- else
- memcpy(&udc->board, dev_get_platdata(dev),
- sizeof(struct at91_udc_data));
+ at91udc_of_init(udc, pdev->dev.of_node);
udc->pdev = pdev;
udc->enabled = 0;
spin_lock_init(&udc->lock);
- /* rm9200 needs manual D+ pullup; off by default */
- if (cpu_is_at91rm9200()) {
- if (!gpio_is_valid(udc->board.pullup_pin)) {
- DBG("no D+ pullup?\n");
- retval = -ENODEV;
- goto fail0;
- }
- retval = gpio_request(udc->board.pullup_pin, "udc_pullup");
- if (retval) {
- DBG("D+ pullup is busy\n");
- goto fail0;
- }
- gpio_direction_output(udc->board.pullup_pin,
- udc->board.pullup_active_low);
- }
+ udc->gadget.ops = &at91_udc_ops;
+ udc->gadget.ep0 = &udc->ep[0].ep;
+ udc->gadget.name = driver_name;
+ udc->gadget.dev.init_name = "gadget";
- /* newer chips have more FIFO memory than rm9200 */
- if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) {
- udc->ep[0].maxpacket = 64;
- udc->ep[3].maxpacket = 64;
- udc->ep[4].maxpacket = 512;
- udc->ep[5].maxpacket = 512;
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- udc->ep[3].maxpacket = 64;
- } else if (cpu_is_at91sam9263()) {
- udc->ep[0].maxpacket = 64;
- udc->ep[3].maxpacket = 64;
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+ ep->ep.name = ep_names[i];
+ ep->ep.ops = &at91_ep_ops;
+ ep->udc = udc;
+ ep->int_mask = BIT(i);
+ if (i != 0 && i != 3)
+ ep->is_pingpong = 1;
}
- udc->udp_baseaddr = ioremap(res->start, resource_size(res));
- if (!udc->udp_baseaddr) {
- retval = -ENOMEM;
- goto fail0a;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ udc->udp_baseaddr = devm_ioremap_resource(dev, res);
+ if (IS_ERR(udc->udp_baseaddr))
+ return PTR_ERR(udc->udp_baseaddr);
+
+ if (udc->caps && udc->caps->init) {
+ retval = udc->caps->init(udc);
+ if (retval)
+ return retval;
}
udc_reinit(udc);
/* get interface and function clocks */
- udc->iclk = clk_get(dev, "udc_clk");
- udc->fclk = clk_get(dev, "udpck");
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- udc->uclk = clk_get(dev, "usb_clk");
- if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk) ||
- (IS_ENABLED(CONFIG_COMMON_CLK) && IS_ERR(udc->uclk))) {
- DBG("clocks missing\n");
- retval = -ENODEV;
- goto fail1;
- }
+ udc->iclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(udc->iclk))
+ return PTR_ERR(udc->iclk);
+
+ udc->fclk = devm_clk_get(dev, "hclk");
+ if (IS_ERR(udc->fclk))
+ return PTR_ERR(udc->fclk);
/* don't do anything until we have both gadget driver and VBUS */
- if (IS_ENABLED(CONFIG_COMMON_CLK)) {
- clk_set_rate(udc->uclk, 48000000);
- retval = clk_prepare(udc->uclk);
- if (retval)
- goto fail1;
- }
+ clk_set_rate(udc->fclk, 48000000);
retval = clk_prepare(udc->fclk);
if (retval)
- goto fail1a;
+ return retval;
retval = clk_prepare_enable(udc->iclk);
if (retval)
- goto fail1b;
+ goto err_unprepare_fclk;
+
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
/* Clear all pending interrupts - UDP may be used by bootloader. */
@@ -1812,18 +1878,21 @@ static int at91udc_probe(struct platform_device *pdev)
/* request UDC and maybe VBUS irqs */
udc->udp_irq = platform_get_irq(pdev, 0);
- retval = request_irq(udc->udp_irq, at91_udc_irq,
- 0, driver_name, udc);
- if (retval < 0) {
+ retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
+ driver_name, udc);
+ if (retval) {
DBG("request irq %d failed\n", udc->udp_irq);
- goto fail1c;
+ goto err_unprepare_iclk;
}
+
if (gpio_is_valid(udc->board.vbus_pin)) {
- retval = gpio_request(udc->board.vbus_pin, "udc_vbus");
- if (retval < 0) {
+ retval = devm_gpio_request(dev, udc->board.vbus_pin,
+ "udc_vbus");
+ if (retval) {
DBG("request vbus pin failed\n");
- goto fail2;
+ goto err_unprepare_iclk;
}
+
gpio_direction_input(udc->board.vbus_pin);
/*
@@ -1840,12 +1909,13 @@ static int at91udc_probe(struct platform_device *pdev)
mod_timer(&udc->vbus_timer,
jiffies + VBUS_POLL_TIMEOUT);
} else {
- if (request_irq(gpio_to_irq(udc->board.vbus_pin),
- at91_vbus_irq, 0, driver_name, udc)) {
+ retval = devm_request_irq(dev,
+ gpio_to_irq(udc->board.vbus_pin),
+ at91_vbus_irq, 0, driver_name, udc);
+ if (retval) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
- retval = -EBUSY;
- goto fail3;
+ goto err_unprepare_iclk;
}
}
} else {
@@ -1854,49 +1924,27 @@ static int at91udc_probe(struct platform_device *pdev)
}
retval = usb_add_gadget_udc(dev, &udc->gadget);
if (retval)
- goto fail4;
+ goto err_unprepare_iclk;
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
return 0;
-fail4:
- if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
- free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
-fail3:
- if (gpio_is_valid(udc->board.vbus_pin))
- gpio_free(udc->board.vbus_pin);
-fail2:
- free_irq(udc->udp_irq, udc);
-fail1c:
+
+err_unprepare_iclk:
clk_unprepare(udc->iclk);
-fail1b:
+err_unprepare_fclk:
clk_unprepare(udc->fclk);
-fail1a:
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_unprepare(udc->uclk);
-fail1:
- if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk))
- clk_put(udc->uclk);
- if (!IS_ERR(udc->fclk))
- clk_put(udc->fclk);
- if (!IS_ERR(udc->iclk))
- clk_put(udc->iclk);
- iounmap(udc->udp_baseaddr);
-fail0a:
- if (cpu_is_at91rm9200())
- gpio_free(udc->board.pullup_pin);
-fail0:
- release_mem_region(res->start, resource_size(res));
+
DBG("%s probe failed, %d\n", driver_name, retval);
+
return retval;
}
static int __exit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
- struct resource *res;
unsigned long flags;
DBG("remove\n");
@@ -1911,29 +1959,9 @@ static int __exit at91udc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
- if (gpio_is_valid(udc->board.vbus_pin)) {
- free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
- gpio_free(udc->board.vbus_pin);
- }
- free_irq(udc->udp_irq, udc);
- iounmap(udc->udp_baseaddr);
-
- if (cpu_is_at91rm9200())
- gpio_free(udc->board.pullup_pin);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_unprepare(udc->uclk);
clk_unprepare(udc->fclk);
clk_unprepare(udc->iclk);
- clk_put(udc->iclk);
- clk_put(udc->fclk);
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_put(udc->uclk);
-
return 0;
}
@@ -1989,15 +2017,6 @@ static int at91udc_resume(struct platform_device *pdev)
#define at91udc_resume NULL
#endif
-#if defined(CONFIG_OF)
-static const struct of_device_id at91_udc_dt_ids[] = {
- { .compatible = "atmel,at91rm9200-udc" },
- { /* sentinel */ }
-};
-
-MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
-#endif
-
static struct platform_driver at91_udc_driver = {
.remove = __exit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
@@ -2005,7 +2024,7 @@ static struct platform_driver at91_udc_driver = {
.resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
- .of_match_table = of_match_ptr(at91_udc_dt_ids),
+ .of_match_table = at91_udc_dt_ids,
},
};
diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h
index 017524663381..2679c8b217cc 100644
--- a/drivers/usb/gadget/udc/at91_udc.h
+++ b/drivers/usb/gadget/udc/at91_udc.h
@@ -107,6 +107,11 @@ struct at91_ep {
unsigned fifo_bank:1;
};
+struct at91_udc_caps {
+ int (*init)(struct at91_udc *udc);
+ void (*pullup)(struct at91_udc *udc, int is_on);
+};
+
/*
* driver is non-SMP, and just blocks IRQs whenever it needs
* access protection for chip registers or driver state
@@ -115,6 +120,7 @@ struct at91_udc {
struct usb_gadget gadget;
struct at91_ep ep[NUM_ENDPOINTS];
struct usb_gadget_driver *driver;
+ const struct at91_udc_caps *caps;
unsigned vbus:1;
unsigned enabled:1;
unsigned clocked:1;
@@ -122,11 +128,10 @@ struct at91_udc {
unsigned req_pending:1;
unsigned wait_for_addr_ack:1;
unsigned wait_for_config_ack:1;
- unsigned selfpowered:1;
unsigned active_suspend:1;
u8 addr;
struct at91_udc_data board;
- struct clk *iclk, *fclk, *uclk;
+ struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
void __iomem *udp_baseaddr;
@@ -134,6 +139,7 @@ struct at91_udc {
spinlock_t lock;
struct timer_list vbus_timer;
struct work_struct vbus_timer_work;
+ struct regmap *matrix;
};
static inline struct at91_udc *to_udc(struct usb_gadget *g)
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index 9f93bed42052..d79cb35dbf8a 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
+#include <linux/clk/at91_pmc.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -264,14 +265,17 @@ static void usba_init_debugfs(struct usba_udc *udc)
goto err_root;
udc->debugfs_root = root;
- regs = debugfs_create_file("regs", 0400, root, udc, &regs_dbg_fops);
- if (!regs)
- goto err_regs;
-
regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM,
CTRL_IOMEM_ID);
- regs->d_inode->i_size = resource_size(regs_resource);
- udc->debugfs_regs = regs;
+
+ if (regs_resource) {
+ regs = debugfs_create_file_size("regs", 0400, root, udc,
+ &regs_dbg_fops,
+ resource_size(regs_resource));
+ if (!regs)
+ goto err_regs;
+ udc->debugfs_regs = regs;
+ }
usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0));
@@ -315,6 +319,17 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc)
}
#endif
+static inline u32 usba_int_enb_get(struct usba_udc *udc)
+{
+ return udc->int_enb_cache;
+}
+
+static inline void usba_int_enb_set(struct usba_udc *udc, u32 val)
+{
+ usba_writel(udc, INT_ENB, val);
+ udc->int_enb_cache = val;
+}
+
static int vbus_is_present(struct usba_udc *udc)
{
if (gpio_is_valid(udc->vbus_pin))
@@ -324,27 +339,22 @@ static int vbus_is_present(struct usba_udc *udc)
return 1;
}
-#if defined(CONFIG_ARCH_AT91SAM9RL)
-
-#include <linux/clk/at91_pmc.h>
-
-static void toggle_bias(int is_on)
+static void toggle_bias(struct usba_udc *udc, int is_on)
{
- unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
-
- if (is_on)
- at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
- else
- at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+ if (udc->errata && udc->errata->toggle_bias)
+ udc->errata->toggle_bias(udc, is_on);
}
-#else
-
-static void toggle_bias(int is_on)
+static void generate_bias_pulse(struct usba_udc *udc)
{
-}
+ if (!udc->bias_pulse_needed)
+ return;
-#endif /* CONFIG_ARCH_AT91SAM9RL */
+ if (udc->errata && udc->errata->pulse_bias)
+ udc->errata->pulse_bias(udc);
+
+ udc->bias_pulse_needed = false;
+}
static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req)
{
@@ -601,16 +611,14 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
if (ep->can_dma) {
u32 ctrl;
- usba_writel(udc, INT_ENB,
- (usba_readl(udc, INT_ENB)
- | USBA_BF(EPT_INT, 1 << ep->index)
- | USBA_BF(DMA_INT, 1 << ep->index)));
+ usba_int_enb_set(udc, usba_int_enb_get(udc) |
+ USBA_BF(EPT_INT, 1 << ep->index) |
+ USBA_BF(DMA_INT, 1 << ep->index));
ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA;
usba_ep_writel(ep, CTL_ENB, ctrl);
} else {
- usba_writel(udc, INT_ENB,
- (usba_readl(udc, INT_ENB)
- | USBA_BF(EPT_INT, 1 << ep->index)));
+ usba_int_enb_set(udc, usba_int_enb_get(udc) |
+ USBA_BF(EPT_INT, 1 << ep->index));
}
spin_unlock_irqrestore(&udc->lock, flags);
@@ -618,7 +626,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index,
(unsigned long)usba_ep_readl(ep, CFG));
DBG(DBG_HW, "INT_ENB after init: %#08lx\n",
- (unsigned long)usba_readl(udc, INT_ENB));
+ (unsigned long)usba_int_enb_get(udc));
return 0;
}
@@ -654,9 +662,8 @@ static int usba_ep_disable(struct usb_ep *_ep)
usba_dma_readl(ep, STATUS);
}
usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE);
- usba_writel(udc, INT_ENB,
- usba_readl(udc, INT_ENB)
- & ~USBA_BF(EPT_INT, 1 << ep->index));
+ usba_int_enb_set(udc, usba_int_enb_get(udc) &
+ ~USBA_BF(EPT_INT, 1 << ep->index));
request_complete_list(ep, &req_list, -ESHUTDOWN);
@@ -985,6 +992,7 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
struct usba_udc *udc = to_usba_udc(gadget);
unsigned long flags;
+ gadget->is_selfpowered = (is_selfpowered != 0);
spin_lock_irqsave(&udc->lock, flags);
if (is_selfpowered)
udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED;
@@ -1619,18 +1627,21 @@ static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep)
static irqreturn_t usba_udc_irq(int irq, void *devid)
{
struct usba_udc *udc = devid;
- u32 status;
+ u32 status, int_enb;
u32 dma_status;
u32 ep_status;
spin_lock(&udc->lock);
- status = usba_readl(udc, INT_STA);
+ int_enb = usba_int_enb_get(udc);
+ status = usba_readl(udc, INT_STA) & int_enb;
DBG(DBG_INT, "irq, status=%#08x\n", status);
if (status & USBA_DET_SUSPEND) {
- toggle_bias(0);
+ toggle_bias(udc, 0);
usba_writel(udc, INT_CLR, USBA_DET_SUSPEND);
+ usba_int_enb_set(udc, int_enb | USBA_WAKE_UP);
+ udc->bias_pulse_needed = true;
DBG(DBG_BUS, "Suspend detected\n");
if (udc->gadget.speed != USB_SPEED_UNKNOWN
&& udc->driver && udc->driver->suspend) {
@@ -1641,13 +1652,15 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
}
if (status & USBA_WAKE_UP) {
- toggle_bias(1);
+ toggle_bias(udc, 1);
usba_writel(udc, INT_CLR, USBA_WAKE_UP);
+ usba_int_enb_set(udc, int_enb & ~USBA_WAKE_UP);
DBG(DBG_BUS, "Wake Up CPU detected\n");
}
if (status & USBA_END_OF_RESUME) {
usba_writel(udc, INT_CLR, USBA_END_OF_RESUME);
+ generate_bias_pulse(udc);
DBG(DBG_BUS, "Resume detected\n");
if (udc->gadget.speed != USB_SPEED_UNKNOWN
&& udc->driver && udc->driver->resume) {
@@ -1683,6 +1696,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
struct usba_ep *ep0;
usba_writel(udc, INT_CLR, USBA_END_OF_RESET);
+ generate_bias_pulse(udc);
reset_all_endpoints(udc);
if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) {
@@ -1708,11 +1722,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid)
| USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE)));
usba_ep_writel(ep0, CTL_ENB,
USBA_EPT_ENABLE | USBA_RX_SETUP);
- usba_writel(udc, INT_ENB,
- (usba_readl(udc, INT_ENB)
- | USBA_BF(EPT_INT, 1)
- | USBA_DET_SUSPEND
- | USBA_END_OF_RESUME));
+ usba_int_enb_set(udc, int_enb | USBA_BF(EPT_INT, 1) |
+ USBA_DET_SUSPEND | USBA_END_OF_RESUME);
/*
* Unclear why we hit this irregularly, e.g. in usbtest,
@@ -1745,13 +1756,13 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid)
vbus = vbus_is_present(udc);
if (vbus != udc->vbus_prev) {
if (vbus) {
- toggle_bias(1);
+ toggle_bias(udc, 1);
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
- usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+ usba_int_enb_set(udc, USBA_END_OF_RESET);
} else {
udc->gadget.speed = USB_SPEED_UNKNOWN;
reset_all_endpoints(udc);
- toggle_bias(0);
+ toggle_bias(udc, 0);
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
if (udc->driver->disconnect) {
spin_unlock(&udc->lock);
@@ -1797,9 +1808,9 @@ static int atmel_usba_start(struct usb_gadget *gadget,
/* If Vbus is present, enable the controller and wait for reset */
spin_lock_irqsave(&udc->lock, flags);
if (vbus_is_present(udc) && udc->vbus_prev == 0) {
- toggle_bias(1);
+ toggle_bias(udc, 1);
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
- usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+ usba_int_enb_set(udc, USBA_END_OF_RESET);
}
spin_unlock_irqrestore(&udc->lock, flags);
@@ -1820,7 +1831,7 @@ static int atmel_usba_stop(struct usb_gadget *gadget)
spin_unlock_irqrestore(&udc->lock, flags);
/* This will also disable the DP pullup */
- toggle_bias(0);
+ toggle_bias(udc, 0);
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
clk_disable_unprepare(udc->hclk);
@@ -1832,6 +1843,41 @@ static int atmel_usba_stop(struct usb_gadget *gadget)
}
#ifdef CONFIG_OF
+static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on)
+{
+ unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+
+ if (is_on)
+ at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+ else
+ at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+}
+
+static void at91sam9g45_pulse_bias(struct usba_udc *udc)
+{
+ unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
+
+ at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+ at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+}
+
+static const struct usba_udc_errata at91sam9rl_errata = {
+ .toggle_bias = at91sam9rl_toggle_bias,
+};
+
+static const struct usba_udc_errata at91sam9g45_errata = {
+ .pulse_bias = at91sam9g45_pulse_bias,
+};
+
+static const struct of_device_id atmel_udc_dt_ids[] = {
+ { .compatible = "atmel,at91sam9rl-udc", .data = &at91sam9rl_errata },
+ { .compatible = "atmel,at91sam9g45-udc", .data = &at91sam9g45_errata },
+ { .compatible = "atmel,sama5d3-udc" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
+
static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
struct usba_udc *udc)
{
@@ -1839,10 +1885,17 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
const char *name;
enum of_gpio_flags flags;
struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match;
struct device_node *pp;
int i, ret;
struct usba_ep *eps, *ep;
+ match = of_match_node(atmel_udc_dt_ids, np);
+ if (!match)
+ return ERR_PTR(-EINVAL);
+
+ udc->errata = match->data;
+
udc->num_ep = 0;
udc->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
@@ -2033,7 +2086,7 @@ static int usba_udc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Unable to enable pclk, aborting.\n");
return ret;
}
- toggle_bias(0);
+
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
clk_disable_unprepare(pclk);
@@ -2042,6 +2095,8 @@ static int usba_udc_probe(struct platform_device *pdev)
else
udc->usba_ep = usba_udc_pdata(pdev, udc);
+ toggle_bias(udc, 0);
+
if (IS_ERR(udc->usba_ep))
return PTR_ERR(udc->usba_ep);
@@ -2101,15 +2156,6 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
return 0;
}
-#if defined(CONFIG_OF)
-static const struct of_device_id atmel_udc_dt_ids[] = {
- { .compatible = "atmel,at91sam9rl-udc" },
- { /* sentinel */ }
-};
-
-MODULE_DEVICE_TABLE(of, atmel_udc_dt_ids);
-#endif
-
static struct platform_driver udc_driver = {
.remove = __exit_p(usba_udc_remove),
.driver = {
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h
index a70706e8cb02..497cd18836f3 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.h
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.h
@@ -304,6 +304,11 @@ struct usba_request {
unsigned int mapped:1;
};
+struct usba_udc_errata {
+ void (*toggle_bias)(struct usba_udc *udc, int is_on);
+ void (*pulse_bias)(struct usba_udc *udc);
+};
+
struct usba_udc {
/* Protect hw registers from concurrent modifications */
spinlock_t lock;
@@ -314,6 +319,7 @@ struct usba_udc {
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
struct platform_device *pdev;
+ const struct usba_udc_errata *errata;
int irq;
int vbus_pin;
int vbus_pin_inverted;
@@ -321,12 +327,15 @@ struct usba_udc {
struct clk *pclk;
struct clk *hclk;
struct usba_ep *usba_ep;
+ bool bias_pulse_needed;
u16 devstatus;
u16 test_mode;
int vbus_prev;
+ u32 int_enb_cache;
+
#ifdef CONFIG_USB_GADGET_DEBUG_FS
struct dentry *debugfs_root;
struct dentry *debugfs_regs;
diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c
index c6dfef8c7bbc..5c8f4effb62a 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_core.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_core.c
@@ -521,7 +521,6 @@ static int bdc_remove(struct platform_device *pdev)
static struct platform_driver bdc_driver = {
.driver = {
.name = BRCM_BDC_NAME,
- .owner = THIS_MODULE
},
.probe = bdc_probe,
.remove = bdc_remove,
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c
index d4fe8d769bd6..b04980cf6dc4 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_ep.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c
@@ -718,7 +718,7 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req)
struct bdc *bdc;
int ret = 0;
- if (!req || !ep || !ep->usb_ep.desc)
+ if (!req || !ep->usb_ep.desc)
return -EINVAL;
bdc = ep->bdc;
@@ -882,8 +882,8 @@ static int ep_set_halt(struct bdc_ep *ep, u32 value)
ret = bdc_ep_set_stall(bdc, ep->ep_num);
if (ret)
- dev_err(bdc->dev, "failed to %s STALL on %s\n",
- value ? "set" : "clear", ep->name);
+ dev_err(bdc->dev, "failed to set STALL on %s\n",
+ ep->name);
else
ep->flags |= BDC_EP_STALL;
} else {
@@ -891,8 +891,8 @@ static int ep_set_halt(struct bdc_ep *ep, u32 value)
dev_dbg(bdc->dev, "Before Clear\n");
ret = bdc_ep_clear_stall(bdc, ep->ep_num);
if (ret)
- dev_err(bdc->dev, "failed to %s STALL on %s\n",
- value ? "set" : "clear", ep->name);
+ dev_err(bdc->dev, "failed to clear STALL on %s\n",
+ ep->name);
else
ep->flags &= ~BDC_EP_STALL;
dev_dbg(bdc->dev, "After Clear\n");
diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c
index 3700ce70b0be..7f77db5d1278 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_udc.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c
@@ -454,6 +454,7 @@ static int bdc_udc_set_selfpowered(struct usb_gadget *gadget,
unsigned long flags;
dev_dbg(bdc->dev, "%s()\n", __func__);
+ gadget->is_selfpowered = (is_self != 0);
spin_lock_irqsave(&bdc->lock, flags);
if (!is_self)
bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED;
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 9c598801404c..8dda48445f6f 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -802,6 +802,7 @@ static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value)
{
struct dummy *dum;
+ _gadget->is_selfpowered = (value != 0);
dum = gadget_to_dummy_hcd(_gadget)->dum;
if (value)
dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
@@ -1924,7 +1925,9 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc)
memset(desc, 0, sizeof *desc);
desc->bDescriptorType = 0x2a;
desc->bDescLength = 12;
- desc->wHubCharacteristics = cpu_to_le16(0x0001);
+ desc->wHubCharacteristics = cpu_to_le16(
+ HUB_CHAR_INDV_PORT_LPSM |
+ HUB_CHAR_COMMON_OCPM);
desc->bNbrPorts = 1;
desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
desc->u.ss.DeviceRemovable = 0xffff;
@@ -1935,7 +1938,9 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
memset(desc, 0, sizeof *desc);
desc->bDescriptorType = 0x29;
desc->bDescLength = 9;
- desc->wHubCharacteristics = cpu_to_le16(0x0001);
+ desc->wHubCharacteristics = cpu_to_le16(
+ HUB_CHAR_INDV_PORT_LPSM |
+ HUB_CHAR_COMMON_OCPM);
desc->bNbrPorts = 1;
desc->u.hs.DeviceRemovable[0] = 0xff;
desc->u.hs.DeviceRemovable[1] = 0xff;
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c
index 795c99c77697..e0822f1b6639 100644
--- a/drivers/usb/gadget/udc/fsl_qe_udc.c
+++ b/drivers/usb/gadget/udc/fsl_qe_udc.c
@@ -2630,7 +2630,7 @@ static int qe_udc_remove(struct platform_device *ofdev)
struct qe_udc *udc = platform_get_drvdata(ofdev);
struct qe_ep *ep;
unsigned int size;
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
usb_del_gadget_udc(&udc->gadget);
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
index 2df807403f22..55fcb930f92e 100644
--- a/drivers/usb/gadget/udc/fsl_udc_core.c
+++ b/drivers/usb/gadget/udc/fsl_udc_core.c
@@ -1337,7 +1337,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
/* Get device status */
- tmp = 1 << USB_DEVICE_SELF_POWERED;
+ tmp = udc->gadget.is_selfpowered;
tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
/* Get interface status */
@@ -1948,6 +1948,7 @@ static int fsl_udc_start(struct usb_gadget *g,
/* hook up the driver */
udc_controller->driver = driver;
spin_unlock_irqrestore(&udc_controller->lock, flags);
+ g->is_selfpowered = 1;
if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
/* Suspend the controller until OTG enable it */
@@ -2529,7 +2530,7 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
if (!udc_controller)
return -ENODEV;
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 34d9b7b831b3..27fd41333f71 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -191,7 +191,6 @@ struct lpc32xx_udc {
bool enabled;
bool clocked;
bool suspended;
- bool selfpowered;
int ep0state;
atomic_t enabled_ep_cnt;
wait_queue_head_t ep_disable_wait_queue;
@@ -547,7 +546,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
udc->vbus ? "present" : "off",
udc->enabled ? (udc->vbus ? "active" : "enabled") :
"disabled",
- udc->selfpowered ? "self" : "VBUS",
+ udc->gadget.is_selfpowered ? "self" : "VBUS",
udc->suspended ? ", suspended" : "",
udc->driver ? udc->driver->driver.name : "(none)");
@@ -2212,7 +2211,7 @@ static int udc_get_status(struct lpc32xx_udc *udc, u16 reqtype, u16 wIndex)
break; /* Not supported */
case USB_RECIP_DEVICE:
- ep0buff = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
+ ep0buff = udc->gadget.is_selfpowered;
if (udc->dev_status & (1 << USB_DEVICE_REMOTE_WAKEUP))
ep0buff |= (1 << USB_DEVICE_REMOTE_WAKEUP);
break;
@@ -2498,10 +2497,7 @@ static int lpc32xx_wakeup(struct usb_gadget *gadget)
static int lpc32xx_set_selfpowered(struct usb_gadget *gadget, int is_on)
{
- struct lpc32xx_udc *udc = to_udc(gadget);
-
- /* Always self-powered */
- udc->selfpowered = (is_on != 0);
+ gadget->is_selfpowered = (is_on != 0);
return 0;
}
@@ -2946,7 +2942,7 @@ static int lpc32xx_start(struct usb_gadget *gadget,
udc->driver = driver;
udc->gadget.dev.of_node = udc->dev->of_node;
udc->enabled = 1;
- udc->selfpowered = 1;
+ udc->gadget.is_selfpowered = 1;
udc->vbus = 0;
/* Force VBUS process once to check for cable insertion */
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c
index 253f3df8326a..d32160d6463f 100644
--- a/drivers/usb/gadget/udc/mv_udc_core.c
+++ b/drivers/usb/gadget/udc/mv_udc_core.c
@@ -1378,9 +1378,6 @@ static int mv_udc_start(struct usb_gadget *gadget,
}
}
- /* pullup is always on */
- mv_udc_pullup(&udc->gadget, 1);
-
/* When boot with cable attached, there will be no vbus irq occurred */
if (udc->qwork)
queue_work(udc->qwork, &udc->vbus_work);
diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c
index d20de1fab08e..195baf3e1fcd 100644
--- a/drivers/usb/gadget/udc/net2272.c
+++ b/drivers/usb/gadget/udc/net2272.c
@@ -1132,13 +1132,10 @@ net2272_wakeup(struct usb_gadget *_gadget)
static int
net2272_set_selfpowered(struct usb_gadget *_gadget, int value)
{
- struct net2272 *dev;
-
if (!_gadget)
return -ENODEV;
- dev = container_of(_gadget, struct net2272, gadget);
- dev->is_selfpowered = value;
+ _gadget->is_selfpowered = (value != 0);
return 0;
}
@@ -1844,7 +1841,7 @@ net2272_handle_stat0_irqs(struct net2272 *dev, u8 stat)
case USB_RECIP_DEVICE:
if (u.r.wLength > 2)
goto do_stall;
- if (dev->is_selfpowered)
+ if (dev->gadget.is_selfpowered)
status = (1 << USB_DEVICE_SELF_POWERED);
/* don't bother with a request object! */
diff --git a/drivers/usb/gadget/udc/net2272.h b/drivers/usb/gadget/udc/net2272.h
index e59505789359..127ab03fcde3 100644
--- a/drivers/usb/gadget/udc/net2272.h
+++ b/drivers/usb/gadget/udc/net2272.h
@@ -458,7 +458,6 @@ struct net2272 {
struct usb_gadget_driver *driver;
unsigned protocol_stall:1,
softconnect:1,
- is_selfpowered:1,
wakeup:1,
dma_eot_polarity:1,
dma_dack_polarity:1,
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index d6411e0a8e03..d2c0bf65e345 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -12,11 +12,7 @@
* the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers
* as well as Gadget Zero and Gadgetfs.
*
- * DMA is enabled by default. Drivers using transfer queues might use
- * DMA chaining to remove IRQ latencies between transfers. (Except when
- * short OUT transfers happen.) Drivers can use the req->no_interrupt
- * hint to completely eliminate some IRQs, if a later IRQ is guaranteed
- * and DMA chaining is enabled.
+ * DMA is enabled by default.
*
* MSI is enabled by default. The legacy IRQ is used if MSI couldn't
* be enabled.
@@ -84,23 +80,6 @@ static const char *const ep_name[] = {
"ep-e", "ep-f", "ep-g", "ep-h",
};
-/* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO)
- * use_dma_chaining -- dma descriptor queueing gives even more irq reduction
- *
- * The net2280 DMA engines are not tightly integrated with their FIFOs;
- * not all cases are (yet) handled well in this driver or the silicon.
- * Some gadget drivers work better with the dma support here than others.
- * These two parameters let you use PIO or more aggressive DMA.
- */
-static bool use_dma = true;
-static bool use_dma_chaining;
-static bool use_msi = true;
-
-/* "modprobe net2280 use_dma=n" etc */
-module_param(use_dma, bool, 0444);
-module_param(use_dma_chaining, bool, 0444);
-module_param(use_msi, bool, 0444);
-
/* mode 0 == ep-{a,b,c,d} 1K fifo each
* mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
* mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable
@@ -120,11 +99,6 @@ static bool enable_suspend;
/* "modprobe net2280 enable_suspend=1" etc */
module_param(enable_suspend, bool, 0444);
-/* force full-speed operation */
-static bool full_speed;
-module_param(full_speed, bool, 0444);
-MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!");
-
#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
static char *type_string(u8 bmAttributes)
@@ -202,15 +176,6 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
/* set speed-dependent max packet; may kick in high bandwidth */
set_max_speed(ep, max);
- /* FIFO lines can't go to different packets. PIO is ok, so
- * use it instead of troublesome (non-bulk) multi-packet DMA.
- */
- if (ep->dma && (max % 4) != 0 && use_dma_chaining) {
- ep_dbg(ep->dev, "%s, no dma for maxpacket %d\n",
- ep->ep.name, ep->ep.maxpacket);
- ep->dma = NULL;
- }
-
/* set type, direction, address; reset fifo counters */
writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
@@ -478,7 +443,7 @@ static int net2280_disable(struct usb_ep *_ep)
/* synch memory views with the device */
(void)readl(&ep->cfg->ep_cfg);
- if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4)
+ if (!ep->dma && ep->num >= 1 && ep->num <= 4)
ep->dma = &ep->dev->dma[ep->num - 1];
spin_unlock_irqrestore(&ep->dev->lock, flags);
@@ -610,9 +575,15 @@ static void out_flush(struct net2280_ep *ep)
u32 __iomem *statp;
u32 tmp;
- ASSERT_OUT_NAKING(ep);
-
statp = &ep->regs->ep_stat;
+
+ tmp = readl(statp);
+ if (tmp & BIT(NAK_OUT_PACKETS)) {
+ ep_dbg(ep->dev, "%s %s %08x !NAK\n",
+ ep->ep.name, __func__, tmp);
+ writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+ }
+
writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
BIT(DATA_PACKET_RECEIVED_INTERRUPT),
statp);
@@ -747,8 +718,7 @@ static void fill_dma_desc(struct net2280_ep *ep,
req->valid = valid;
if (valid)
dmacount |= BIT(VALID_BIT);
- if (likely(!req->req.no_interrupt || !use_dma_chaining))
- dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE);
+ dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE);
/* td->dmadesc = previously set by caller */
td->dmaaddr = cpu_to_le32 (req->req.dma);
@@ -862,27 +832,11 @@ static void start_dma(struct net2280_ep *ep, struct net2280_request *req)
req->td->dmadesc = cpu_to_le32 (ep->td_dma);
fill_dma_desc(ep, req, 1);
- if (!use_dma_chaining)
- req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN));
+ req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN));
start_queue(ep, tmp, req->td_dma);
}
-static inline void resume_dma(struct net2280_ep *ep)
-{
- writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl);
-
- ep->dma_started = true;
-}
-
-static inline void ep_stop_dma(struct net2280_ep *ep)
-{
- writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl);
- spin_stop_dma(ep->dma);
-
- ep->dma_started = false;
-}
-
static inline void
queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid)
{
@@ -973,10 +927,8 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
return ret;
}
-#if 0
ep_vdbg(dev, "%s queue req %p, len %d buf %p\n",
_ep->name, _req, _req->length, _req->buf);
-#endif
spin_lock_irqsave(&dev->lock, flags);
@@ -984,24 +936,12 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
_req->actual = 0;
/* kickstart this i/o queue? */
- if (list_empty(&ep->queue) && !ep->stopped) {
- /* DMA request while EP halted */
- if (ep->dma &&
- (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) &&
- (dev->quirks & PLX_SUPERSPEED)) {
- int valid = 1;
- if (ep->is_in) {
- int expect;
- expect = likely(req->req.zero ||
- ((req->req.length %
- ep->ep.maxpacket) != 0));
- if (expect != ep->in_fifo_validate)
- valid = 0;
- }
- queue_dma(ep, req, valid);
- }
+ if (list_empty(&ep->queue) && !ep->stopped &&
+ !((dev->quirks & PLX_SUPERSPEED) && ep->dma &&
+ (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)))) {
+
/* use DMA if the endpoint supports it, else pio */
- else if (ep->dma)
+ if (ep->dma)
start_dma(ep, req);
else {
/* maybe there's no control data, just status ack */
@@ -1084,8 +1024,6 @@ dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount,
done(ep, req, status);
}
-static void restart_dma(struct net2280_ep *ep);
-
static void scan_dma_completions(struct net2280_ep *ep)
{
/* only look at descriptors that were "naturally" retired,
@@ -1117,9 +1055,8 @@ static void scan_dma_completions(struct net2280_ep *ep)
dma_done(ep, req, tmp, 0);
break;
} else if (!ep->is_in &&
- (req->req.length % ep->ep.maxpacket) != 0) {
- if (ep->dev->quirks & PLX_SUPERSPEED)
- return dma_done(ep, req, tmp, 0);
+ (req->req.length % ep->ep.maxpacket) &&
+ !(ep->dev->quirks & PLX_SUPERSPEED)) {
tmp = readl(&ep->regs->ep_stat);
/* AVOID TROUBLE HERE by not issuing short reads from
@@ -1150,67 +1087,15 @@ static void scan_dma_completions(struct net2280_ep *ep)
static void restart_dma(struct net2280_ep *ep)
{
struct net2280_request *req;
- u32 dmactl = dmactl_default;
if (ep->stopped)
return;
req = list_entry(ep->queue.next, struct net2280_request, queue);
- if (!use_dma_chaining) {
- start_dma(ep, req);
- return;
- }
-
- /* the 2280 will be processing the queue unless queue hiccups after
- * the previous transfer:
- * IN: wanted automagic zlp, head doesn't (or vice versa)
- * DMA_FIFO_VALIDATE doesn't init from dma descriptors.
- * OUT: was "usb-short", we must restart.
- */
- if (ep->is_in && !req->valid) {
- struct net2280_request *entry, *prev = NULL;
- int reqmode, done = 0;
-
- ep_dbg(ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td);
- ep->in_fifo_validate = likely(req->req.zero ||
- (req->req.length % ep->ep.maxpacket) != 0);
- if (ep->in_fifo_validate)
- dmactl |= BIT(DMA_FIFO_VALIDATE);
- list_for_each_entry(entry, &ep->queue, queue) {
- __le32 dmacount;
-
- if (entry == req)
- continue;
- dmacount = entry->td->dmacount;
- if (!done) {
- reqmode = likely(entry->req.zero ||
- (entry->req.length % ep->ep.maxpacket));
- if (reqmode == ep->in_fifo_validate) {
- entry->valid = 1;
- dmacount |= valid_bit;
- entry->td->dmacount = dmacount;
- prev = entry;
- continue;
- } else {
- /* force a hiccup */
- prev->td->dmacount |= dma_done_ie;
- done = 1;
- }
- }
-
- /* walk the rest of the queue so unlinks behave */
- entry->valid = 0;
- dmacount &= ~valid_bit;
- entry->td->dmacount = dmacount;
- prev = entry;
- }
- }
-
- writel(0, &ep->dma->dmactl);
- start_queue(ep, dmactl, req->td_dma);
+ start_dma(ep, req);
}
-static void abort_dma_228x(struct net2280_ep *ep)
+static void abort_dma(struct net2280_ep *ep)
{
/* abort the current transfer */
if (likely(!list_empty(&ep->queue))) {
@@ -1222,19 +1107,6 @@ static void abort_dma_228x(struct net2280_ep *ep)
scan_dma_completions(ep);
}
-static void abort_dma_338x(struct net2280_ep *ep)
-{
- writel(BIT(DMA_ABORT), &ep->dma->dmastat);
- spin_stop_dma(ep->dma);
-}
-
-static void abort_dma(struct net2280_ep *ep)
-{
- if (ep->dev->quirks & PLX_LEGACY)
- return abort_dma_228x(ep);
- return abort_dma_338x(ep);
-}
-
/* dequeue ALL requests */
static void nuke(struct net2280_ep *ep)
{
@@ -1306,25 +1178,6 @@ static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req)
done(ep, req, -ECONNRESET);
}
req = NULL;
-
- /* patch up hardware chaining data */
- } else if (ep->dma && use_dma_chaining) {
- if (req->queue.prev == ep->queue.next) {
- writel(le32_to_cpu(req->td->dmadesc),
- &ep->dma->dmadesc);
- if (req->td->dmacount & dma_done_ie)
- writel(readl(&ep->dma->dmacount) |
- le32_to_cpu(dma_done_ie),
- &ep->dma->dmacount);
- } else {
- struct net2280_request *prev;
-
- prev = list_entry(req->queue.prev,
- struct net2280_request, queue);
- prev->td->dmadesc = req->td->dmadesc;
- if (req->td->dmacount & dma_done_ie)
- prev->td->dmacount |= dma_done_ie;
- }
}
if (req)
@@ -1512,10 +1365,10 @@ static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value)
tmp = readl(&dev->usb->usbctl);
if (value) {
tmp |= BIT(SELF_POWERED_STATUS);
- dev->selfpowered = 1;
+ _gadget->is_selfpowered = 1;
} else {
tmp &= ~BIT(SELF_POWERED_STATUS);
- dev->selfpowered = 0;
+ _gadget->is_selfpowered = 0;
}
writel(tmp, &dev->usb->usbctl);
spin_unlock_irqrestore(&dev->lock, flags);
@@ -1604,14 +1457,11 @@ static ssize_t registers_show(struct device *_dev,
/* Main Control Registers */
t = scnprintf(next, size, "%s version " DRIVER_VERSION
- ", chiprev %04x, dma %s\n\n"
+ ", chiprev %04x\n\n"
"devinit %03x fifoctl %08x gadget '%s'\n"
"pci irqenb0 %02x irqenb1 %08x "
"irqstat0 %04x irqstat1 %08x\n",
driver_name, dev->chiprev,
- use_dma
- ? (use_dma_chaining ? "chaining" : "enabled")
- : "disabled",
readl(&dev->regs->devinit),
readl(&dev->regs->fifoctl),
s,
@@ -1913,76 +1763,73 @@ static void defect7374_disable_data_eps(struct net2280 *dev)
static void defect7374_enable_data_eps_zero(struct net2280 *dev)
{
u32 tmp = 0, tmp_reg;
- u32 fsmvalue, scratch;
+ u32 scratch;
int i;
unsigned char ep_sel;
scratch = get_idx_reg(dev->regs, SCRATCH);
- fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
+
+ WARN_ON((scratch & (0xf << DEFECT7374_FSM_FIELD))
+ == DEFECT7374_FSM_SS_CONTROL_READ);
+
scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
- /*See if firmware needs to set up for workaround*/
- if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
- ep_warn(dev, "Operate Defect 7374 workaround soft this time");
- ep_warn(dev, "It will operate on cold-reboot and SS connect");
-
- /*GPEPs:*/
- tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
- (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
- ((dev->enhanced_mode) ?
- BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
- BIT(IN_ENDPOINT_ENABLE));
-
- for (i = 1; i < 5; i++)
- writel(tmp, &dev->ep[i].cfg->ep_cfg);
-
- /* CSRIN, PCIIN, STATIN, RCIN*/
- tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
- writel(tmp, &dev->dep[1].dep_cfg);
- writel(tmp, &dev->dep[3].dep_cfg);
- writel(tmp, &dev->dep[4].dep_cfg);
- writel(tmp, &dev->dep[5].dep_cfg);
-
- /*Implemented for development and debug.
- * Can be refined/tuned later.*/
- for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
- /* Select an endpoint for subsequent operations: */
- tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
- writel(((tmp_reg & ~0x1f) | ep_sel),
- &dev->plregs->pl_ep_ctrl);
-
- if (ep_sel == 1) {
- tmp =
- (readl(&dev->plregs->pl_ep_ctrl) |
- BIT(CLEAR_ACK_ERROR_CODE) | 0);
- writel(tmp, &dev->plregs->pl_ep_ctrl);
- continue;
- }
+ ep_warn(dev, "Operate Defect 7374 workaround soft this time");
+ ep_warn(dev, "It will operate on cold-reboot and SS connect");
- if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
- ep_sel == 18 || ep_sel == 20)
- continue;
+ /*GPEPs:*/
+ tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
+ (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
+ ((dev->enhanced_mode) ?
+ BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
+ BIT(IN_ENDPOINT_ENABLE));
- tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
- BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
- writel(tmp, &dev->plregs->pl_ep_cfg_4);
+ for (i = 1; i < 5; i++)
+ writel(tmp, &dev->ep[i].cfg->ep_cfg);
- tmp = readl(&dev->plregs->pl_ep_ctrl) &
- ~BIT(EP_INITIALIZED);
- writel(tmp, &dev->plregs->pl_ep_ctrl);
+ /* CSRIN, PCIIN, STATIN, RCIN*/
+ tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
+ writel(tmp, &dev->dep[1].dep_cfg);
+ writel(tmp, &dev->dep[3].dep_cfg);
+ writel(tmp, &dev->dep[4].dep_cfg);
+ writel(tmp, &dev->dep[5].dep_cfg);
+
+ /*Implemented for development and debug.
+ * Can be refined/tuned later.*/
+ for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
+ /* Select an endpoint for subsequent operations: */
+ tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
+ writel(((tmp_reg & ~0x1f) | ep_sel),
+ &dev->plregs->pl_ep_ctrl);
+ if (ep_sel == 1) {
+ tmp =
+ (readl(&dev->plregs->pl_ep_ctrl) |
+ BIT(CLEAR_ACK_ERROR_CODE) | 0);
+ writel(tmp, &dev->plregs->pl_ep_ctrl);
+ continue;
}
- /* Set FSM to focus on the first Control Read:
- * - Tip: Connection speed is known upon the first
- * setup request.*/
- scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
- set_idx_reg(dev->regs, SCRATCH, scratch);
+ if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
+ ep_sel == 18 || ep_sel == 20)
+ continue;
+
+ tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
+ BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
+ writel(tmp, &dev->plregs->pl_ep_cfg_4);
+
+ tmp = readl(&dev->plregs->pl_ep_ctrl) &
+ ~BIT(EP_INITIALIZED);
+ writel(tmp, &dev->plregs->pl_ep_ctrl);
- } else{
- ep_warn(dev, "Defect 7374 workaround soft will NOT operate");
- ep_warn(dev, "It will operate on cold-reboot and SS connect");
}
+
+ /* Set FSM to focus on the first Control Read:
+ * - Tip: Connection speed is known upon the first
+ * setup request.*/
+ scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
+ set_idx_reg(dev->regs, SCRATCH, scratch);
+
}
/* keeping it simple:
@@ -2033,21 +1880,13 @@ static void usb_reset_228x(struct net2280 *dev)
static void usb_reset_338x(struct net2280 *dev)
{
u32 tmp;
- u32 fsmvalue;
dev->gadget.speed = USB_SPEED_UNKNOWN;
(void)readl(&dev->usb->usbctl);
net2280_led_init(dev);
- fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
- (0xf << DEFECT7374_FSM_FIELD);
-
- /* See if firmware needs to set up for workaround: */
- if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
- ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__,
- fsmvalue);
- } else {
+ if (dev->bug7734_patched) {
/* disable automatic responses, and irqs */
writel(0, &dev->usb->stdrsp);
writel(0, &dev->regs->pciirqenb0);
@@ -2064,7 +1903,7 @@ static void usb_reset_338x(struct net2280 *dev)
writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1);
- if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
+ if (dev->bug7734_patched) {
/* reset, and enable pci */
tmp = readl(&dev->regs->devinit) |
BIT(PCI_ENABLE) |
@@ -2093,10 +1932,6 @@ static void usb_reset(struct net2280 *dev)
static void usb_reinit_228x(struct net2280 *dev)
{
u32 tmp;
- int init_dma;
-
- /* use_dma changes are ignored till next device re-init */
- init_dma = use_dma;
/* basic endpoint init */
for (tmp = 0; tmp < 7; tmp++) {
@@ -2108,8 +1943,7 @@ static void usb_reinit_228x(struct net2280 *dev)
if (tmp > 0 && tmp <= 4) {
ep->fifo_size = 1024;
- if (init_dma)
- ep->dma = &dev->dma[tmp - 1];
+ ep->dma = &dev->dma[tmp - 1];
} else
ep->fifo_size = 64;
ep->regs = &dev->epregs[tmp];
@@ -2133,17 +1967,12 @@ static void usb_reinit_228x(struct net2280 *dev)
static void usb_reinit_338x(struct net2280 *dev)
{
- int init_dma;
int i;
u32 tmp, val;
- u32 fsmvalue;
static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00,
0x00, 0xC0, 0x00, 0xC0 };
- /* use_dma changes are ignored till next device re-init */
- init_dma = use_dma;
-
/* basic endpoint init */
for (i = 0; i < dev->n_ep; i++) {
struct net2280_ep *ep = &dev->ep[i];
@@ -2152,7 +1981,7 @@ static void usb_reinit_338x(struct net2280 *dev)
ep->dev = dev;
ep->num = i;
- if (i > 0 && i <= 4 && init_dma)
+ if (i > 0 && i <= 4)
ep->dma = &dev->dma[i - 1];
if (dev->enhanced_mode) {
@@ -2177,14 +2006,7 @@ static void usb_reinit_338x(struct net2280 *dev)
dev->ep[0].stopped = 0;
/* Link layer set up */
- fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
- (0xf << DEFECT7374_FSM_FIELD);
-
- /* See if driver needs to set up for workaround: */
- if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
- ep_info(dev, "%s: Defect 7374 FsmValue %08x\n",
- __func__, fsmvalue);
- else {
+ if (dev->bug7734_patched) {
tmp = readl(&dev->usb_ext->usbctl2) &
~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE));
writel(tmp, &dev->usb_ext->usbctl2);
@@ -2291,15 +2113,8 @@ static void ep0_start_228x(struct net2280 *dev)
static void ep0_start_338x(struct net2280 *dev)
{
- u32 fsmvalue;
-
- fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
- (0xf << DEFECT7374_FSM_FIELD);
- if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
- ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__,
- fsmvalue);
- else
+ if (dev->bug7734_patched)
writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
BIT(SET_EP_HIDE_STATUS_PHASE),
&dev->epregs[0].ep_rsp);
@@ -2382,16 +2197,12 @@ static int net2280_start(struct usb_gadget *_gadget,
if (retval)
goto err_func;
- /* Enable force-full-speed testing mode, if desired */
- if (full_speed && (dev->quirks & PLX_LEGACY))
- writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag);
-
- /* ... then enable host detection and ep0; and we're ready
+ /* enable host detection and ep0; and we're ready
* for set_configuration as well as eventual disconnect.
*/
net2280_led_active(dev, 1);
- if (dev->quirks & PLX_SUPERSPEED)
+ if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
defect7374_enable_data_eps_zero(dev);
ep0_start(dev);
@@ -2444,10 +2255,6 @@ static int net2280_stop(struct usb_gadget *_gadget)
net2280_led_active(dev, 0);
- /* Disable full-speed test mode */
- if (dev->quirks & PLX_LEGACY)
- writel(0, &dev->usb->xcvrdiag);
-
device_remove_file(&dev->pdev->dev, &dev_attr_function);
device_remove_file(&dev->pdev->dev, &dev_attr_queues);
@@ -2478,10 +2285,10 @@ static void handle_ep_small(struct net2280_ep *ep)
/* ack all, and handle what we care about */
t = readl(&ep->regs->ep_stat);
ep->irqs++;
-#if 0
+
ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n",
- ep->ep.name, t, req ? &req->req : 0);
-#endif
+ ep->ep.name, t, req ? &req->req : NULL);
+
if (!ep->is_in || (ep->dev->quirks & PLX_2280))
writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat);
else
@@ -2717,6 +2524,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
* run after the next USB connection.
*/
scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ;
+ dev->bug7734_patched = 1;
goto restore_data_eps;
}
@@ -2730,6 +2538,7 @@ static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
if ((state >= (ACK_GOOD_NORMAL << STATE)) &&
(state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) {
scratch |= DEFECT7374_FSM_SS_CONTROL_READ;
+ dev->bug7734_patched = 1;
break;
}
@@ -2766,80 +2575,19 @@ restore_data_eps:
return;
}
-static void ep_stall(struct net2280_ep *ep, int stall)
+static void ep_clear_seqnum(struct net2280_ep *ep)
{
struct net2280 *dev = ep->dev;
u32 val;
static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 };
- if (stall) {
- writel(BIT(SET_ENDPOINT_HALT) |
- /* BIT(SET_NAK_PACKETS) | */
- BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
- &ep->regs->ep_rsp);
- ep->is_halt = 1;
- } else {
- if (dev->gadget.speed == USB_SPEED_SUPER) {
- /*
- * Workaround for SS SeqNum not cleared via
- * Endpoint Halt (Clear) bit. select endpoint
- */
- val = readl(&dev->plregs->pl_ep_ctrl);
- val = (val & ~0x1f) | ep_pl[ep->num];
- writel(val, &dev->plregs->pl_ep_ctrl);
-
- val |= BIT(SEQUENCE_NUMBER_RESET);
- writel(val, &dev->plregs->pl_ep_ctrl);
- }
- val = readl(&ep->regs->ep_rsp);
- val |= BIT(CLEAR_ENDPOINT_HALT) |
- BIT(CLEAR_ENDPOINT_TOGGLE);
- writel(val,
- /* | BIT(CLEAR_NAK_PACKETS),*/
- &ep->regs->ep_rsp);
- ep->is_halt = 0;
- val = readl(&ep->regs->ep_rsp);
- }
-}
-
-static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged)
-{
- /* set/clear, then synch memory views with the device */
- if (value) {
- ep->stopped = 1;
- if (ep->num == 0)
- ep->dev->protocol_stall = 1;
- else {
- if (ep->dma)
- ep_stop_dma(ep);
- ep_stall(ep, true);
- }
-
- if (wedged)
- ep->wedged = 1;
- } else {
- ep->stopped = 0;
- ep->wedged = 0;
-
- ep_stall(ep, false);
+ val = readl(&dev->plregs->pl_ep_ctrl) & ~0x1f;
+ val |= ep_pl[ep->num];
+ writel(val, &dev->plregs->pl_ep_ctrl);
+ val |= BIT(SEQUENCE_NUMBER_RESET);
+ writel(val, &dev->plregs->pl_ep_ctrl);
- /* Flush the queue */
- if (!list_empty(&ep->queue)) {
- struct net2280_request *req =
- list_entry(ep->queue.next, struct net2280_request,
- queue);
- if (ep->dma)
- resume_dma(ep);
- else {
- if (ep->is_in)
- write_fifo(ep, &req->req);
- else {
- if (read_fifo(ep, req))
- done(ep, req, 0);
- }
- }
- }
- }
+ return;
}
static void handle_stat0_irqs_superspeed(struct net2280 *dev,
@@ -2863,7 +2611,7 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev,
switch (r.bRequestType) {
case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
status = dev->wakeup_enable ? 0x02 : 0x00;
- if (dev->selfpowered)
+ if (dev->gadget.is_selfpowered)
status |= BIT(0);
status |= (dev->u1_enable << 2 | dev->u2_enable << 3 |
dev->ltm_enable << 4);
@@ -2940,7 +2688,12 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev,
if (w_value != USB_ENDPOINT_HALT)
goto do_stall3;
ep_vdbg(dev, "%s clear halt\n", e->ep.name);
- ep_stall(e, false);
+ /*
+ * Workaround for SS SeqNum not cleared via
+ * Endpoint Halt (Clear) bit. select endpoint
+ */
+ ep_clear_seqnum(e);
+ clear_halt(e);
if (!list_empty(&e->queue) && e->td_dma)
restart_dma(e);
allow_status(ep);
@@ -2998,7 +2751,14 @@ static void handle_stat0_irqs_superspeed(struct net2280 *dev,
e = get_ep_by_addr(dev, w_index);
if (!e || (w_value != USB_ENDPOINT_HALT))
goto do_stall3;
- ep_stdrsp(e, true, false);
+ ep->stopped = 1;
+ if (ep->num == 0)
+ ep->dev->protocol_stall = 1;
+ else {
+ if (ep->dma)
+ abort_dma(ep);
+ set_halt(ep);
+ }
allow_status_338x(ep);
break;
@@ -3026,7 +2786,7 @@ do_stall3:
r.bRequestType, r.bRequest, tmp);
dev->protocol_stall = 1;
/* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */
- ep_stall(ep, true);
+ set_halt(ep);
}
next_endpoints3:
@@ -3091,9 +2851,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
}
ep->stopped = 0;
dev->protocol_stall = 0;
- if (dev->quirks & PLX_SUPERSPEED)
- ep->is_halt = 0;
- else{
+ if (!(dev->quirks & PLX_SUPERSPEED)) {
if (ep->dev->quirks & PLX_2280)
tmp = BIT(FIFO_OVERFLOW) |
BIT(FIFO_UNDERFLOW);
@@ -3120,7 +2878,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
cpu_to_le32s(&u.raw[0]);
cpu_to_le32s(&u.raw[1]);
- if (dev->quirks & PLX_SUPERSPEED)
+ if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
defect7374_workaround(dev, u.r);
tmp = 0;
@@ -3423,17 +3181,12 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
continue;
}
- /* chaining should stop on abort, short OUT from fifo,
- * or (stat0 codepath) short OUT transfer.
- */
- if (!use_dma_chaining) {
- if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) {
- ep_dbg(ep->dev, "%s no xact done? %08x\n",
- ep->ep.name, tmp);
- continue;
- }
- stop_dma(ep->dma);
+ if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) {
+ ep_dbg(ep->dev, "%s no xact done? %08x\n",
+ ep->ep.name, tmp);
+ continue;
}
+ stop_dma(ep->dma);
/* OUT transfers terminate when the data from the
* host is in our memory. Process whatever's done.
@@ -3448,30 +3201,9 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
scan_dma_completions(ep);
/* disable dma on inactive queues; else maybe restart */
- if (list_empty(&ep->queue)) {
- if (use_dma_chaining)
- stop_dma(ep->dma);
- } else {
+ if (!list_empty(&ep->queue)) {
tmp = readl(&dma->dmactl);
- if (!use_dma_chaining || (tmp & BIT(DMA_ENABLE)) == 0)
- restart_dma(ep);
- else if (ep->is_in && use_dma_chaining) {
- struct net2280_request *req;
- __le32 dmacount;
-
- /* the descriptor at the head of the chain
- * may still have VALID_BIT clear; that's
- * used to trigger changing DMA_FIFO_VALIDATE
- * (affects automagic zlp writes).
- */
- req = list_entry(ep->queue.next,
- struct net2280_request, queue);
- dmacount = req->td->dmacount;
- dmacount &= cpu_to_le32(BIT(VALID_BIT) |
- DMA_BYTE_COUNT_MASK);
- if (dmacount && (dmacount & valid_bit) == 0)
- restart_dma(ep);
- }
+ restart_dma(ep);
}
ep->irqs++;
}
@@ -3556,7 +3288,7 @@ static void net2280_remove(struct pci_dev *pdev)
}
if (dev->got_irq)
free_irq(pdev->irq, dev);
- if (use_msi && dev->quirks & PLX_SUPERSPEED)
+ if (dev->quirks & PLX_SUPERSPEED)
pci_disable_msi(pdev);
if (dev->regs)
iounmap(dev->regs);
@@ -3581,9 +3313,6 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
void __iomem *base = NULL;
int retval, i;
- if (!use_dma)
- use_dma_chaining = 0;
-
/* alloc, and start init */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
@@ -3663,9 +3392,12 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
(0xf << DEFECT7374_FSM_FIELD);
/* See if firmware needs to set up for workaround: */
- if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ)
+ if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
+ dev->bug7734_patched = 1;
writel(0, &dev->usb->usbctl);
- } else{
+ } else
+ dev->bug7734_patched = 0;
+ } else {
dev->enhanced_mode = 0;
dev->n_ep = 7;
/* put into initial config, link up all endpoints */
@@ -3682,7 +3414,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto done;
}
- if (use_msi && (dev->quirks & PLX_SUPERSPEED))
+ if (dev->quirks & PLX_SUPERSPEED)
if (pci_enable_msi(pdev))
ep_err(dev, "Failed to enable MSI mode\n");
@@ -3741,9 +3473,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ep_info(dev, "%s\n", driver_desc);
ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n",
pdev->irq, base, dev->chiprev);
- ep_info(dev, "version: " DRIVER_VERSION "; dma %s %s\n",
- use_dma ? (use_dma_chaining ? "chaining" : "enabled")
- : "disabled",
+ ep_info(dev, "version: " DRIVER_VERSION "; %s\n",
dev->enhanced_mode ? "enhanced mode" : "legacy mode");
retval = device_create_file(&pdev->dev, &dev_attr_registers);
if (retval)
@@ -3776,9 +3506,6 @@ static void net2280_shutdown(struct pci_dev *pdev)
/* disable the pullup so the host will think we're gone */
writel(0, &dev->usb->usbctl);
- /* Disable full-speed test mode */
- if (dev->quirks & PLX_LEGACY)
- writel(0, &dev->usb->xcvrdiag);
}
diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h
index 03f15242d794..ac8d5a20a378 100644
--- a/drivers/usb/gadget/udc/net2280.h
+++ b/drivers/usb/gadget/udc/net2280.h
@@ -100,7 +100,6 @@ struct net2280_ep {
dma_addr_t td_dma; /* of dummy */
struct net2280 *dev;
unsigned long irqs;
- unsigned is_halt:1, dma_started:1;
/* analogous to a host-side qh */
struct list_head queue;
@@ -126,7 +125,7 @@ static inline void allow_status(struct net2280_ep *ep)
ep->stopped = 1;
}
-static void allow_status_338x(struct net2280_ep *ep)
+static inline void allow_status_338x(struct net2280_ep *ep)
{
/*
* Control Status Phase Handshake was set by the chip when the setup
@@ -165,8 +164,8 @@ struct net2280 {
u2_enable:1,
ltm_enable:1,
wakeup_enable:1,
- selfpowered:1,
- addressed_state:1;
+ addressed_state:1,
+ bug7734_patched:1;
u16 chiprev;
int enhanced_mode;
int n_ep;
@@ -356,23 +355,6 @@ static inline void start_out_naking(struct net2280_ep *ep)
readl(&ep->regs->ep_rsp);
}
-#ifdef DEBUG
-static inline void assert_out_naking(struct net2280_ep *ep, const char *where)
-{
- u32 tmp = readl(&ep->regs->ep_stat);
-
- if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) {
- ep_dbg(ep->dev, "%s %s %08x !NAK\n",
- ep->ep.name, where, tmp);
- writel(BIT(SET_NAK_OUT_PACKETS),
- &ep->regs->ep_rsp);
- }
-}
-#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep, __func__)
-#else
-#define ASSERT_OUT_NAKING(ep) do {} while (0)
-#endif
-
static inline void stop_out_naking(struct net2280_ep *ep)
{
u32 tmp;
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
index 288c087220a8..e2fcdb8e5596 100644
--- a/drivers/usb/gadget/udc/omap_udc.c
+++ b/drivers/usb/gadget/udc/omap_udc.c
@@ -1171,6 +1171,7 @@ omap_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered)
unsigned long flags;
u16 syscon1;
+ gadget->is_selfpowered = (is_selfpowered != 0);
udc = container_of(gadget, struct omap_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
syscon1 = omap_readw(UDC_SYSCON1);
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c
index 1c7379ac2379..613547f07828 100644
--- a/drivers/usb/gadget/udc/pch_udc.c
+++ b/drivers/usb/gadget/udc/pch_udc.c
@@ -1161,6 +1161,7 @@ static int pch_udc_pcd_selfpowered(struct usb_gadget *gadget, int value)
if (!gadget)
return -EINVAL;
+ gadget->is_selfpowered = (value != 0);
dev = container_of(gadget, struct pch_udc_dev, gadget);
if (value)
pch_udc_set_selfpowered(dev);
diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c
index 8550b2d5db32..f6cbe667ce39 100644
--- a/drivers/usb/gadget/udc/pxa25x_udc.c
+++ b/drivers/usb/gadget/udc/pxa25x_udc.c
@@ -1272,7 +1272,6 @@ static int pxa25x_udc_start(struct usb_gadget *g,
goto bind_fail;
}
- pullup(dev);
dump_state(dev);
return 0;
bind_fail:
@@ -1339,7 +1338,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g)
local_irq_disable();
dev->pullup = 0;
- pullup(dev);
stop_activity(dev, NULL);
local_irq_enable();
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c
index c61a896061fa..6a855fc9bd84 100644
--- a/drivers/usb/gadget/udc/pxa27x_udc.c
+++ b/drivers/usb/gadget/udc/pxa27x_udc.c
@@ -1809,7 +1809,6 @@ static int pxa27x_udc_start(struct usb_gadget *g,
/* first hook up the driver ... */
udc->driver = driver;
- dplus_pullup(udc, 1);
if (!IS_ERR_OR_NULL(udc->transceiver)) {
retval = otg_set_peripheral(udc->transceiver->otg,
@@ -1862,7 +1861,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g)
stop_activity(udc, NULL);
udc_disable(udc);
- dplus_pullup(udc, 0);
udc->driver = NULL;
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c
index 06870da0b988..2495fe9c95c5 100644
--- a/drivers/usb/gadget/udc/r8a66597-udc.c
+++ b/drivers/usb/gadget/udc/r8a66597-udc.c
@@ -1803,6 +1803,7 @@ static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self)
{
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
+ gadget->is_selfpowered = (is_self != 0);
if (is_self)
r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED;
else
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c
index 824cf12e9add..b808951491cc 100644
--- a/drivers/usb/gadget/udc/s3c2410_udc.c
+++ b/drivers/usb/gadget/udc/s3c2410_udc.c
@@ -238,14 +238,6 @@ static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base)
S3C2410_UDC_EP0_CSR_REG);
}
-static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base)
-{
- udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
- udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY
- | S3C2410_UDC_EP0_CSR_SSE),
- S3C2410_UDC_EP0_CSR_REG);
-}
-
static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
@@ -291,18 +283,6 @@ static void s3c2410_udc_nuke(struct s3c2410_udc *udc,
}
}
-static inline void s3c2410_udc_clear_ep_state(struct s3c2410_udc *dev)
-{
- unsigned i;
-
- /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
- * fifos, and pending transactions mustn't be continued in any case.
- */
-
- for (i = 1; i < S3C2410_ENDPOINTS; i++)
- s3c2410_udc_nuke(dev, &dev->ep[i], -ECONNABORTED);
-}
-
static inline int s3c2410_udc_fifo_count_out(void)
{
int tmp;
@@ -1454,6 +1434,7 @@ static int s3c2410_udc_set_selfpowered(struct usb_gadget *gadget, int value)
dprintk(DEBUG_NORMAL, "%s()\n", __func__);
+ gadget->is_selfpowered = (value != 0);
if (value)
udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
else
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index e31d574d8860..5a81cb086b99 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -564,6 +564,7 @@ static USB_UDC_ATTR(is_a_peripheral);
static USB_UDC_ATTR(b_hnp_enable);
static USB_UDC_ATTR(a_hnp_support);
static USB_UDC_ATTR(a_alt_hnp_support);
+static USB_UDC_ATTR(is_selfpowered);
static struct attribute *usb_udc_attrs[] = {
&dev_attr_srp.attr,
@@ -577,6 +578,7 @@ static struct attribute *usb_udc_attrs[] = {
&dev_attr_b_hnp_enable.attr,
&dev_attr_a_hnp_support.attr,
&dev_attr_a_alt_hnp_support.attr,
+ &dev_attr_is_selfpowered.attr,
NULL,
};
diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c
index 1eac56fc384d..dd3e9fd31b80 100644
--- a/drivers/usb/gadget/udc/udc-xilinx.c
+++ b/drivers/usb/gadget/udc/udc-xilinx.c
@@ -2131,8 +2131,8 @@ static int xudc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, udc);
- dev_vdbg(&pdev->dev, "%s at 0x%08X mapped to 0x%08X %s\n",
- driver_name, (u32)res->start, (u32 __force)udc->addr,
+ dev_vdbg(&pdev->dev, "%s at 0x%08X mapped to %p %s\n",
+ driver_name, (u32)res->start, udc->addr,
udc->dma_enabled ? "with DMA" : "without DMA");
return 0;