Merge tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg KH: "Here's the big pull request for the USB driver tree for 3.20-rc1. Nothing major happening here, just lots of gadget driver updates, new device ids, and a bunch of cleanups. All of these have been in linux-next for a while with no reported issues" * tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (299 commits) usb: musb: fix device hotplug behind hub usb: dwc2: Fix a bug in reading the endpoint directions from reg. staging: emxx_udc: fix the build error usb: Retry port status check on resume to work around RH bugs Revert "usb: Reset USB-3 devices on USB-3 link bounce" uhci-hub: use HUB_CHAR_* usb: kconfig: replace PPC_OF with PPC ehci-pci: disable for Intel MID platforms (update) usb: gadget: Kconfig: use bool instead of boolean usb: musb: blackfin: remove incorrect __exit_p() USB: fix use-after-free bug in usb_hcd_unlink_urb() ehci-pci: disable for Intel MID platforms usb: host: pci_quirks: joing string literals USB: add flag for HCDs that can't receive wakeup requests (isp1760-hcd) USB: usbfs: allow URBs to be reaped after disconnection cdc-acm: kill unnecessary messages cdc-acm: add sanity checks usb: phy: phy-generic: Fix USB PHY gpio reset usb: dwc2: fix USB core dependencies usb: renesas_usbhs: fix NULL pointer dereference in dma_release_channel() ...
This commit is contained in:
@@ -176,7 +176,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)");
|
||||
|
||||
@@ -1000,7 +1000,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 +1149,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");
|
||||
@@ -1653,7 +1653,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;
|
||||
}
|
||||
|
@@ -122,7 +122,6 @@ 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;
|
||||
|
@@ -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>
|
||||
@@ -315,6 +316,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 +336,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 +608,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 +623,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 +659,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 +989,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 +1624,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 +1649,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 +1693,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 +1719,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 +1753,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 +1805,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 +1828,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 +1840,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 +1882,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 +2083,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 +2092,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 +2153,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 = {
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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");
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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! */
|
||||
|
@@ -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,
|
||||
|
@@ -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");
|
||||
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));
|
||||
/*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);
|
||||
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);
|
||||
/* 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);
|
||||
/*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;
|
||||
}
|
||||
|
||||
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);
|
||||
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 = 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);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user