Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213532
b: refs/heads/master
c: 513b91b
h: refs/heads/master
v: v3
  • Loading branch information
JiebingLi authored and Greg Kroah-Hartman committed Oct 22, 2010
1 parent 6ab99c5 commit d6ebe90
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3eed298ffa94d77901cfda269c4368de83d133fb
refs/heads/master: 513b91b688f527766bfe335d1ffd145257ad1624
92 changes: 60 additions & 32 deletions trunk/drivers/usb/gadget/langwell_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,11 +1159,37 @@ static int langwell_get_frame(struct usb_gadget *_gadget)
}


/* enter or exit PHY low power state */
static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
{
u32 devlc;
u8 devlc_byte2;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);

devlc = readl(&dev->op_regs->devlc);
dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);

if (flag)
devlc |= LPM_PHCD;
else
devlc &= ~LPM_PHCD;

/* FIXME: workaround for Langwell A1/A2/A3 sighting */
devlc_byte2 = (devlc >> 16) & 0xff;
writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);

devlc = readl(&dev->op_regs->devlc);
dev_vdbg(&dev->pdev->dev,
"%s PHY low power suspend, devlc = 0x%08x\n",
flag ? "enter" : "exit", devlc);
}


/* tries to wake up the host connected to this gadget */
static int langwell_wakeup(struct usb_gadget *_gadget)
{
struct langwell_udc *dev;
u32 portsc1, devlc;
u32 portsc1;
unsigned long flags;

if (!_gadget)
Expand All @@ -1186,22 +1212,19 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
return 0;
}

/* LPM L1 to L0, remote wakeup */
if (dev->lpm && dev->lpm_state == LPM_L1) {
portsc1 |= PORTS_SLP;
writel(portsc1, &dev->op_regs->portsc1);
}

/* force port resume */
if (dev->usb_state == USB_STATE_SUSPENDED) {
portsc1 |= PORTS_FPR;
writel(portsc1, &dev->op_regs->portsc1);
}
/* LPM L1 to L0 or legacy remote wakeup */
if (dev->lpm && dev->lpm_state == LPM_L1)
dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
else
dev_info(&dev->pdev->dev, "device remote wakeup\n");

/* exit PHY low power suspend */
devlc = readl(&dev->op_regs->devlc);
devlc &= ~LPM_PHCD;
writel(devlc, &dev->op_regs->devlc);
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 0);

/* force port resume */
portsc1 |= PORTS_FPR;
writel(portsc1, &dev->op_regs->portsc1);

spin_unlock_irqrestore(&dev->lock, flags);

Expand Down Expand Up @@ -1331,6 +1354,7 @@ static const struct usb_gadget_ops langwell_ops = {
static int langwell_udc_reset(struct langwell_udc *dev)
{
u32 usbcmd, usbmode, devlc, endpointlistaddr;
u8 devlc_byte0, devlc_byte2;
unsigned long timeout;

if (!dev)
Expand Down Expand Up @@ -1375,9 +1399,17 @@ static int langwell_udc_reset(struct langwell_udc *dev)
/* if support USB LPM, ACK all LPM token */
if (dev->lpm) {
devlc = readl(&dev->op_regs->devlc);
dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
/* FIXME: workaround for Langwell A1/A2/A3 sighting */
devlc &= ~LPM_STL; /* don't STALL LPM token */
devlc &= ~LPM_NYT_ACK; /* ACK LPM token */
writel(devlc, &dev->op_regs->devlc);
devlc_byte0 = devlc & 0xff;
devlc_byte2 = (devlc >> 16) & 0xff;
writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
devlc = readl(&dev->op_regs->devlc);
dev_vdbg(&dev->pdev->dev,
"ACK LPM token, devlc = 0x%08x\n", devlc);
}

/* fill endpointlistaddr register */
Expand Down Expand Up @@ -1871,6 +1903,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (unlikely(!driver || !driver->bind || !driver->unbind))
return -EINVAL;

/* exit PHY low power suspend */
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 0);

/* unbind OTG transceiver */
if (dev->transceiver)
(void)otg_set_peripheral(dev->transceiver, 0);
Expand Down Expand Up @@ -2706,7 +2742,6 @@ static void handle_usb_reset(struct langwell_udc *dev)
/* USB bus suspend/resume interrupt */
static void handle_bus_suspend(struct langwell_udc *dev)
{
u32 devlc;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);

dev->resume_state = dev->usb_state;
Expand Down Expand Up @@ -2747,26 +2782,23 @@ static void handle_bus_suspend(struct langwell_udc *dev)
}

/* enter PHY low power suspend */
devlc = readl(&dev->op_regs->devlc);
devlc |= LPM_PHCD;
writel(devlc, &dev->op_regs->devlc);
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 0);

dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}


static void handle_bus_resume(struct langwell_udc *dev)
{
u32 devlc;
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);

dev->usb_state = dev->resume_state;
dev->resume_state = 0;

/* exit PHY low power suspend */
devlc = readl(&dev->op_regs->devlc);
devlc &= ~LPM_PHCD;
writel(devlc, &dev->op_regs->devlc);
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 0);

#ifdef OTG_TRANSCEIVER
if (dev->lotg->otg.default_a == 0)
Expand Down Expand Up @@ -3232,7 +3264,6 @@ static int langwell_udc_probe(struct pci_dev *pdev,
static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct langwell_udc *dev = the_controller;
u32 devlc;

dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);

Expand All @@ -3251,9 +3282,8 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
pci_set_power_state(pdev, PCI_D3hot);

/* enter PHY low power suspend */
devlc = readl(&dev->op_regs->devlc);
devlc |= LPM_PHCD;
writel(devlc, &dev->op_regs->devlc);
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 1);

dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
Expand All @@ -3264,14 +3294,12 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
static int langwell_udc_resume(struct pci_dev *pdev)
{
struct langwell_udc *dev = the_controller;
u32 devlc;

dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);

/* exit PHY low power suspend */
devlc = readl(&dev->op_regs->devlc);
devlc &= ~LPM_PHCD;
writel(devlc, &dev->op_regs->devlc);
if (dev->pdev->device != 0x0829)
langwell_phy_low_power(dev, 0);

/* set device D0 power state */
pci_set_power_state(pdev, PCI_D0);
Expand Down

0 comments on commit d6ebe90

Please sign in to comment.