1 /*
2  * Copyright (C) 2001-2004 by David Brownell
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 /* this file is part of ehci-hcd.c */
20 
21 /*-------------------------------------------------------------------------*/
22 
23 /*
24  * EHCI Root Hub ... the nonsharable stuff
25  *
26  * Registers don't need cpu_to_le32, that happens transparently
27  */
28 
29 /*-------------------------------------------------------------------------*/
30 //#include <linux/usb/otg.h>
31 #include <usb_host_hub.h>
32 
33 #define PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
34 
35 
36 static void unlink_empty_async_suspended(struct ehci_hcd *ehci);
37 
38 //static int persist_enabled_on_companion(struct usb_device *udev, void *unused)
39 //{
40 //  return !udev->maxchild && udev->persist_enabled &&
41 //      udev->bus->root_hub->speed < USB_SPEED_HIGH;
42 //}
43 //
44 ///* After a power loss, ports that were owned by the companion must be
45 // * reset so that the companion can still own them.
46 // */
47 //static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
48 //{
49 //  u32 __iomem *reg;
50 //  u32     status;
51 //  int     port;
52 //  __le32      buf;
53 //  struct hc_gen_hcd * *hcd = ehci_to_hcd(ehci);
54 //
55 //  if (!ehci->owned_ports)
56 //      return;
57 //
58 //  /*
59 //   * USB 1.1 devices are mostly HIDs, which don't need to persist across
60 //   * suspends. If we ensure that none of our companion's devices have
61 //   * persist_enabled (by looking through all USB 1.1 buses in the system),
62 //   * we can skip this and avoid slowing resume down. Devices without
63 //   * persist will just get reenumerated shortly after resume anyway.
64 //   */
65 //  if (!usb_for_each_dev(NULL, persist_enabled_on_companion))
66 //      return;
67 //
68 //  /* Make sure the ports are powered */
69 //  port = HCS_N_PORTS(ehci->hcs_params);
70 //  while (port--) {
71 //      if (usb_test_bit(port, &ehci->owned_ports)) {
72 //          reg = &ehci->regs->port_status[port];
73 //          status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
74 //          if (!(status & PORT_POWER))
75 //              ehci_port_power(ehci, port, true);
76 //      }
77 //  }
78 //
79 //  /* Give the connections some time to appear */
80 //  hal_msleep(20);
81 //
82 //  spin_lock_irq(&ehci->lock);
83 //  port = HCS_N_PORTS(ehci->hcs_params);
84 //  while (port--) {
85 //      if (usb_test_bit(port, &ehci->owned_ports)) {
86 //          reg = &ehci->regs->port_status[port];
87 //          status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
88 //
89 //          /* Port already owned by companion? */
90 //          if (status & PORT_OWNER)
91 //              usb_clear_bit(port, &ehci->owned_ports);
92 //          else if (usb_test_bit(port, &ehci->companion_ports))
93 //              ehci_writel(ehci, status & ~PORT_PE, reg);
94 //          else {
95 //              spin_unlock_irq(&ehci->lock);
96 //              ehci_hub_control(hcd, SetPortFeature,
97 //                      USB_PORT_FEAT_RESET, port + 1,
98 //                      NULL, 0);
99 //              spin_lock_irq(&ehci->lock);
100 //          }
101 //      }
102 //  }
103 //  spin_unlock_irq(&ehci->lock);
104 //
105 //  if (!ehci->owned_ports)
106 //      return;
107 //  hal_msleep(90);     /* Wait for resets to complete */
108 //
109 //  spin_lock_irq(&ehci->lock);
110 //  port = HCS_N_PORTS(ehci->hcs_params);
111 //  while (port--) {
112 //      if (usb_test_bit(port, &ehci->owned_ports)) {
113 //          spin_unlock_irq(&ehci->lock);
114 //          ehci_hub_control(hcd, GetPortStatus,
115 //                  0, port + 1,
116 //                  (char *) &buf, sizeof(buf));
117 //          spin_lock_irq(&ehci->lock);
118 //
119 //          /* The companion should now own the port,
120 //           * but if something went wrong the port must not
121 //           * remain enabled.
122 //           */
123 //          reg = &ehci->regs->port_status[port];
124 //          status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
125 //          if (status & PORT_OWNER)
126 //              ehci_writel(ehci, status | PORT_CSC, reg);
127 //          else {
128 //              ehci_dbg("failed handover port %d: %x\n",
129 //                      port + 1, status);
130 //              ehci_writel(ehci, status & ~PORT_PE, reg);
131 //          }
132 //      }
133 //  }
134 //
135 //  ehci->owned_ports = 0;
136 //  spin_unlock_irq(&ehci->lock);
137 //}
138 
139 //static int ehci_port_change(struct ehci_hcd *ehci)
140 //{
141 //  int i = HCS_N_PORTS(ehci->hcs_params);
142 //
143 //  /* First check if the controller indicates a change event */
144 //
145 //  if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)
146 //      return 1;
147 //
148 //  /*
149 //   * Not all controllers appear to update this while going from D3 to D0,
150 //   * so check the individual port status registers as well
151 //   */
152 //
153 //  while (i--)
154 //      if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC)
155 //          return 1;
156 //
157 //  return 0;
158 //}
159 
160 //void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
161 //      bool suspending, bool do_wakeup)
162 //{
163 //  int     port;
164 //  u32     temp;
165 //
166 //  /* If remote wakeup is enabled for the root hub but disabled
167 //   * for the controller, we must adjust all the port wakeup flags
168 //   * when the controller is suspended or resumed.  In all other
169 //   * cases they don't need to be changed.
170 //   */
171 //  if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup || do_wakeup)
172 //      return;
173 //
174 //  spin_lock_irq(&ehci->lock);
175 //
176 //  /* clear phy low-power mode before changing wakeup flags */
177 //  if (ehci->has_tdi_phy_lpm) {
178 //      port = HCS_N_PORTS(ehci->hcs_params);
179 //      while (port--) {
180 //          u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
181 //
182 //          temp = ehci_readl(ehci, hostpc_reg);
183 //          ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
184 //      }
185 //      spin_unlock_irq(&ehci->lock);
186 //      hal_msleep(5);
187 //      spin_lock_irq(&ehci->lock);
188 //  }
189 //
190 //  port = HCS_N_PORTS(ehci->hcs_params);
191 //  while (port--) {
192 //      u32 __iomem *reg = &ehci->regs->port_status[port];
193 //      u32     t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
194 //      u32     t2 = t1 & ~PORT_WAKE_BITS;
195 //
196 //      /* If we are suspending the controller, clear the flags.
197 //       * If we are resuming the controller, set the wakeup flags.
198 //       */
199 //      if (!suspending) {
200 //          if (t1 & PORT_CONNECT)
201 //              t2 |= PORT_WKOC_E | PORT_WKDISC_E;
202 //          else
203 //              t2 |= PORT_WKOC_E | PORT_WKCONN_E;
204 //      }
205 //      ehci_writel(ehci, t2, reg);
206 //  }
207 //
208 //  /* enter phy low-power mode again */
209 //  if (ehci->has_tdi_phy_lpm) {
210 //      port = HCS_N_PORTS(ehci->hcs_params);
211 //      while (port--) {
212 //          u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
213 //
214 //          temp = ehci_readl(ehci, hostpc_reg);
215 //          ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
216 //      }
217 //  }
218 //
219 //  /* Does the root hub have a port wakeup pending? */
220 //  if (!suspending && ehci_port_change(ehci))
221 //      usb_hcd_resume_root_hub(ehci_to_hcd(ehci));
222 //
223 //  spin_unlock_irq(&ehci->lock);
224 //}
225 //EXPORT_SYMBOL_GPL(ehci_adjust_port_wakeup_flags);
226 
227 
ehci_bus_suspend(struct hc_gen_dev * hcd)228 int ehci_bus_suspend (struct hc_gen_dev *hcd)
229 {
230     __inf("ERR: Not support suspend.\n");
231     return 0;
232 }
233 
234 
ehci_bus_resume(struct hc_gen_dev * hcd)235 int ehci_bus_resume (struct hc_gen_dev *hcd)
236 {
237     __inf("ERR: Not support resume.\n");
238     return 0;
239 }
240 //static int ehci_bus_suspend (struct hc_gen_hcd **hcd)
241 //{
242 //  struct ehci_hcd     *ehci = hcd_to_ehci (hcd);
243 //  int         port;
244 //  int         mask;
245 //  int         changed;
246 //  bool            fs_idle_delay;
247 //
248 //  ehci_dbg("suspend root hub\n");
249 //
250 //  if (time_before (jiffies, ehci->next_statechange))
251 //      hal_msleep(5);
252 //
253 //  /* stop the schedules */
254 //  ehci_quiesce(ehci);
255 //
256 //  spin_lock_irq (&ehci->lock);
257 //  if (ehci->rh_state < EHCI_RH_RUNNING)
258 //      goto done;
259 //
260 //  /* Once the controller is stopped, port resumes that are already
261 //   * in progress won't complete.  Hence if remote wakeup is enabled
262 //   * for the root hub and any ports are in the middle of a resume or
263 //   * remote wakeup, we must fail the suspend.
264 //   */
265 //  if (hcd->self.root_hub->do_remote_wakeup) {
266 //      if (ehci->resuming_ports) {
267 //          spin_unlock_irq(&ehci->lock);
268 //          ehci_dbg("suspend failed because a port is resuming\n");
269 //          return -EBUSY;
270 //      }
271 //  }
272 //
273 //  /* Unlike other USB host controller types, EHCI doesn't have
274 //   * any notion of "global" or bus-wide suspend.  The driver has
275 //   * to manually suspend all the active unsuspended ports, and
276 //   * then manually resume them in the bus_resume() routine.
277 //   */
278 //  ehci->bus_suspended = 0;
279 //  ehci->owned_ports = 0;
280 //  changed = 0;
281 //  fs_idle_delay = false;
282 //  port = HCS_N_PORTS(ehci->hcs_params);
283 //  while (port--) {
284 //      u32 __iomem *reg = &ehci->regs->port_status [port];
285 //      u32     t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
286 //      u32     t2 = t1 & ~PORT_WAKE_BITS;
287 //
288 //      /* keep track of which ports we suspend */
289 //      if (t1 & PORT_OWNER)
290 //          usb_set_bit(port, &ehci->owned_ports);
291 //      else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
292 //          t2 |= PORT_SUSPEND;
293 //          usb_set_bit(port, &ehci->bus_suspended);
294 //      }
295 //
296 //      /* enable remote wakeup on all ports, if told to do so */
297 //      if (hcd->self.root_hub->do_remote_wakeup) {
298 //          /* only enable appropriate wake bits, otherwise the
299 //           * hardware can not go phy low power mode. If a race
300 //           * condition happens here(connection change during bits
301 //           * set), the port change detection will finally fix it.
302 //           */
303 //          if (t1 & PORT_CONNECT)
304 //              t2 |= PORT_WKOC_E | PORT_WKDISC_E;
305 //          else
306 //              t2 |= PORT_WKOC_E | PORT_WKCONN_E;
307 //      }
308 //
309 //      if (t1 != t2) {
310 //          /*
311 //           * On some controllers, Wake-On-Disconnect will
312 //           * generate false wakeup signals until the bus
313 //           * switches over to full-speed idle.  For their
314 //           * sake, add a delay if we need one.
315 //           */
316 //          if ((t2 & PORT_WKDISC_E) &&
317 //                  ehci_port_speed(ehci, t2) ==
318 //                      USB_PORT_STAT_HIGH_SPEED)
319 //              fs_idle_delay = true;
320 //          ehci_writel(ehci, t2, reg);
321 //          changed = 1;
322 //      }
323 //  }
324 //  spin_unlock_irq(&ehci->lock);
325 //
326 //  if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) {
327 //      /*
328 //       * Wait for HCD to enter low-power mode or for the bus
329 //       * to switch to full-speed idle.
330 //       */
331 //      usleep_range(5000, 5500);
332 //  }
333 //
334 //  if (changed && ehci->has_tdi_phy_lpm) {
335 //      spin_lock_irq(&ehci->lock);
336 //      port = HCS_N_PORTS(ehci->hcs_params);
337 //      while (port--) {
338 //          u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
339 //          u32     t3;
340 //
341 //          t3 = ehci_readl(ehci, hostpc_reg);
342 //          ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
343 //          t3 = ehci_readl(ehci, hostpc_reg);
344 //          ehci_dbg("Port %d phy low-power mode %s\n",
345 //                  port, (t3 & HOSTPC_PHCD) ?
346 //                  "succeeded" : "failed");
347 //      }
348 //      spin_unlock_irq(&ehci->lock);
349 //  }
350 //
351 //  /* Apparently some devices need a >= 1-uframe delay here */
352 //  if (ehci->bus_suspended)
353 //      udelay(150);
354 //
355 //  /* turn off now-idle HC */
356 //  ehci_halt (ehci);
357 //
358 //  spin_lock_irq(&ehci->lock);
359 //  if (ehci->enabled_hrtimer_events & BIT(EHCI_HRTIMER_POLL_DEAD))
360 //      ehci_handle_controller_death(ehci);
361 //  if (ehci->rh_state != EHCI_RH_RUNNING)
362 //      goto done;
363 //  ehci->rh_state = EHCI_RH_SUSPENDED;
364 //
365 //  unlink_empty_async_suspended(ehci);
366 //
367 //  /* Any IAA cycle that started before the suspend is now invalid */
368 //  end_iaa_cycle(ehci);
369 //  ehci_handle_start_intr_unlinks(ehci);
370 //  ehci_handle_intr_unlinks(ehci);
371 //  end_free_itds(ehci);
372 //
373 //  /* allow remote wakeup */
374 //  mask = INTR_MASK;
375 //  if (!hcd->self.root_hub->do_remote_wakeup)
376 //      mask &= ~STS_PCD;
377 //  ehci_writel(ehci, mask, &ehci->regs->intr_enable);
378 //  ehci_readl(ehci, &ehci->regs->intr_enable);
379 //
380 // done:
381 //  ehci->next_statechange = jiffies + msecs_to_jiffies(10);
382 //  ehci->enabled_hrtimer_events = 0;
383 //  ehci->next_hrtimer_event = EHCI_HRTIMER_NO_EVENT;
384 //  spin_unlock_irq (&ehci->lock);
385 //
386 //  hrtimer_cancel(&ehci->hrtimer);
387 //  return 0;
388 //}
389 
390 
391 /* caller has locked the root hub, and should reset/reinit on error */
392 //static int ehci_bus_resume (struct hc_gen_hcd **hcd)
393 //{
394 //  struct ehci_hcd     *ehci = hcd_to_ehci (hcd);
395 //  u32         temp;
396 //  u32         power_okay;
397 //  int         i;
398 //  unsigned long       resume_needed = 0;
399 //
400 //  if (time_before (jiffies, ehci->next_statechange))
401 //      hal_msleep(5);
402 //  spin_lock_irq (&ehci->lock);
403 //  if (!HCD_HW_ACCESSIBLE(hcd) || ehci->shutdown)
404 //      goto shutdown;
405 //
406 //  if (unlikely(ehci->debug)) {
407 //      if (!dbgp_reset_prep(hcd))
408 //          ehci->debug = NULL;
409 //      else
410 //          dbgp_external_startup(hcd);
411 //  }
412 //
413 //  /* Ideally and we've got a real resume here, and no port's power
414 //   * was lost.  (For PCI, that means Vaux was maintained.)  But we
415 //   * could instead be restoring a swsusp snapshot -- so that BIOS was
416 //   * the last user of the controller, not reset/pm hardware keeping
417 //   * state we gave to it.
418 //   */
419 //  power_okay = ehci_readl(ehci, &ehci->regs->intr_enable);
420 //  ehci_dbg("resume root hub%s\n",
421 //          power_okay ? "" : " after power loss");
422 //
423 //  /* at least some APM implementations will try to deliver
424 //   * IRQs right away, so delay them until we're ready.
425 //   */
426 //  ehci_writel(ehci, 0, &ehci->regs->intr_enable);
427 //
428 //  /* re-init operational registers */
429 //  ehci_writel(ehci, 0, &ehci->regs->segment);
430 //  ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
431 //  ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
432 //
433 //  /* restore CMD_RUN, framelist size, and irq threshold */
434 //  ehci->command |= CMD_RUN;
435 //  ehci_writel(ehci, ehci->command, &ehci->regs->command);
436 //  ehci->rh_state = EHCI_RH_RUNNING;
437 //
438 //  /*
439 //   * According to Bugzilla #8190, the port status for some controllers
440 //   * will be wrong without a delay. At their wrong status, the port
441 //   * is enabled, but not suspended neither resumed.
442 //   */
443 //  i = HCS_N_PORTS(ehci->hcs_params);
444 //  while (i--) {
445 //      temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
446 //      if ((temp & PORT_PE) &&
447 //              !(temp & (PORT_SUSPEND | PORT_RESUME))) {
448 //          ehci_dbg("Port status(0x%x) is wrong\n", temp);
449 //          spin_unlock_irq(&ehci->lock);
450 //          hal_msleep(8);
451 //          spin_lock_irq(&ehci->lock);
452 //          break;
453 //      }
454 //  }
455 //
456 //  if (ehci->shutdown)
457 //      goto shutdown;
458 //
459 //  /* clear phy low-power mode before resume */
460 //  if (ehci->bus_suspended && ehci->has_tdi_phy_lpm) {
461 //      i = HCS_N_PORTS(ehci->hcs_params);
462 //      while (i--) {
463 //          if (usb_test_bit(i, &ehci->bus_suspended)) {
464 //              u32 __iomem *hostpc_reg =
465 //                          &ehci->regs->hostpc[i];
466 //
467 //              temp = ehci_readl(ehci, hostpc_reg);
468 //              ehci_writel(ehci, temp & ~HOSTPC_PHCD,
469 //                      hostpc_reg);
470 //          }
471 //      }
472 //      spin_unlock_irq(&ehci->lock);
473 //      hal_msleep(5);
474 //      spin_lock_irq(&ehci->lock);
475 //      if (ehci->shutdown)
476 //          goto shutdown;
477 //  }
478 //
479 //  /* manually resume the ports we suspended during bus_suspend() */
480 //  i = HCS_N_PORTS (ehci->hcs_params);
481 //  while (i--) {
482 //      temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
483 //      temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
484 //      if (usb_test_bit(i, &ehci->bus_suspended) &&
485 //              (temp & PORT_SUSPEND)) {
486 //          temp |= PORT_RESUME;
487 //          usb_set_bit(i, &resume_needed);
488 //      }
489 //      ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
490 //  }
491 //
492 //  /*
493 //   * hal_msleep for USB_RESUME_TIMEOUT ms only if code is trying to resume
494 //   * port
495 //   */
496 //  if (resume_needed) {
497 //      spin_unlock_irq(&ehci->lock);
498 //      hal_msleep(USB_RESUME_TIMEOUT);
499 //      spin_lock_irq(&ehci->lock);
500 //      if (ehci->shutdown)
501 //          goto shutdown;
502 //  }
503 //
504 //  i = HCS_N_PORTS (ehci->hcs_params);
505 //  while (i--) {
506 //      temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
507 //      if (usb_test_bit(i, &resume_needed)) {
508 //          temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
509 //          ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
510 //      }
511 //  }
512 //
513 //  ehci->next_statechange = jiffies + msecs_to_jiffies(5);
514 //  spin_unlock_irq(&ehci->lock);
515 //
516 //  ehci_handover_companion_ports(ehci);
517 //
518 //  /* Now we can safely re-enable irqs */
519 //  spin_lock_irq(&ehci->lock);
520 //  if (ehci->shutdown)
521 //      goto shutdown;
522 //  ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
523 //  (void) ehci_readl(ehci, &ehci->regs->intr_enable);
524 //  spin_unlock_irq(&ehci->lock);
525 //
526 //  return 0;
527 //
528 // shutdown:
529 //  spin_unlock_irq(&ehci->lock);
530 //  return -ESHUTDOWN;
531 //}
532 //
533 //#else
534 //
535 //#define ehci_bus_suspend  NULL
536 //#define ehci_bus_resume       NULL
537 //
538 //#endif    /* CONFIG_PM */
539 
540 /*-------------------------------------------------------------------------*/
541 
542 /*
543  * Sets the owner of a port
544  */
set_owner(struct ehci_hcd * ehci,int portnum,int new_owner)545 static void set_owner(struct ehci_hcd *ehci, int portnum, int new_owner)
546 {
547     //u32 __iomem       *status_reg;
548     u32         port_status;
549     int             try;
550     //status_reg = &ehci->regs->port_status[portnum];
551 
552     /*
553      * The controller won't set the OWNER bit if the port is
554      * enabled, so this loop will sometimes require at least two
555      * iterations: one to disable the port and one to set OWNER.
556      */
557     for (try = 4; try > 0; --try) {
558         hal_spin_lock(&ehci->lock);
559         port_status = ehci_readl(ehci,
560                 &ehci->regs->port_status[portnum]);
561         if ((port_status & PORT_OWNER) == new_owner
562                 || (port_status & (PORT_OWNER | PORT_CONNECT))
563                     == 0)
564             try = 0;
565         else {
566             port_status ^= PORT_OWNER;
567             port_status &= ~(PORT_PE | PORT_RWC_BITS);
568             ehci_writel(ehci, port_status,
569                     &ehci->regs->port_status[portnum]);
570         }
571         hal_spin_unlock(&ehci->lock);
572         if (try > 1)
573             hal_msleep(5);
574     }
575 }
576 
577 /*-------------------------------------------------------------------------*/
578 
check_reset_complete(struct ehci_hcd * ehci,int index,u32 * status_reg,int port_status)579 static int check_reset_complete (
580     struct ehci_hcd *ehci,
581     int     index,
582     u32     *status_reg,
583     int     port_status
584 ) {
585     if (!(port_status & PORT_CONNECT))
586         return port_status;
587 
588     /* if reset finished and it's still not enabled -- handoff */
589     if (!(port_status & PORT_PE)) {
590 
591         /* with integrated TT, there's nobody to hand it to! */
592         //if (ehci_is_TDI(ehci)) {
593         //  ehci_dbg("Failed to enable port %d on root hub TT\n",
594         //      index+1);
595         //  return port_status;
596         //}
597 
598         ehci_dbg("port %d full speed --> companion\n",
599             index + 1);
600 
601         // what happens if HCS_N_CC(params) == 0 ?
602         port_status |= PORT_OWNER;
603         port_status &= ~PORT_RWC_BITS;
604         ehci_writel(ehci, port_status, status_reg);
605 
606         /* ensure 440EPX ohci controller state is operational */
607         if (ehci->has_amcc_usb23)
608             set_ohci_hcfs(ehci, 1);
609     } else {
610         ehci_dbg("port %d reset complete, port enabled\n",
611             index + 1);
612         /* ensure 440EPx ohci controller state is suspended */
613         if (ehci->has_amcc_usb23)
614             set_ohci_hcfs(ehci, 0);
615     }
616 
617     return port_status;
618 }
619 
620 /*-------------------------------------------------------------------------*/
621 
622 
623 /* build "status change" packet (one or two bytes) from HC registers */
624 
ehci_hub_status_data(struct hc_gen_dev * hcd,char * buf)625 int ehci_hub_status_data (struct hc_gen_dev *hcd, char *buf)
626 {
627     struct ehci_hcd *ehci = hcd_to_ehci (hcd);
628     u32     temp, status;
629     u32     mask;
630     int     ports, i, retval = 1;
631     unsigned long   flags;
632     u32     ppcd = ~0;
633 
634     /* init status to no-changes */
635     buf [0] = 0;
636     ports = HCS_N_PORTS (ehci->hcs_params);
637     if (ports > 7) {
638         buf [1] = 0;
639         retval++;
640     }
641 
642     /* Inform the core about resumes-in-progress by returning
643      * a non-zero value even if there are no status changes.
644      */
645     status = ehci->resuming_ports;
646 
647     /* Some boards (mostly VIA?) report bogus overcurrent indications,
648      * causing massive log spam unless we completely ignore them.  It
649      * may be relevant that VIA VT8235 controllers, where PORT_POWER is
650      * always set, seem to clear PORT_OCC and PORT_CSC when writing to
651      * PORT_POWER; that's surprising, but maybe within-spec.
652      */
653     //if (!ignore_oc)
654     //  mask = PORT_CSC | PORT_PEC | PORT_OCC;
655     //else
656         mask = PORT_CSC | PORT_PEC;
657     // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
658 
659     /* no hub change reports (bit 0) for now (power, ...) */
660 
661     /* port N changes (bit N)? */
662     flags = hal_spin_lock_irqsave(&ehci->lock);
663 
664     /* get per-port change detect bits */
665     if (ehci->has_ppcd)
666         ppcd = ehci_readl(ehci, &ehci->regs->status) >> 16;
667 
668     for (i = 0; i < ports; i++) {
669         /* leverage per-port change bits feature */
670         if (ppcd & (1 << i))
671             temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
672         else
673             temp = 0;
674 
675         /*
676          * Return status information even for ports with OWNER set.
677          * Otherwise hub_wq wouldn't see the disconnect event when a
678          * high-speed device is switched over to the companion
679          * controller by the user.
680          */
681 
682         if ((temp & mask) != 0 || usb_test_bit(i, (volatile uint32_t *)&ehci->port_c_suspend)) {
683                 //|| (ehci->reset_done[i] && time_after_eq(
684                 //  jiffies, ehci->reset_done[i]))) {
685             if (i < 7)
686                 buf [0] |= 1 << (i + 1);
687             else
688                 buf [1] |= 1 << (i - 7);
689             status = STS_PCD;
690         }
691     }
692 
693     /* If a resume is in progress, make sure it can finish */
694     /*
695     if (ehci->resuming_ports)
696         mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25));
697     */
698     hal_spin_unlock_irqrestore (&ehci->lock, flags);
699     return status ? retval : 0;
700 }
701 
702 /*-------------------------------------------------------------------------*/
703 
704 static void
ehci_hub_descriptor(struct ehci_hcd * ehci,struct usb_hub_descriptor * desc)705 ehci_hub_descriptor (
706     struct ehci_hcd         *ehci,
707     struct usb_hub_descriptor   *desc
708 ) {
709     int     ports = HCS_N_PORTS (ehci->hcs_params);
710     u16     temp;
711 
712     desc->bDescriptorType = USB_DT_HUB;
713     desc->bPwrOn2PwrGood = 10;  /* ehci 1.0, 2.3.9 says 20ms max */
714     desc->bHubContrCurrent = 0;
715 
716     desc->bNbrPorts = ports;
717     temp = 1 + (ports / 8);
718     desc->bDescLength = 7 + 2 * temp;
719 
720     /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
721     memset(&desc->DeviceRemovable[0], 0, temp);
722     memset(&desc->DeviceRemovable[temp], 0xff, temp);
723 
724     //temp = HUB_CHAR_INDV_PORT_OCPM;   /* per-port overcurrent reporting */
725     //if (HCS_PPC (ehci->hcs_params))
726     //  temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */
727     //else
728     //  temp |= HUB_CHAR_NO_LPSM; /* no power switching */
729 #if 0
730 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
731     if (HCS_INDICATOR (ehci->hcs_params))
732         temp |= HUB_CHAR_PORTIND; /* per-port indicators (LEDs) */
733 #endif
734     desc->wHubCharacteristics = cpu_to_le16(temp);
735 }
736 
737 /*-------------------------------------------------------------------------*/
738 
ehci_hub_control(struct hc_gen_dev * hcd,u16 typeReq,u16 wValue,u16 wIndex,char * buf,u16 wLength)739 int ehci_hub_control(
740     struct hc_gen_dev *hcd,
741     u16     typeReq,
742     u16     wValue,
743     u16     wIndex,
744     char        *buf,
745     u16     wLength
746 ) {
747     struct ehci_hcd *ehci = hcd_to_ehci (hcd);
748     int     ports = HCS_N_PORTS (ehci->hcs_params);
749     u32     *status_reg, *hostpc_reg;
750     u32     temp, temp1, status;
751     uint32_t    flags;
752     int     retval = 0;
753     unsigned    selector;
754 
755     /*
756      * Avoid underflow while calculating (wIndex & 0xff) - 1.
757      * The compiler might deduce that wIndex can never be 0 and then
758      * optimize away the tests for !wIndex below.
759      */
760     temp = wIndex & 0xff;
761     temp -= (temp > 0);
762     status_reg = &ehci->regs->port_status[temp];
763     hostpc_reg = &ehci->regs->hostpc[temp];
764 
765     //printf("[%s %d] typeReq = 0x%x, wValue = 0x%x, wIndex = 0x%x, wLength = 0x%x, status_reg = 0x%lx\n", __func__, __LINE__,
766      //                  typeReq, wValue, wIndex, wLength, ehci_readl(ehci, status_reg));
767 
768     /*
769      * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
770      * HCS_INDICATOR may say we can change LEDs to off/amber/green.
771      * (track current state ourselves) ... blink for diagnostics,
772      * power, "this is the one", etc.  EHCI spec supports this.
773      */
774 
775     flags = hal_spin_lock_irqsave(&ehci->lock);
776     switch (typeReq) {
777     case ClearHubFeature:
778         switch (wValue) {
779         case C_HUB_LOCAL_POWER:
780         case C_HUB_OVER_CURRENT:
781             /* no hub-wide feature/status flags */
782             break;
783         default:
784             goto error;
785         }
786         break;
787     case ClearPortFeature:
788         if (!wIndex || wIndex > ports)
789             goto error;
790         wIndex--;
791         temp = ehci_readl(ehci, status_reg);
792         temp &= ~PORT_RWC_BITS;
793 
794         /*
795          * Even if OWNER is set, so the port is owned by the
796          * companion controller, hub_wq needs to be able to clear
797          * the port-change status bits (especially
798          * USB_PORT_STAT_C_CONNECTION).
799          */
800         switch (wValue) {
801         case USB_PORT_FEAT_ENABLE:
802             ehci_writel(ehci, temp & ~PORT_PE, status_reg);
803             break;
804         case USB_PORT_FEAT_C_ENABLE:
805             ehci_writel(ehci, temp | PORT_PEC, status_reg);
806             break;
807         case USB_PORT_FEAT_SUSPEND:
808             if (temp & PORT_RESET)
809                 goto error;
810             if (ehci->no_selective_suspend)
811                 break;
812             if (!(temp & PORT_SUSPEND))
813                 break;
814             if ((temp & PORT_PE) == 0)
815                 goto error;
816 
817             /* clear phy low-power mode before resume */
818             if (ehci->has_tdi_phy_lpm) {
819                 temp1 = ehci_readl(ehci, hostpc_reg);
820                 ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
821                         hostpc_reg);
822                 hal_spin_unlock_irqrestore(&ehci->lock, flags);
823                 hal_msleep(5);/* wait to leave low-power mode */
824                 flags = hal_spin_lock_irqsave(&ehci->lock);
825             }
826             /* resume signaling for 20 msec */
827             temp &= ~PORT_WAKE_BITS;
828             ehci_writel(ehci, temp | PORT_RESUME, status_reg);
829             //ehci->reset_done[wIndex] = jiffies
830             //      + msecs_to_jiffies(USB_RESUME_TIMEOUT);
831             usb_set_bit(wIndex, (volatile uint32_t *)&ehci->resuming_ports);
832             usb_hcd_start_port_resume(&hcd->self, wIndex);
833             break;
834         case USB_PORT_FEAT_C_SUSPEND:
835             usb_clear_bit(wIndex, (volatile uint32_t *)&ehci->port_c_suspend);
836             break;
837         case USB_PORT_FEAT_POWER:
838             if (HCS_PPC(ehci->hcs_params)) {
839                 hal_spin_unlock_irqrestore(&ehci->lock, flags);
840                 ehci_port_power(ehci, wIndex, false);
841                 flags = hal_spin_lock_irqsave(&ehci->lock);
842             }
843             break;
844         case USB_PORT_FEAT_C_CONNECTION:
845             ehci_writel(ehci, temp | PORT_CSC, status_reg);
846             break;
847         case USB_PORT_FEAT_C_OVER_CURRENT:
848             ehci_writel(ehci, temp | PORT_OCC, status_reg);
849             break;
850         case USB_PORT_FEAT_C_RESET:
851             /* GetPortStatus clears reset */
852             break;
853         default:
854             goto error;
855         }
856         ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */
857         break;
858     case GetHubDescriptor:
859         ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
860             buf);
861         break;
862     case GetHubStatus:
863         /* no hub-wide feature/status flags */
864         memset (buf, 0, 4);
865         //cpu_to_le32s ((u32 *) buf);
866         break;
867     case GetPortStatus:
868         if (!wIndex || wIndex > ports)
869             goto error;
870         wIndex--;
871         status = 0;
872         temp = ehci_readl(ehci, status_reg);
873 
874         // wPortChange bits
875         if (temp & PORT_CSC)
876             status |= USB_PORT_STAT_C_CONNECTION << 16;
877         if (temp & PORT_PEC)
878             status |= USB_PORT_STAT_C_ENABLE << 16;
879 
880         //if ((temp & PORT_OCC) && !ignore_oc){
881         //  status |= USB_PORT_STAT_C_OVERCURRENT << 16;
882 
883         //  /*
884         //   * Hubs should disable port power on over-current.
885         //   * However, not all EHCI implementations do this
886         //   * automatically, even if they _do_ support per-port
887         //   * power switching; they're allowed to just limit the
888         //   * current.  hub_wq will turn the power back on.
889         //   */
890         //  if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle))
891         //          && HCS_PPC(ehci->hcs_params)) {
892         //      spin_unlock_irqrestore(&ehci->lock, flags);
893         //      ehci_port_power(ehci, wIndex, false);
894         //      spin_lock_irqsave(&ehci->lock, flags);
895         //      temp = ehci_readl(ehci, status_reg);
896         //  }
897         //}
898 
899         /* no reset or resume pending */
900         if (!ehci->reset_done[wIndex]) {
901 
902             /* Remote Wakeup received? */
903         //  if (temp & PORT_RESUME) {
904         //      /* resume signaling for 20 msec */
905         //      ehci->reset_done[wIndex] = jiffies
906         //              + msecs_to_jiffies(20);
907         //      usb_hcd_start_port_resume(&hcd->self, wIndex);
908         //      usb_set_bit(wIndex, &ehci->resuming_ports);
909         //      /* check the port again */
910         //      mod_timer(&ehci_to_hcd(ehci)->rh_timer,
911         //              ehci->reset_done[wIndex]);
912         //  }
913 
914         /* reset or resume not yet complete */
915         //} else if (!time_after_eq(jiffies, ehci->reset_done[wIndex])) {
916         //  ;   /* wait until it is complete */
917 
918         /* resume completed */
919         } else if (usb_test_bit(wIndex, (volatile uint32_t *)&ehci->resuming_ports)) {
920         //  usb_clear_bit(wIndex, &ehci->suspended_ports);
921         //  usb_set_bit(wIndex, &ehci->port_c_suspend);
922         //  ehci->reset_done[wIndex] = 0;
923         //  usb_hcd_end_port_resume(&hcd->self, wIndex);
924 
925         //  /* stop resume signaling */
926         //  temp &= ~(PORT_RWC_BITS | PORT_SUSPEND | PORT_RESUME);
927         //  ehci_writel(ehci, temp, status_reg);
928         //  usb_clear_bit(wIndex, &ehci->resuming_ports);
929         //  retval = ehci_handshake(ehci, status_reg,
930         //          PORT_RESUME, 0, 2000 /* 2msec */);
931         //  if (retval != 0) {
932         //      ehci_dbg("port %d resume error %d\n",
933         //              wIndex + 1, retval);
934         //      goto error;
935         //  }
936         //  temp = ehci_readl(ehci, status_reg);
937 
938         /* whoever resets must GetPortStatus to complete it!! */
939         } else {
940             /* FIXME: we need to implement time_after_eq or
941              * something similar to wait reset complete.
942              */
943             hal_spin_unlock_irqrestore(&ehci->lock, flags);
944             hal_msleep(50);
945             flags = hal_spin_lock_irqsave(&ehci->lock);
946 
947             status |= USB_PORT_STAT_C_RESET << 16;
948             ehci->reset_done [wIndex] = 0;
949 
950             /* force reset to complete */
951             ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
952                     status_reg);
953             /* REVISIT:  some hardware needs 550+ usec to clear
954              * this bit; seems too long to spin routinely...
955              */
956             retval = ehci_handshake(ehci, status_reg,
957                     PORT_RESET, 0, 1000);
958             if (retval != 0) {
959                 ehci_err ("port %d reset error %d\n",
960                     wIndex + 1, retval);
961                 goto error;
962             }
963 
964             /* see what we found out */
965             temp = check_reset_complete (ehci, wIndex, status_reg,
966                     ehci_readl(ehci, status_reg));
967         }
968 
969         /* transfer dedicated ports to the companion hc */
970         if ((temp & PORT_CONNECT) &&
971                 usb_test_bit(wIndex, (volatile uint32_t *)&ehci->companion_ports)) {
972             temp &= ~PORT_RWC_BITS;
973             temp |= PORT_OWNER;
974             ehci_writel(ehci, temp, status_reg);
975             ehci_dbg("port %d --> companion\n", wIndex + 1);
976             temp = ehci_readl(ehci, status_reg);
977         }
978 
979         /*
980          * Even if OWNER is set, there's no harm letting hub_wq
981          * see the wPortStatus values (they should all be 0 except
982          * for PORT_POWER anyway).
983          */
984 
985         if (temp & PORT_CONNECT) {
986             status |= USB_PORT_STAT_CONNECTION;
987             // status may be from integrated TT
988             if (ehci->has_hostpc) {
989                 temp1 = ehci_readl(ehci, hostpc_reg);
990                 //status |= ehci_port_speed(ehci, temp1);
991                 status |= USB_PORT_STAT_HIGH_SPEED;
992             } else
993                 //status |= ehci_port_speed(ehci, temp);
994                 status |= USB_PORT_STAT_HIGH_SPEED;
995         }
996         if (temp & PORT_PE)
997             status |= USB_PORT_STAT_ENABLE;
998 
999         /* maybe the port was unsuspended without our knowledge */
1000         //if (temp & (PORT_SUSPEND|PORT_RESUME)) {
1001         //  status |= USB_PORT_STAT_SUSPEND;
1002         //} else if (usb_test_bit(wIndex, &ehci->suspended_ports)) {
1003         //  usb_clear_bit(wIndex, &ehci->suspended_ports);
1004         //  usb_clear_bit(wIndex, &ehci->resuming_ports);
1005         //  ehci->reset_done[wIndex] = 0;
1006         //  if (temp & PORT_PE)
1007         //      usb_set_bit(wIndex, &ehci->port_c_suspend);
1008         //  usb_hcd_end_port_resume(&hcd->self, wIndex);
1009         //}
1010 
1011         if (temp & PORT_OC)
1012             status |= USB_PORT_STAT_OVERCURRENT;
1013         if (temp & PORT_RESET)
1014             status |= USB_PORT_STAT_RESET;
1015         if (temp & PORT_POWER)
1016             status |= USB_PORT_STAT_POWER;
1017         if (usb_test_bit(wIndex, (volatile uint32_t *)&ehci->port_c_suspend))
1018             status |= USB_PORT_STAT_C_SUSPEND << 16;
1019 
1020         //if (status & ~0xffff) /* only if wPortChange is interesting */
1021             //ehci_dbg("GetStatus", wIndex + 1, temp);
1022         //put_unaligned_le32(status, buf);
1023         *(u32 *)buf = status;
1024         break;
1025     case SetHubFeature:
1026         switch (wValue) {
1027         case C_HUB_LOCAL_POWER:
1028         case C_HUB_OVER_CURRENT:
1029             /* no hub-wide feature/status flags */
1030             break;
1031         default:
1032             goto error;
1033         }
1034         break;
1035     case SetPortFeature:
1036         selector = wIndex >> 8;
1037         wIndex &= 0xff;
1038         //if (unlikely(ehci->debug)) {
1039         //  /* If the debug port is active any port
1040         //   * feature requests should get denied */
1041         //  if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
1042         //      (readl(&ehci->debug->control) & DBGP_ENABLED)) {
1043         //      retval = -ENODEV;
1044         //      goto error_exit;
1045         //  }
1046         //}
1047         if (!wIndex || wIndex > ports)
1048             goto error;
1049         wIndex--;
1050         temp = ehci_readl(ehci, status_reg);
1051         if (temp & PORT_OWNER)
1052             break;
1053 
1054         temp &= ~PORT_RWC_BITS;
1055         switch (wValue) {
1056         case USB_PORT_FEAT_SUSPEND:
1057             if (ehci->no_selective_suspend)
1058                 break;
1059             if ((temp & PORT_PE) == 0
1060                     || (temp & PORT_RESET) != 0)
1061                 goto error;
1062 
1063             /* After above check the port must be connected.
1064              * Set appropriate bit thus could put phy into low power
1065              * mode if we have tdi_phy_lpm feature
1066              */
1067             temp &= ~PORT_WKCONN_E;
1068             temp |= PORT_WKDISC_E | PORT_WKOC_E;
1069             ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
1070             if (ehci->has_tdi_phy_lpm) {
1071                 hal_spin_unlock_irqrestore(&ehci->lock, flags);
1072                 hal_msleep(5);/* 5ms for HCD enter low pwr mode */
1073                 flags = hal_spin_lock_irqsave(&ehci->lock);
1074                 temp1 = ehci_readl(ehci, hostpc_reg);
1075                 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
1076                     hostpc_reg);
1077                 temp1 = ehci_readl(ehci, hostpc_reg);
1078                 ehci_dbg("Port%d phy low pwr mode %s\n",
1079                     wIndex, (temp1 & HOSTPC_PHCD) ?
1080                     "succeeded" : "failed");
1081             }
1082             usb_set_bit(wIndex, (volatile uint32_t *)&ehci->suspended_ports);
1083             break;
1084         case USB_PORT_FEAT_POWER:
1085             //if (HCS_PPC(ehci->hcs_params)) {
1086             //  hal_spin_unlock_irqrestore(flags);
1087             //  ehci_port_power(ehci, wIndex, true);
1088             //  flags = hal_spin_lock_irqsave();
1089             //}
1090             break;
1091         case USB_PORT_FEAT_RESET:
1092             if (temp & (PORT_SUSPEND|PORT_RESUME))
1093                 goto error;
1094             /* line status bits may report this as low speed,
1095              * which can be fine if this root hub has a
1096              * transaction translator built in.
1097              */
1098             if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
1099                     && PORT_USB11 (temp)) {
1100                 ehci_dbg("port %d low speed --> companion\n",
1101                     wIndex + 1);
1102                 temp |= PORT_OWNER;
1103             } else {
1104                 temp |= PORT_RESET;
1105                 temp &= ~PORT_PE;
1106 
1107                 /*
1108                  * caller must wait, then call GetPortStatus
1109                  * usb 2.0 spec says 50 ms resets on root
1110                  */
1111                 ehci->reset_done [wIndex] = 50;
1112 
1113                 /*
1114                  * Force full-speed connect for FSL high-speed
1115                  * erratum; disable HS Chirp by setting PFSC bit
1116                  */
1117                 if (ehci_has_fsl_hs_errata(ehci))
1118                     temp |= (1 << PORTSC_FSL_PFSC);
1119             }
1120             ehci_writel(ehci, temp, status_reg);
1121             break;
1122 
1123         /* For downstream facing ports (these):  one hub port is put
1124          * into test mode according to USB2 11.24.2.13, then the hub
1125          * must be reset (which for root hub now means rmmod+modprobe,
1126          * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
1127          * about the EHCI-specific stuff.
1128          */
1129 
1130         case USB_PORT_FEAT_TEST:
1131             //if (!selector || selector > 5)
1132             //  goto error;
1133             //hal_spin_unlock_irqrestore(flags);
1134             //ehci_quiesce(ehci);
1135             //flags = hal_spin_lock_irqsave();
1136 
1137             ///* Put all enabled ports into suspend */
1138             //while (ports--) {
1139             //  u32 __iomem *sreg =
1140             //          &ehci->regs->port_status[ports];
1141 
1142             //  temp = ehci_readl(ehci, sreg) & ~PORT_RWC_BITS;
1143             //  if (temp & PORT_PE)
1144             //      ehci_writel(ehci, temp | PORT_SUSPEND,
1145             //              sreg);
1146             //}
1147 
1148             //hal_spin_unlock_irqrestore(flags);
1149             //ehci_halt(ehci);
1150             //flags = hal_spin_lock_irqsave();
1151 
1152             //temp = ehci_readl(ehci, status_reg);
1153             //temp |= selector << 16;
1154             //ehci_writel(ehci, temp, status_reg);
1155             break;
1156 
1157         default:
1158             goto error;
1159         }
1160         ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
1161         break;
1162 
1163     default:
1164 error:
1165         /* "stall" on error */
1166         retval = -EPIPE;
1167     }
1168 error_exit:
1169     hal_spin_unlock_irqrestore(&ehci->lock, flags);
1170     return retval;
1171 }
1172 
ehci_relinquish_port(struct hc_gen_dev * hcd,int portnum)1173 static void ehci_relinquish_port(struct hc_gen_dev *hcd, int portnum)
1174 {
1175     struct ehci_hcd     *ehci = hcd_to_ehci(hcd);
1176 
1177     set_owner(ehci, --portnum, PORT_OWNER);
1178 }
1179 
ehci_port_handed_over(struct hc_gen_dev * hcd,int portnum)1180 static int ehci_port_handed_over(struct hc_gen_dev *hcd, int portnum)
1181 {
1182     struct ehci_hcd     *ehci = hcd_to_ehci(hcd);
1183     u32         *reg;
1184 
1185     reg = &ehci->regs->port_status[portnum - 1];
1186     return ehci_readl(ehci, reg) & PORT_OWNER;
1187 }
1188 
ehci_port_power(struct ehci_hcd * ehci,int portnum,bool enable)1189 static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable)
1190 {
1191     struct hc_gen_dev *hcd = ehci_to_hcd(ehci);
1192     u32 *status_reg = &ehci->regs->port_status[portnum];
1193     u32 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
1194 
1195     if (enable)
1196         ehci_writel(ehci, temp | PORT_POWER, status_reg);
1197     else
1198         ehci_writel(ehci, temp & ~PORT_POWER, status_reg);
1199 
1200     //if (hcd->driver->port_power)
1201     //  hcd->driver->port_power(hcd, portnum, enable);
1202 
1203     return 0;
1204 }
1205