Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2001-2004 by David Brownell
0004  */
0005 
0006 /* this file is part of ehci-hcd.c */
0007 
0008 /*-------------------------------------------------------------------------*/
0009 
0010 /*
0011  * EHCI Root Hub ... the nonsharable stuff
0012  *
0013  * Registers don't need cpu_to_le32, that happens transparently
0014  */
0015 
0016 /*-------------------------------------------------------------------------*/
0017 
0018 #define PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
0019 
0020 #ifdef  CONFIG_PM
0021 
0022 static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
0023 
0024 static int persist_enabled_on_companion(struct usb_device *udev, void *unused)
0025 {
0026     return !udev->maxchild && udev->persist_enabled &&
0027         udev->bus->root_hub->speed < USB_SPEED_HIGH;
0028 }
0029 
0030 /* After a power loss, ports that were owned by the companion must be
0031  * reset so that the companion can still own them.
0032  */
0033 static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
0034 {
0035     u32 __iomem *reg;
0036     u32     status;
0037     int     port;
0038     __le32      buf;
0039     struct usb_hcd  *hcd = ehci_to_hcd(ehci);
0040 
0041     if (!ehci->owned_ports)
0042         return;
0043 
0044     /*
0045      * USB 1.1 devices are mostly HIDs, which don't need to persist across
0046      * suspends. If we ensure that none of our companion's devices have
0047      * persist_enabled (by looking through all USB 1.1 buses in the system),
0048      * we can skip this and avoid slowing resume down. Devices without
0049      * persist will just get reenumerated shortly after resume anyway.
0050      */
0051     if (!usb_for_each_dev(NULL, persist_enabled_on_companion))
0052         return;
0053 
0054     /* Make sure the ports are powered */
0055     port = HCS_N_PORTS(ehci->hcs_params);
0056     while (port--) {
0057         if (test_bit(port, &ehci->owned_ports)) {
0058             reg = &ehci->regs->port_status[port];
0059             status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
0060             if (!(status & PORT_POWER))
0061                 ehci_port_power(ehci, port, true);
0062         }
0063     }
0064 
0065     /* Give the connections some time to appear */
0066     msleep(20);
0067 
0068     spin_lock_irq(&ehci->lock);
0069     port = HCS_N_PORTS(ehci->hcs_params);
0070     while (port--) {
0071         if (test_bit(port, &ehci->owned_ports)) {
0072             reg = &ehci->regs->port_status[port];
0073             status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
0074 
0075             /* Port already owned by companion? */
0076             if (status & PORT_OWNER)
0077                 clear_bit(port, &ehci->owned_ports);
0078             else if (test_bit(port, &ehci->companion_ports))
0079                 ehci_writel(ehci, status & ~PORT_PE, reg);
0080             else {
0081                 spin_unlock_irq(&ehci->lock);
0082                 ehci_hub_control(hcd, SetPortFeature,
0083                         USB_PORT_FEAT_RESET, port + 1,
0084                         NULL, 0);
0085                 spin_lock_irq(&ehci->lock);
0086             }
0087         }
0088     }
0089     spin_unlock_irq(&ehci->lock);
0090 
0091     if (!ehci->owned_ports)
0092         return;
0093     msleep(90);     /* Wait for resets to complete */
0094 
0095     spin_lock_irq(&ehci->lock);
0096     port = HCS_N_PORTS(ehci->hcs_params);
0097     while (port--) {
0098         if (test_bit(port, &ehci->owned_ports)) {
0099             spin_unlock_irq(&ehci->lock);
0100             ehci_hub_control(hcd, GetPortStatus,
0101                     0, port + 1,
0102                     (char *) &buf, sizeof(buf));
0103             spin_lock_irq(&ehci->lock);
0104 
0105             /* The companion should now own the port,
0106              * but if something went wrong the port must not
0107              * remain enabled.
0108              */
0109             reg = &ehci->regs->port_status[port];
0110             status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
0111             if (status & PORT_OWNER)
0112                 ehci_writel(ehci, status | PORT_CSC, reg);
0113             else {
0114                 ehci_dbg(ehci, "failed handover port %d: %x\n",
0115                         port + 1, status);
0116                 ehci_writel(ehci, status & ~PORT_PE, reg);
0117             }
0118         }
0119     }
0120 
0121     ehci->owned_ports = 0;
0122     spin_unlock_irq(&ehci->lock);
0123 }
0124 
0125 static int ehci_port_change(struct ehci_hcd *ehci)
0126 {
0127     int i = HCS_N_PORTS(ehci->hcs_params);
0128 
0129     /* First check if the controller indicates a change event */
0130 
0131     if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)
0132         return 1;
0133 
0134     /*
0135      * Not all controllers appear to update this while going from D3 to D0,
0136      * so check the individual port status registers as well
0137      */
0138 
0139     while (i--)
0140         if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC)
0141             return 1;
0142 
0143     return 0;
0144 }
0145 
0146 void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
0147         bool suspending, bool do_wakeup)
0148 {
0149     int     port;
0150     u32     temp;
0151 
0152     /* If remote wakeup is enabled for the root hub but disabled
0153      * for the controller, we must adjust all the port wakeup flags
0154      * when the controller is suspended or resumed.  In all other
0155      * cases they don't need to be changed.
0156      */
0157     if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
0158         return;
0159 
0160     spin_lock_irq(&ehci->lock);
0161 
0162     /* clear phy low-power mode before changing wakeup flags */
0163     if (ehci->has_tdi_phy_lpm) {
0164         port = HCS_N_PORTS(ehci->hcs_params);
0165         while (port--) {
0166             u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
0167 
0168             temp = ehci_readl(ehci, hostpc_reg);
0169             ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
0170         }
0171         spin_unlock_irq(&ehci->lock);
0172         msleep(5);
0173         spin_lock_irq(&ehci->lock);
0174     }
0175 
0176     port = HCS_N_PORTS(ehci->hcs_params);
0177     while (port--) {
0178         u32 __iomem *reg = &ehci->regs->port_status[port];
0179         u32     t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
0180         u32     t2 = t1 & ~PORT_WAKE_BITS;
0181 
0182         /* If we are suspending the controller, clear the flags.
0183          * If we are resuming the controller, set the wakeup flags.
0184          */
0185         if (!suspending) {
0186             if (t1 & PORT_CONNECT)
0187                 t2 |= PORT_WKOC_E | PORT_WKDISC_E;
0188             else
0189                 t2 |= PORT_WKOC_E | PORT_WKCONN_E;
0190         }
0191         ehci_writel(ehci, t2, reg);
0192     }
0193 
0194     /* enter phy low-power mode again */
0195     if (ehci->has_tdi_phy_lpm) {
0196         port = HCS_N_PORTS(ehci->hcs_params);
0197         while (port--) {
0198             u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
0199 
0200             temp = ehci_readl(ehci, hostpc_reg);
0201             ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
0202         }
0203     }
0204 
0205     /* Does the root hub have a port wakeup pending? */
0206     if (!suspending && ehci_port_change(ehci))
0207         usb_hcd_resume_root_hub(ehci_to_hcd(ehci));
0208 
0209     spin_unlock_irq(&ehci->lock);
0210 }
0211 EXPORT_SYMBOL_GPL(ehci_adjust_port_wakeup_flags);
0212 
0213 static int ehci_bus_suspend (struct usb_hcd *hcd)
0214 {
0215     struct ehci_hcd     *ehci = hcd_to_ehci (hcd);
0216     int         port;
0217     int         mask;
0218     int         changed;
0219     bool            fs_idle_delay;
0220 
0221     ehci_dbg(ehci, "suspend root hub\n");
0222 
0223     if (time_before (jiffies, ehci->next_statechange))
0224         msleep(5);
0225 
0226     /* stop the schedules */
0227     ehci_quiesce(ehci);
0228 
0229     spin_lock_irq (&ehci->lock);
0230     if (ehci->rh_state < EHCI_RH_RUNNING)
0231         goto done;
0232 
0233     /* Once the controller is stopped, port resumes that are already
0234      * in progress won't complete.  Hence if remote wakeup is enabled
0235      * for the root hub and any ports are in the middle of a resume or
0236      * remote wakeup, we must fail the suspend.
0237      */
0238     if (hcd->self.root_hub->do_remote_wakeup) {
0239         if (ehci->resuming_ports) {
0240             spin_unlock_irq(&ehci->lock);
0241             ehci_dbg(ehci, "suspend failed because a port is resuming\n");
0242             return -EBUSY;
0243         }
0244     }
0245 
0246     /* Unlike other USB host controller types, EHCI doesn't have
0247      * any notion of "global" or bus-wide suspend.  The driver has
0248      * to manually suspend all the active unsuspended ports, and
0249      * then manually resume them in the bus_resume() routine.
0250      */
0251     ehci->bus_suspended = 0;
0252     ehci->owned_ports = 0;
0253     changed = 0;
0254     fs_idle_delay = false;
0255     port = HCS_N_PORTS(ehci->hcs_params);
0256     while (port--) {
0257         u32 __iomem *reg = &ehci->regs->port_status [port];
0258         u32     t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
0259         u32     t2 = t1 & ~PORT_WAKE_BITS;
0260 
0261         /* keep track of which ports we suspend */
0262         if (t1 & PORT_OWNER)
0263             set_bit(port, &ehci->owned_ports);
0264         else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
0265             t2 |= PORT_SUSPEND;
0266             set_bit(port, &ehci->bus_suspended);
0267         }
0268 
0269         /* enable remote wakeup on all ports, if told to do so */
0270         if (hcd->self.root_hub->do_remote_wakeup) {
0271             /* only enable appropriate wake bits, otherwise the
0272              * hardware can not go phy low power mode. If a race
0273              * condition happens here(connection change during bits
0274              * set), the port change detection will finally fix it.
0275              */
0276             if (t1 & PORT_CONNECT)
0277                 t2 |= PORT_WKOC_E | PORT_WKDISC_E;
0278             else
0279                 t2 |= PORT_WKOC_E | PORT_WKCONN_E;
0280         }
0281 
0282         if (t1 != t2) {
0283             /*
0284              * On some controllers, Wake-On-Disconnect will
0285              * generate false wakeup signals until the bus
0286              * switches over to full-speed idle.  For their
0287              * sake, add a delay if we need one.
0288              */
0289             if ((t2 & PORT_WKDISC_E) &&
0290                     ehci_port_speed(ehci, t2) ==
0291                         USB_PORT_STAT_HIGH_SPEED)
0292                 fs_idle_delay = true;
0293             ehci_writel(ehci, t2, reg);
0294             changed = 1;
0295         }
0296     }
0297     spin_unlock_irq(&ehci->lock);
0298 
0299     if (changed && ehci_has_fsl_susp_errata(ehci))
0300         /*
0301          * Wait for at least 10 millisecondes to ensure the controller
0302          * enter the suspend status before initiating a port resume
0303          * using the Force Port Resume bit (Not-EHCI compatible).
0304          */
0305         usleep_range(10000, 20000);
0306 
0307     if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) {
0308         /*
0309          * Wait for HCD to enter low-power mode or for the bus
0310          * to switch to full-speed idle.
0311          */
0312         usleep_range(5000, 5500);
0313     }
0314 
0315     if (changed && ehci->has_tdi_phy_lpm) {
0316         spin_lock_irq(&ehci->lock);
0317         port = HCS_N_PORTS(ehci->hcs_params);
0318         while (port--) {
0319             u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
0320             u32     t3;
0321 
0322             t3 = ehci_readl(ehci, hostpc_reg);
0323             ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
0324             t3 = ehci_readl(ehci, hostpc_reg);
0325             ehci_dbg(ehci, "Port %d phy low-power mode %s\n",
0326                     port, (t3 & HOSTPC_PHCD) ?
0327                     "succeeded" : "failed");
0328         }
0329         spin_unlock_irq(&ehci->lock);
0330     }
0331 
0332     /* Apparently some devices need a >= 1-uframe delay here */
0333     if (ehci->bus_suspended)
0334         udelay(150);
0335 
0336     /* turn off now-idle HC */
0337     ehci_halt (ehci);
0338 
0339     spin_lock_irq(&ehci->lock);
0340     if (ehci->enabled_hrtimer_events & BIT(EHCI_HRTIMER_POLL_DEAD))
0341         ehci_handle_controller_death(ehci);
0342     if (ehci->rh_state != EHCI_RH_RUNNING)
0343         goto done;
0344     ehci->rh_state = EHCI_RH_SUSPENDED;
0345 
0346     unlink_empty_async_suspended(ehci);
0347 
0348     /* Some Synopsys controllers mistakenly leave IAA turned on */
0349     ehci_writel(ehci, STS_IAA, &ehci->regs->status);
0350 
0351     /* Any IAA cycle that started before the suspend is now invalid */
0352     end_iaa_cycle(ehci);
0353     ehci_handle_start_intr_unlinks(ehci);
0354     ehci_handle_intr_unlinks(ehci);
0355     end_free_itds(ehci);
0356 
0357     /* allow remote wakeup */
0358     mask = INTR_MASK;
0359     if (!hcd->self.root_hub->do_remote_wakeup)
0360         mask &= ~STS_PCD;
0361     ehci_writel(ehci, mask, &ehci->regs->intr_enable);
0362     ehci_readl(ehci, &ehci->regs->intr_enable);
0363 
0364  done:
0365     ehci->next_statechange = jiffies + msecs_to_jiffies(10);
0366     ehci->enabled_hrtimer_events = 0;
0367     ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
0368     spin_unlock_irq (&ehci->lock);
0369 
0370     hrtimer_cancel(&ehci->hrtimer);
0371     return 0;
0372 }
0373 
0374 
0375 /* caller has locked the root hub, and should reset/reinit on error */
0376 static int ehci_bus_resume (struct usb_hcd *hcd)
0377 {
0378     struct ehci_hcd     *ehci = hcd_to_ehci (hcd);
0379     u32         temp;
0380     u32         power_okay;
0381     int         i;
0382     unsigned long       resume_needed = 0;
0383 
0384     if (time_before (jiffies, ehci->next_statechange))
0385         msleep(5);
0386     spin_lock_irq (&ehci->lock);
0387     if (!HCD_HW_ACCESSIBLE(hcd) || ehci->shutdown)
0388         goto shutdown;
0389 
0390     if (unlikely(ehci->debug)) {
0391         if (!dbgp_reset_prep(hcd))
0392             ehci->debug = NULL;
0393         else
0394             dbgp_external_startup(hcd);
0395     }
0396 
0397     /* Ideally and we've got a real resume here, and no port's power
0398      * was lost.  (For PCI, that means Vaux was maintained.)  But we
0399      * could instead be restoring a swsusp snapshot -- so that BIOS was
0400      * the last user of the controller, not reset/pm hardware keeping
0401      * state we gave to it.
0402      */
0403     power_okay = ehci_readl(ehci, &ehci->regs->intr_enable);
0404     ehci_dbg(ehci, "resume root hub%s\n",
0405             power_okay ? "" : " after power loss");
0406 
0407     /* at least some APM implementations will try to deliver
0408      * IRQs right away, so delay them until we're ready.
0409      */
0410     ehci_writel(ehci, 0, &ehci->regs->intr_enable);
0411 
0412     /* re-init operational registers */
0413     ehci_writel(ehci, 0, &ehci->regs->segment);
0414     ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
0415     ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
0416 
0417     /* restore CMD_RUN, framelist size, and irq threshold */
0418     ehci->command |= CMD_RUN;
0419     ehci_writel(ehci, ehci->command, &ehci->regs->command);
0420     ehci->rh_state = EHCI_RH_RUNNING;
0421 
0422     /*
0423      * According to Bugzilla #8190, the port status for some controllers
0424      * will be wrong without a delay. At their wrong status, the port
0425      * is enabled, but not suspended neither resumed.
0426      */
0427     i = HCS_N_PORTS(ehci->hcs_params);
0428     while (i--) {
0429         temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
0430         if ((temp & PORT_PE) &&
0431                 !(temp & (PORT_SUSPEND | PORT_RESUME))) {
0432             ehci_dbg(ehci, "Port status(0x%x) is wrong\n", temp);
0433             spin_unlock_irq(&ehci->lock);
0434             msleep(8);
0435             spin_lock_irq(&ehci->lock);
0436             break;
0437         }
0438     }
0439 
0440     if (ehci->shutdown)
0441         goto shutdown;
0442 
0443     /* clear phy low-power mode before resume */
0444     if (ehci->bus_suspended && ehci->has_tdi_phy_lpm) {
0445         i = HCS_N_PORTS(ehci->hcs_params);
0446         while (i--) {
0447             if (test_bit(i, &ehci->bus_suspended)) {
0448                 u32 __iomem *hostpc_reg =
0449                             &ehci->regs->hostpc[i];
0450 
0451                 temp = ehci_readl(ehci, hostpc_reg);
0452                 ehci_writel(ehci, temp & ~HOSTPC_PHCD,
0453                         hostpc_reg);
0454             }
0455         }
0456         spin_unlock_irq(&ehci->lock);
0457         msleep(5);
0458         spin_lock_irq(&ehci->lock);
0459         if (ehci->shutdown)
0460             goto shutdown;
0461     }
0462 
0463     /* manually resume the ports we suspended during bus_suspend() */
0464     i = HCS_N_PORTS (ehci->hcs_params);
0465     while (i--) {
0466         temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
0467         temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
0468         if (test_bit(i, &ehci->bus_suspended) &&
0469                 (temp & PORT_SUSPEND)) {
0470             temp |= PORT_RESUME;
0471             set_bit(i, &resume_needed);
0472         }
0473         ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
0474     }
0475 
0476     /*
0477      * msleep for USB_RESUME_TIMEOUT ms only if code is trying to resume
0478      * port
0479      */
0480     if (resume_needed) {
0481         spin_unlock_irq(&ehci->lock);
0482         msleep(USB_RESUME_TIMEOUT);
0483         spin_lock_irq(&ehci->lock);
0484         if (ehci->shutdown)
0485             goto shutdown;
0486     }
0487 
0488     i = HCS_N_PORTS (ehci->hcs_params);
0489     while (i--) {
0490         temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
0491         if (test_bit(i, &resume_needed)) {
0492             temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
0493             ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
0494         }
0495     }
0496 
0497     ehci->next_statechange = jiffies + msecs_to_jiffies(5);
0498     spin_unlock_irq(&ehci->lock);
0499 
0500     ehci_handover_companion_ports(ehci);
0501 
0502     /* Now we can safely re-enable irqs */
0503     spin_lock_irq(&ehci->lock);
0504     if (ehci->shutdown)
0505         goto shutdown;
0506     ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
0507     (void) ehci_readl(ehci, &ehci->regs->intr_enable);
0508     spin_unlock_irq(&ehci->lock);
0509 
0510     return 0;
0511 
0512  shutdown:
0513     spin_unlock_irq(&ehci->lock);
0514     return -ESHUTDOWN;
0515 }
0516 
0517 static unsigned long ehci_get_resuming_ports(struct usb_hcd *hcd)
0518 {
0519     struct ehci_hcd     *ehci = hcd_to_ehci(hcd);
0520 
0521     return ehci->resuming_ports;
0522 }
0523 
0524 #else
0525 
0526 #define ehci_bus_suspend    NULL
0527 #define ehci_bus_resume     NULL
0528 #define ehci_get_resuming_ports NULL
0529 
0530 #endif  /* CONFIG_PM */
0531 
0532 /*-------------------------------------------------------------------------*/
0533 
0534 /*
0535  * Sets the owner of a port
0536  */
0537 static void set_owner(struct ehci_hcd *ehci, int portnum, int new_owner)
0538 {
0539     u32 __iomem     *status_reg;
0540     u32         port_status;
0541     int             try;
0542 
0543     status_reg = &ehci->regs->port_status[portnum];
0544 
0545     /*
0546      * The controller won't set the OWNER bit if the port is
0547      * enabled, so this loop will sometimes require at least two
0548      * iterations: one to disable the port and one to set OWNER.
0549      */
0550     for (try = 4; try > 0; --try) {
0551         spin_lock_irq(&ehci->lock);
0552         port_status = ehci_readl(ehci, status_reg);
0553         if ((port_status & PORT_OWNER) == new_owner
0554                 || (port_status & (PORT_OWNER | PORT_CONNECT))
0555                     == 0)
0556             try = 0;
0557         else {
0558             port_status ^= PORT_OWNER;
0559             port_status &= ~(PORT_PE | PORT_RWC_BITS);
0560             ehci_writel(ehci, port_status, status_reg);
0561         }
0562         spin_unlock_irq(&ehci->lock);
0563         if (try > 1)
0564             msleep(5);
0565     }
0566 }
0567 
0568 /*-------------------------------------------------------------------------*/
0569 
0570 static int check_reset_complete (
0571     struct ehci_hcd *ehci,
0572     int     index,
0573     u32 __iomem *status_reg,
0574     int     port_status
0575 ) {
0576     if (!(port_status & PORT_CONNECT))
0577         return port_status;
0578 
0579     /* if reset finished and it's still not enabled -- handoff */
0580     if (!(port_status & PORT_PE)) {
0581 
0582         /* with integrated TT, there's nobody to hand it to! */
0583         if (ehci_is_TDI(ehci)) {
0584             ehci_dbg (ehci,
0585                 "Failed to enable port %d on root hub TT\n",
0586                 index+1);
0587             return port_status;
0588         }
0589 
0590         ehci_dbg (ehci, "port %d full speed --> companion\n",
0591             index + 1);
0592 
0593         // what happens if HCS_N_CC(params) == 0 ?
0594         port_status |= PORT_OWNER;
0595         port_status &= ~PORT_RWC_BITS;
0596         ehci_writel(ehci, port_status, status_reg);
0597 
0598         /* ensure 440EPX ohci controller state is operational */
0599         if (ehci->has_amcc_usb23)
0600             set_ohci_hcfs(ehci, 1);
0601     } else {
0602         ehci_dbg(ehci, "port %d reset complete, port enabled\n",
0603             index + 1);
0604         /* ensure 440EPx ohci controller state is suspended */
0605         if (ehci->has_amcc_usb23)
0606             set_ohci_hcfs(ehci, 0);
0607     }
0608 
0609     return port_status;
0610 }
0611 
0612 /*-------------------------------------------------------------------------*/
0613 
0614 
0615 /* build "status change" packet (one or two bytes) from HC registers */
0616 
0617 static int
0618 ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
0619 {
0620     struct ehci_hcd *ehci = hcd_to_ehci (hcd);
0621     u32     temp, status;
0622     u32     mask;
0623     int     ports, i, retval = 1;
0624     unsigned long   flags;
0625     u32     ppcd = ~0;
0626 
0627     /* init status to no-changes */
0628     buf [0] = 0;
0629     ports = HCS_N_PORTS (ehci->hcs_params);
0630     if (ports > 7) {
0631         buf [1] = 0;
0632         retval++;
0633     }
0634 
0635     /* Inform the core about resumes-in-progress by returning
0636      * a non-zero value even if there are no status changes.
0637      */
0638     status = ehci->resuming_ports;
0639 
0640     /* Some boards (mostly VIA?) report bogus overcurrent indications,
0641      * causing massive log spam unless we completely ignore them.  It
0642      * may be relevant that VIA VT8235 controllers, where PORT_POWER is
0643      * always set, seem to clear PORT_OCC and PORT_CSC when writing to
0644      * PORT_POWER; that's surprising, but maybe within-spec.
0645      */
0646     if (!ignore_oc && !ehci->spurious_oc)
0647         mask = PORT_CSC | PORT_PEC | PORT_OCC;
0648     else
0649         mask = PORT_CSC | PORT_PEC;
0650     // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
0651 
0652     /* no hub change reports (bit 0) for now (power, ...) */
0653 
0654     /* port N changes (bit N)? */
0655     spin_lock_irqsave (&ehci->lock, flags);
0656 
0657     /* get per-port change detect bits */
0658     if (ehci->has_ppcd)
0659         ppcd = ehci_readl(ehci, &ehci->regs->status) >> 16;
0660 
0661     for (i = 0; i < ports; i++) {
0662         /* leverage per-port change bits feature */
0663         if (ppcd & (1 << i))
0664             temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
0665         else
0666             temp = 0;
0667 
0668         /*
0669          * Return status information even for ports with OWNER set.
0670          * Otherwise hub_wq wouldn't see the disconnect event when a
0671          * high-speed device is switched over to the companion
0672          * controller by the user.
0673          */
0674 
0675         if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
0676                 || (ehci->reset_done[i] && time_after_eq(
0677                     jiffies, ehci->reset_done[i]))) {
0678             if (i < 7)
0679                 buf [0] |= 1 << (i + 1);
0680             else
0681                 buf [1] |= 1 << (i - 7);
0682             status = STS_PCD;
0683         }
0684     }
0685 
0686     /* If a resume is in progress, make sure it can finish */
0687     if (ehci->resuming_ports)
0688         mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25));
0689 
0690     spin_unlock_irqrestore (&ehci->lock, flags);
0691     return status ? retval : 0;
0692 }
0693 
0694 /*-------------------------------------------------------------------------*/
0695 
0696 static void
0697 ehci_hub_descriptor (
0698     struct ehci_hcd         *ehci,
0699     struct usb_hub_descriptor   *desc
0700 ) {
0701     int     ports = HCS_N_PORTS (ehci->hcs_params);
0702     u16     temp;
0703 
0704     desc->bDescriptorType = USB_DT_HUB;
0705     desc->bPwrOn2PwrGood = 10;  /* ehci 1.0, 2.3.9 says 20ms max */
0706     desc->bHubContrCurrent = 0;
0707 
0708     desc->bNbrPorts = ports;
0709     temp = 1 + (ports / 8);
0710     desc->bDescLength = 7 + 2 * temp;
0711 
0712     /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
0713     memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
0714     memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
0715 
0716     temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
0717     if (HCS_PPC (ehci->hcs_params))
0718         temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */
0719     else
0720         temp |= HUB_CHAR_NO_LPSM; /* no power switching */
0721 #if 0
0722 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
0723     if (HCS_INDICATOR (ehci->hcs_params))
0724         temp |= HUB_CHAR_PORTIND; /* per-port indicators (LEDs) */
0725 #endif
0726     desc->wHubCharacteristics = cpu_to_le16(temp);
0727 }
0728 
0729 /*-------------------------------------------------------------------------*/
0730 
0731 int ehci_hub_control(
0732     struct usb_hcd  *hcd,
0733     u16     typeReq,
0734     u16     wValue,
0735     u16     wIndex,
0736     char        *buf,
0737     u16     wLength
0738 ) {
0739     struct ehci_hcd *ehci = hcd_to_ehci (hcd);
0740     int     ports = HCS_N_PORTS (ehci->hcs_params);
0741     u32 __iomem *status_reg, *hostpc_reg;
0742     u32     temp, temp1, status;
0743     unsigned long   flags;
0744     int     retval = 0;
0745     unsigned    selector;
0746 
0747     /*
0748      * Avoid out-of-bounds values while calculating the port index
0749      * from wIndex.  The compiler doesn't like pointers to invalid
0750      * addresses, even if they are never used.
0751      */
0752     temp = (wIndex - 1) & 0xff;
0753     if (temp >= HCS_N_PORTS_MAX)
0754         temp = 0;
0755     status_reg = &ehci->regs->port_status[temp];
0756     hostpc_reg = &ehci->regs->hostpc[temp];
0757 
0758     /*
0759      * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
0760      * HCS_INDICATOR may say we can change LEDs to off/amber/green.
0761      * (track current state ourselves) ... blink for diagnostics,
0762      * power, "this is the one", etc.  EHCI spec supports this.
0763      */
0764 
0765     spin_lock_irqsave (&ehci->lock, flags);
0766     switch (typeReq) {
0767     case ClearHubFeature:
0768         switch (wValue) {
0769         case C_HUB_LOCAL_POWER:
0770         case C_HUB_OVER_CURRENT:
0771             /* no hub-wide feature/status flags */
0772             break;
0773         default:
0774             goto error;
0775         }
0776         break;
0777     case ClearPortFeature:
0778         if (!wIndex || wIndex > ports)
0779             goto error;
0780         wIndex--;
0781         temp = ehci_readl(ehci, status_reg);
0782         temp &= ~PORT_RWC_BITS;
0783 
0784         /*
0785          * Even if OWNER is set, so the port is owned by the
0786          * companion controller, hub_wq needs to be able to clear
0787          * the port-change status bits (especially
0788          * USB_PORT_STAT_C_CONNECTION).
0789          */
0790 
0791         switch (wValue) {
0792         case USB_PORT_FEAT_ENABLE:
0793             ehci_writel(ehci, temp & ~PORT_PE, status_reg);
0794             break;
0795         case USB_PORT_FEAT_C_ENABLE:
0796             ehci_writel(ehci, temp | PORT_PEC, status_reg);
0797             break;
0798         case USB_PORT_FEAT_SUSPEND:
0799             if (temp & PORT_RESET)
0800                 goto error;
0801             if (ehci->no_selective_suspend)
0802                 break;
0803 #ifdef CONFIG_USB_OTG
0804             if ((hcd->self.otg_port == (wIndex + 1))
0805                 && hcd->self.b_hnp_enable) {
0806                 otg_start_hnp(hcd->usb_phy->otg);
0807                 break;
0808             }
0809 #endif
0810             if (!(temp & PORT_SUSPEND))
0811                 break;
0812             if ((temp & PORT_PE) == 0)
0813                 goto error;
0814 
0815             /* clear phy low-power mode before resume */
0816             if (ehci->has_tdi_phy_lpm) {
0817                 temp1 = ehci_readl(ehci, hostpc_reg);
0818                 ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
0819                         hostpc_reg);
0820                 spin_unlock_irqrestore(&ehci->lock, flags);
0821                 msleep(5);/* wait to leave low-power mode */
0822                 spin_lock_irqsave(&ehci->lock, flags);
0823             }
0824             /* resume signaling for 20 msec */
0825             temp &= ~PORT_WAKE_BITS;
0826             ehci_writel(ehci, temp | PORT_RESUME, status_reg);
0827             ehci->reset_done[wIndex] = jiffies
0828                     + msecs_to_jiffies(USB_RESUME_TIMEOUT);
0829             set_bit(wIndex, &ehci->resuming_ports);
0830             usb_hcd_start_port_resume(&hcd->self, wIndex);
0831             break;
0832         case USB_PORT_FEAT_C_SUSPEND:
0833             clear_bit(wIndex, &ehci->port_c_suspend);
0834             break;
0835         case USB_PORT_FEAT_POWER:
0836             if (HCS_PPC(ehci->hcs_params)) {
0837                 spin_unlock_irqrestore(&ehci->lock, flags);
0838                 ehci_port_power(ehci, wIndex, false);
0839                 spin_lock_irqsave(&ehci->lock, flags);
0840             }
0841             break;
0842         case USB_PORT_FEAT_C_CONNECTION:
0843             ehci_writel(ehci, temp | PORT_CSC, status_reg);
0844             break;
0845         case USB_PORT_FEAT_C_OVER_CURRENT:
0846             ehci_writel(ehci, temp | PORT_OCC, status_reg);
0847             break;
0848         case USB_PORT_FEAT_C_RESET:
0849             /* GetPortStatus clears reset */
0850             break;
0851         default:
0852             goto error;
0853         }
0854         ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */
0855         break;
0856     case GetHubDescriptor:
0857         ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
0858             buf);
0859         break;
0860     case GetHubStatus:
0861         /* no hub-wide feature/status flags */
0862         memset (buf, 0, 4);
0863         //cpu_to_le32s ((u32 *) buf);
0864         break;
0865     case GetPortStatus:
0866         if (!wIndex || wIndex > ports)
0867             goto error;
0868         wIndex--;
0869         status = 0;
0870         temp = ehci_readl(ehci, status_reg);
0871 
0872         // wPortChange bits
0873         if (temp & PORT_CSC)
0874             status |= USB_PORT_STAT_C_CONNECTION << 16;
0875         if (temp & PORT_PEC)
0876             status |= USB_PORT_STAT_C_ENABLE << 16;
0877 
0878         if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){
0879             status |= USB_PORT_STAT_C_OVERCURRENT << 16;
0880 
0881             /*
0882              * Hubs should disable port power on over-current.
0883              * However, not all EHCI implementations do this
0884              * automatically, even if they _do_ support per-port
0885              * power switching; they're allowed to just limit the
0886              * current.  hub_wq will turn the power back on.
0887              */
0888             if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle))
0889                     && HCS_PPC(ehci->hcs_params)) {
0890                 spin_unlock_irqrestore(&ehci->lock, flags);
0891                 ehci_port_power(ehci, wIndex, false);
0892                 spin_lock_irqsave(&ehci->lock, flags);
0893                 temp = ehci_readl(ehci, status_reg);
0894             }
0895         }
0896 
0897         /* no reset or resume pending */
0898         if (!ehci->reset_done[wIndex]) {
0899 
0900             /* Remote Wakeup received? */
0901             if (temp & PORT_RESUME) {
0902                 /* resume signaling for 20 msec */
0903                 ehci->reset_done[wIndex] = jiffies
0904                         + msecs_to_jiffies(20);
0905                 usb_hcd_start_port_resume(&hcd->self, wIndex);
0906                 set_bit(wIndex, &ehci->resuming_ports);
0907                 /* check the port again */
0908                 mod_timer(&ehci_to_hcd(ehci)->rh_timer,
0909                         ehci->reset_done[wIndex]);
0910             }
0911 
0912         /* reset or resume not yet complete */
0913         } else if (!time_after_eq(jiffies, ehci->reset_done[wIndex])) {
0914             ;   /* wait until it is complete */
0915 
0916         /* resume completed */
0917         } else if (test_bit(wIndex, &ehci->resuming_ports)) {
0918             clear_bit(wIndex, &ehci->suspended_ports);
0919             set_bit(wIndex, &ehci->port_c_suspend);
0920             ehci->reset_done[wIndex] = 0;
0921             usb_hcd_end_port_resume(&hcd->self, wIndex);
0922 
0923             /* stop resume signaling */
0924             temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
0925             ehci_writel(ehci, temp, status_reg);
0926             clear_bit(wIndex, &ehci->resuming_ports);
0927             retval = ehci_handshake(ehci, status_reg,
0928                     PORT_RESUME, 0, 2000 /* 2msec */);
0929             if (retval != 0) {
0930                 ehci_err(ehci, "port %d resume error %d\n",
0931                         wIndex + 1, retval);
0932                 goto error;
0933             }
0934             temp = ehci_readl(ehci, status_reg);
0935 
0936         /* whoever resets must GetPortStatus to complete it!! */
0937         } else {
0938             status |= USB_PORT_STAT_C_RESET << 16;
0939             ehci->reset_done [wIndex] = 0;
0940 
0941             /* force reset to complete */
0942             ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
0943                     status_reg);
0944             /* REVISIT:  some hardware needs 550+ usec to clear
0945              * this bit; seems too long to spin routinely...
0946              */
0947             retval = ehci_handshake(ehci, status_reg,
0948                     PORT_RESET, 0, 1000);
0949             if (retval != 0) {
0950                 ehci_err (ehci, "port %d reset error %d\n",
0951                     wIndex + 1, retval);
0952                 goto error;
0953             }
0954 
0955             /* see what we found out */
0956             temp = check_reset_complete (ehci, wIndex, status_reg,
0957                     ehci_readl(ehci, status_reg));
0958         }
0959 
0960         /* transfer dedicated ports to the companion hc */
0961         if ((temp & PORT_CONNECT) &&
0962                 test_bit(wIndex, &ehci->companion_ports)) {
0963             temp &= ~PORT_RWC_BITS;
0964             temp |= PORT_OWNER;
0965             ehci_writel(ehci, temp, status_reg);
0966             ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1);
0967             temp = ehci_readl(ehci, status_reg);
0968         }
0969 
0970         /*
0971          * Even if OWNER is set, there's no harm letting hub_wq
0972          * see the wPortStatus values (they should all be 0 except
0973          * for PORT_POWER anyway).
0974          */
0975 
0976         if (temp & PORT_CONNECT) {
0977             status |= USB_PORT_STAT_CONNECTION;
0978             // status may be from integrated TT
0979             if (ehci->has_hostpc) {
0980                 temp1 = ehci_readl(ehci, hostpc_reg);
0981                 status |= ehci_port_speed(ehci, temp1);
0982             } else
0983                 status |= ehci_port_speed(ehci, temp);
0984         }
0985         if (temp & PORT_PE)
0986             status |= USB_PORT_STAT_ENABLE;
0987 
0988         /* maybe the port was unsuspended without our knowledge */
0989         if (temp & (PORT_SUSPEND|PORT_RESUME)) {
0990             status |= USB_PORT_STAT_SUSPEND;
0991         } else if (test_bit(wIndex, &ehci->suspended_ports)) {
0992             clear_bit(wIndex, &ehci->suspended_ports);
0993             clear_bit(wIndex, &ehci->resuming_ports);
0994             ehci->reset_done[wIndex] = 0;
0995             if (temp & PORT_PE)
0996                 set_bit(wIndex, &ehci->port_c_suspend);
0997             usb_hcd_end_port_resume(&hcd->self, wIndex);
0998         }
0999 
1000         if (temp & PORT_OC)
1001             status |= USB_PORT_STAT_OVERCURRENT;
1002         if (temp & PORT_RESET)
1003             status |= USB_PORT_STAT_RESET;
1004         if (temp & PORT_POWER)
1005             status |= USB_PORT_STAT_POWER;
1006         if (test_bit(wIndex, &ehci->port_c_suspend))
1007             status |= USB_PORT_STAT_C_SUSPEND << 16;
1008 
1009         if (status & ~0xffff)   /* only if wPortChange is interesting */
1010             dbg_port(ehci, "GetStatus", wIndex + 1, temp);
1011         put_unaligned_le32(status, buf);
1012         break;
1013     case SetHubFeature:
1014         switch (wValue) {
1015         case C_HUB_LOCAL_POWER:
1016         case C_HUB_OVER_CURRENT:
1017             /* no hub-wide feature/status flags */
1018             break;
1019         default:
1020             goto error;
1021         }
1022         break;
1023     case SetPortFeature:
1024         selector = wIndex >> 8;
1025         wIndex &= 0xff;
1026         if (unlikely(ehci->debug)) {
1027             /* If the debug port is active any port
1028              * feature requests should get denied */
1029             if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
1030                 (readl(&ehci->debug->control) & DBGP_ENABLED)) {
1031                 retval = -ENODEV;
1032                 goto error_exit;
1033             }
1034         }
1035         if (!wIndex || wIndex > ports)
1036             goto error;
1037         wIndex--;
1038         temp = ehci_readl(ehci, status_reg);
1039         if (temp & PORT_OWNER)
1040             break;
1041 
1042         temp &= ~PORT_RWC_BITS;
1043         switch (wValue) {
1044         case USB_PORT_FEAT_SUSPEND:
1045             if (ehci->no_selective_suspend)
1046                 break;
1047             if ((temp & PORT_PE) == 0
1048                     || (temp & PORT_RESET) != 0)
1049                 goto error;
1050 
1051             /* After above check the port must be connected.
1052              * Set appropriate bit thus could put phy into low power
1053              * mode if we have tdi_phy_lpm feature
1054              */
1055             temp &= ~PORT_WKCONN_E;
1056             temp |= PORT_WKDISC_E | PORT_WKOC_E;
1057             ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
1058             if (ehci->has_tdi_phy_lpm) {
1059                 spin_unlock_irqrestore(&ehci->lock, flags);
1060                 msleep(5);/* 5ms for HCD enter low pwr mode */
1061                 spin_lock_irqsave(&ehci->lock, flags);
1062                 temp1 = ehci_readl(ehci, hostpc_reg);
1063                 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
1064                     hostpc_reg);
1065                 temp1 = ehci_readl(ehci, hostpc_reg);
1066                 ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
1067                     wIndex, (temp1 & HOSTPC_PHCD) ?
1068                     "succeeded" : "failed");
1069             }
1070             if (ehci_has_fsl_susp_errata(ehci)) {
1071                 /* 10ms for HCD enter suspend */
1072                 spin_unlock_irqrestore(&ehci->lock, flags);
1073                 usleep_range(10000, 20000);
1074                 spin_lock_irqsave(&ehci->lock, flags);
1075             }
1076             set_bit(wIndex, &ehci->suspended_ports);
1077             break;
1078         case USB_PORT_FEAT_POWER:
1079             if (HCS_PPC(ehci->hcs_params)) {
1080                 spin_unlock_irqrestore(&ehci->lock, flags);
1081                 ehci_port_power(ehci, wIndex, true);
1082                 spin_lock_irqsave(&ehci->lock, flags);
1083             }
1084             break;
1085         case USB_PORT_FEAT_RESET:
1086             if (temp & (PORT_SUSPEND|PORT_RESUME))
1087                 goto error;
1088             /* line status bits may report this as low speed,
1089              * which can be fine if this root hub has a
1090              * transaction translator built in.
1091              */
1092             if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
1093                     && !ehci_is_TDI(ehci)
1094                     && PORT_USB11 (temp)) {
1095                 ehci_dbg (ehci,
1096                     "port %d low speed --> companion\n",
1097                     wIndex + 1);
1098                 temp |= PORT_OWNER;
1099             } else {
1100                 temp |= PORT_RESET;
1101                 temp &= ~PORT_PE;
1102 
1103                 /*
1104                  * caller must wait, then call GetPortStatus
1105                  * usb 2.0 spec says 50 ms resets on root
1106                  */
1107                 ehci->reset_done [wIndex] = jiffies
1108                         + msecs_to_jiffies (50);
1109 
1110                 /*
1111                  * Force full-speed connect for FSL high-speed
1112                  * erratum; disable HS Chirp by setting PFSC bit
1113                  */
1114                 if (ehci_has_fsl_hs_errata(ehci))
1115                     temp |= (1 << PORTSC_FSL_PFSC);
1116             }
1117             ehci_writel(ehci, temp, status_reg);
1118             break;
1119 
1120         /* For downstream facing ports (these):  one hub port is put
1121          * into test mode according to USB2 11.24.2.13, then the hub
1122          * must be reset (which for root hub now means rmmod+modprobe,
1123          * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
1124          * about the EHCI-specific stuff.
1125          */
1126         case USB_PORT_FEAT_TEST:
1127 #ifdef CONFIG_USB_HCD_TEST_MODE
1128             if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) {
1129                 spin_unlock_irqrestore(&ehci->lock, flags);
1130                 retval = ehset_single_step_set_feature(hcd,
1131                                 wIndex + 1);
1132                 spin_lock_irqsave(&ehci->lock, flags);
1133                 break;
1134             }
1135 #endif
1136             if (!selector || selector > 5)
1137                 goto error;
1138             spin_unlock_irqrestore(&ehci->lock, flags);
1139             ehci_quiesce(ehci);
1140             spin_lock_irqsave(&ehci->lock, flags);
1141 
1142             /* Put all enabled ports into suspend */
1143             while (ports--) {
1144                 u32 __iomem *sreg =
1145                         &ehci->regs->port_status[ports];
1146 
1147                 temp = ehci_readl(ehci, sreg) & ~PORT_RWC_BITS;
1148                 if (temp & PORT_PE)
1149                     ehci_writel(ehci, temp | PORT_SUSPEND,
1150                             sreg);
1151             }
1152 
1153             spin_unlock_irqrestore(&ehci->lock, flags);
1154             ehci_halt(ehci);
1155             spin_lock_irqsave(&ehci->lock, flags);
1156 
1157             temp = ehci_readl(ehci, status_reg);
1158             temp |= selector << 16;
1159             ehci_writel(ehci, temp, status_reg);
1160             break;
1161 
1162         default:
1163             goto error;
1164         }
1165         ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
1166         break;
1167 
1168     default:
1169 error:
1170         /* "stall" on error */
1171         retval = -EPIPE;
1172     }
1173 error_exit:
1174     spin_unlock_irqrestore (&ehci->lock, flags);
1175     return retval;
1176 }
1177 EXPORT_SYMBOL_GPL(ehci_hub_control);
1178 
1179 static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
1180 {
1181     struct ehci_hcd     *ehci = hcd_to_ehci(hcd);
1182 
1183     if (ehci_is_TDI(ehci))
1184         return;
1185     set_owner(ehci, --portnum, PORT_OWNER);
1186 }
1187 
1188 static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
1189 {
1190     struct ehci_hcd     *ehci = hcd_to_ehci(hcd);
1191     u32 __iomem     *reg;
1192 
1193     if (ehci_is_TDI(ehci))
1194         return 0;
1195     reg = &ehci->regs->port_status[portnum - 1];
1196     return ehci_readl(ehci, reg) & PORT_OWNER;
1197 }
1198 
1199 static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable)
1200 {
1201     struct usb_hcd *hcd = ehci_to_hcd(ehci);
1202     u32 __iomem *status_reg = &ehci->regs->port_status[portnum];
1203     u32 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
1204 
1205     if (enable)
1206         ehci_writel(ehci, temp | PORT_POWER, status_reg);
1207     else
1208         ehci_writel(ehci, temp & ~PORT_POWER, status_reg);
1209 
1210     if (hcd->driver->port_power)
1211         hcd->driver->port_power(hcd, portnum, enable);
1212 
1213     return 0;
1214 }