aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiebingLi <jiebing.li@intel.com>2010-08-05 09:18:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:21:18 -0400
commit513b91b688f527766bfe335d1ffd145257ad1624 (patch)
treede2ee7aeb2a4fa62f27ec09d4d6213b654461d5a /drivers
parent3eed298ffa94d77901cfda269c4368de83d133fb (diff)
USB: langwell: USB Client PHY low power mode setting
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/langwell_udc.c92
1 files changed, 60 insertions, 32 deletions
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index 599ad8a1f5fe..8b92e2208dad 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -1159,11 +1159,37 @@ static int langwell_get_frame(struct usb_gadget *_gadget)
1159} 1159}
1160 1160
1161 1161
1162/* enter or exit PHY low power state */
1163static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
1164{
1165 u32 devlc;
1166 u8 devlc_byte2;
1167 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
1168
1169 devlc = readl(&dev->op_regs->devlc);
1170 dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
1171
1172 if (flag)
1173 devlc |= LPM_PHCD;
1174 else
1175 devlc &= ~LPM_PHCD;
1176
1177 /* FIXME: workaround for Langwell A1/A2/A3 sighting */
1178 devlc_byte2 = (devlc >> 16) & 0xff;
1179 writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
1180
1181 devlc = readl(&dev->op_regs->devlc);
1182 dev_vdbg(&dev->pdev->dev,
1183 "%s PHY low power suspend, devlc = 0x%08x\n",
1184 flag ? "enter" : "exit", devlc);
1185}
1186
1187
1162/* tries to wake up the host connected to this gadget */ 1188/* tries to wake up the host connected to this gadget */
1163static int langwell_wakeup(struct usb_gadget *_gadget) 1189static int langwell_wakeup(struct usb_gadget *_gadget)
1164{ 1190{
1165 struct langwell_udc *dev; 1191 struct langwell_udc *dev;
1166 u32 portsc1, devlc; 1192 u32 portsc1;
1167 unsigned long flags; 1193 unsigned long flags;
1168 1194
1169 if (!_gadget) 1195 if (!_gadget)
@@ -1186,22 +1212,19 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
1186 return 0; 1212 return 0;
1187 } 1213 }
1188 1214
1189 /* LPM L1 to L0, remote wakeup */ 1215 /* LPM L1 to L0 or legacy remote wakeup */
1190 if (dev->lpm && dev->lpm_state == LPM_L1) { 1216 if (dev->lpm && dev->lpm_state == LPM_L1)
1191 portsc1 |= PORTS_SLP; 1217 dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
1192 writel(portsc1, &dev->op_regs->portsc1); 1218 else
1193 } 1219 dev_info(&dev->pdev->dev, "device remote wakeup\n");
1194
1195 /* force port resume */
1196 if (dev->usb_state == USB_STATE_SUSPENDED) {
1197 portsc1 |= PORTS_FPR;
1198 writel(portsc1, &dev->op_regs->portsc1);
1199 }
1200 1220
1201 /* exit PHY low power suspend */ 1221 /* exit PHY low power suspend */
1202 devlc = readl(&dev->op_regs->devlc); 1222 if (dev->pdev->device != 0x0829)
1203 devlc &= ~LPM_PHCD; 1223 langwell_phy_low_power(dev, 0);
1204 writel(devlc, &dev->op_regs->devlc); 1224
1225 /* force port resume */
1226 portsc1 |= PORTS_FPR;
1227 writel(portsc1, &dev->op_regs->portsc1);
1205 1228
1206 spin_unlock_irqrestore(&dev->lock, flags); 1229 spin_unlock_irqrestore(&dev->lock, flags);
1207 1230
@@ -1331,6 +1354,7 @@ static const struct usb_gadget_ops langwell_ops = {
1331static int langwell_udc_reset(struct langwell_udc *dev) 1354static int langwell_udc_reset(struct langwell_udc *dev)
1332{ 1355{
1333 u32 usbcmd, usbmode, devlc, endpointlistaddr; 1356 u32 usbcmd, usbmode, devlc, endpointlistaddr;
1357 u8 devlc_byte0, devlc_byte2;
1334 unsigned long timeout; 1358 unsigned long timeout;
1335 1359
1336 if (!dev) 1360 if (!dev)
@@ -1375,9 +1399,17 @@ static int langwell_udc_reset(struct langwell_udc *dev)
1375 /* if support USB LPM, ACK all LPM token */ 1399 /* if support USB LPM, ACK all LPM token */
1376 if (dev->lpm) { 1400 if (dev->lpm) {
1377 devlc = readl(&dev->op_regs->devlc); 1401 devlc = readl(&dev->op_regs->devlc);
1402 dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
1403 /* FIXME: workaround for Langwell A1/A2/A3 sighting */
1378 devlc &= ~LPM_STL; /* don't STALL LPM token */ 1404 devlc &= ~LPM_STL; /* don't STALL LPM token */
1379 devlc &= ~LPM_NYT_ACK; /* ACK LPM token */ 1405 devlc &= ~LPM_NYT_ACK; /* ACK LPM token */
1380 writel(devlc, &dev->op_regs->devlc); 1406 devlc_byte0 = devlc & 0xff;
1407 devlc_byte2 = (devlc >> 16) & 0xff;
1408 writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
1409 writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
1410 devlc = readl(&dev->op_regs->devlc);
1411 dev_vdbg(&dev->pdev->dev,
1412 "ACK LPM token, devlc = 0x%08x\n", devlc);
1381 } 1413 }
1382 1414
1383 /* fill endpointlistaddr register */ 1415 /* fill endpointlistaddr register */
@@ -1871,6 +1903,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1871 if (unlikely(!driver || !driver->bind || !driver->unbind)) 1903 if (unlikely(!driver || !driver->bind || !driver->unbind))
1872 return -EINVAL; 1904 return -EINVAL;
1873 1905
1906 /* exit PHY low power suspend */
1907 if (dev->pdev->device != 0x0829)
1908 langwell_phy_low_power(dev, 0);
1909
1874 /* unbind OTG transceiver */ 1910 /* unbind OTG transceiver */
1875 if (dev->transceiver) 1911 if (dev->transceiver)
1876 (void)otg_set_peripheral(dev->transceiver, 0); 1912 (void)otg_set_peripheral(dev->transceiver, 0);
@@ -2706,7 +2742,6 @@ static void handle_usb_reset(struct langwell_udc *dev)
2706/* USB bus suspend/resume interrupt */ 2742/* USB bus suspend/resume interrupt */
2707static void handle_bus_suspend(struct langwell_udc *dev) 2743static void handle_bus_suspend(struct langwell_udc *dev)
2708{ 2744{
2709 u32 devlc;
2710 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); 2745 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
2711 2746
2712 dev->resume_state = dev->usb_state; 2747 dev->resume_state = dev->usb_state;
@@ -2747,9 +2782,8 @@ static void handle_bus_suspend(struct langwell_udc *dev)
2747 } 2782 }
2748 2783
2749 /* enter PHY low power suspend */ 2784 /* enter PHY low power suspend */
2750 devlc = readl(&dev->op_regs->devlc); 2785 if (dev->pdev->device != 0x0829)
2751 devlc |= LPM_PHCD; 2786 langwell_phy_low_power(dev, 0);
2752 writel(devlc, &dev->op_regs->devlc);
2753 2787
2754 dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); 2788 dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
2755} 2789}
@@ -2757,16 +2791,14 @@ static void handle_bus_suspend(struct langwell_udc *dev)
2757 2791
2758static void handle_bus_resume(struct langwell_udc *dev) 2792static void handle_bus_resume(struct langwell_udc *dev)
2759{ 2793{
2760 u32 devlc;
2761 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); 2794 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
2762 2795
2763 dev->usb_state = dev->resume_state; 2796 dev->usb_state = dev->resume_state;
2764 dev->resume_state = 0; 2797 dev->resume_state = 0;
2765 2798
2766 /* exit PHY low power suspend */ 2799 /* exit PHY low power suspend */
2767 devlc = readl(&dev->op_regs->devlc); 2800 if (dev->pdev->device != 0x0829)
2768 devlc &= ~LPM_PHCD; 2801 langwell_phy_low_power(dev, 0);
2769 writel(devlc, &dev->op_regs->devlc);
2770 2802
2771#ifdef OTG_TRANSCEIVER 2803#ifdef OTG_TRANSCEIVER
2772 if (dev->lotg->otg.default_a == 0) 2804 if (dev->lotg->otg.default_a == 0)
@@ -3232,7 +3264,6 @@ error:
3232static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) 3264static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
3233{ 3265{
3234 struct langwell_udc *dev = the_controller; 3266 struct langwell_udc *dev = the_controller;
3235 u32 devlc;
3236 3267
3237 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); 3268 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
3238 3269
@@ -3251,9 +3282,8 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
3251 pci_set_power_state(pdev, PCI_D3hot); 3282 pci_set_power_state(pdev, PCI_D3hot);
3252 3283
3253 /* enter PHY low power suspend */ 3284 /* enter PHY low power suspend */
3254 devlc = readl(&dev->op_regs->devlc); 3285 if (dev->pdev->device != 0x0829)
3255 devlc |= LPM_PHCD; 3286 langwell_phy_low_power(dev, 1);
3256 writel(devlc, &dev->op_regs->devlc);
3257 3287
3258 dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); 3288 dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
3259 return 0; 3289 return 0;
@@ -3264,14 +3294,12 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
3264static int langwell_udc_resume(struct pci_dev *pdev) 3294static int langwell_udc_resume(struct pci_dev *pdev)
3265{ 3295{
3266 struct langwell_udc *dev = the_controller; 3296 struct langwell_udc *dev = the_controller;
3267 u32 devlc;
3268 3297
3269 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); 3298 dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
3270 3299
3271 /* exit PHY low power suspend */ 3300 /* exit PHY low power suspend */
3272 devlc = readl(&dev->op_regs->devlc); 3301 if (dev->pdev->device != 0x0829)
3273 devlc &= ~LPM_PHCD; 3302 langwell_phy_low_power(dev, 0);
3274 writel(devlc, &dev->op_regs->devlc);
3275 3303
3276 /* set device D0 power state */ 3304 /* set device D0 power state */
3277 pci_set_power_state(pdev, PCI_D0); 3305 pci_set_power_state(pdev, PCI_D0);