Skip to content

Commit

Permalink
USB: langwell: USB Client PHY low power mode setting
Browse files Browse the repository at this point in the history
PHY low power mode setting with a static function

Signed-off-by: JiebingLi <jiebing.li@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
JiebingLi authored and Greg Kroah-Hartman committed Oct 22, 2010
1 parent 3eed298 commit 513b91b
Showing 1 changed file with 60 additions and 32 deletions.
92 changes: 60 additions & 32 deletions 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 513b91b

Please sign in to comment.