Lines Matching +full:self +full:- +full:powered
1 // SPDX-License-Identifier: GPL-2.0
6 * Copyright (C) 2004-2005 David Brownell
23 * and usb-storage.
26 * - usb suspend/resume triggered by sl811
27 * - various issues noted in the code
28 * - performance work; use both register banks; ...
29 * - use urb->iso_frame_desc[] with ISO transfers
64 MODULE_ALIAS("platform:sl811-hcd");
74 static const char hcd_name[] = "sl811-hcd";
76 /*-------------------------------------------------------------------------*/
82 /* hub is inactive unless the port is powered */ in port_power()
84 if (sl811->port1 & USB_PORT_STAT_POWER) in port_power()
87 sl811->port1 = USB_PORT_STAT_POWER; in port_power()
88 sl811->irq_enable = SL11H_INTMASK_INSRMV; in port_power()
90 sl811->port1 = 0; in port_power()
91 sl811->irq_enable = 0; in port_power()
92 hcd->state = HC_STATE_HALT; in port_power()
94 sl811->ctrl1 = 0; in port_power()
98 if (sl811->board && sl811->board->port_power) { in port_power()
100 dev_dbg(hcd->self.controller, "power %s\n", in port_power()
102 sl811->board->port_power(hcd->self.controller, is_on); in port_power()
106 if (sl811->board && sl811->board->reset) in port_power()
107 sl811->board->reset(hcd->self.controller); in port_power()
114 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in port_power()
116 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in port_power()
121 /*-------------------------------------------------------------------------*/
123 /* This is a PIO-only HCD. Queueing appends URBs to the endpoint's queue,
148 data_reg = sl811->data_reg; in setup_packet()
149 sl811_write_buf(sl811, addr, urb->setup_packet, len); in setup_packet()
154 writeb(SL_SETUP /* | ep->epnum */, data_reg); in setup_packet()
155 writeb(usb_pipedevice(urb->pipe), data_reg); in setup_packet()
160 ep->length = 0; in setup_packet()
176 do_out = urb->transfer_buffer_length && usb_pipein(urb->pipe); in status_packet()
177 data_reg = sl811->data_reg; in status_packet()
182 writeb((do_out ? SL_OUT : SL_IN) /* | ep->epnum */, data_reg); in status_packet()
183 writeb(usb_pipedevice(urb->pipe), data_reg); in status_packet()
190 ep->length = 0; in status_packet()
191 PACKET("STATUS%s/%s qh%p\n", ep->nak_count ? "/retry" : "", in status_packet()
197 * urb->iso_frame_desc is currently ignored here...
212 len = ep->maxpacket; in in_packet()
215 && usb_gettoggle(urb->dev, ep->epnum, 0)) in in_packet()
217 data_reg = sl811->data_reg; in in_packet()
222 writeb(SL_IN | ep->epnum, data_reg); in in_packet()
223 writeb(usb_pipedevice(urb->pipe), data_reg); in in_packet()
226 ep->length = min_t(u32, len, in in_packet()
227 urb->transfer_buffer_length - urb->actual_length); in in_packet()
228 PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", in in_packet()
229 !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); in in_packet()
233 * urb->iso_frame_desc is currently ignored here...
248 buf = urb->transfer_buffer + urb->actual_length; in out_packet()
251 len = min_t(u32, ep->maxpacket, in out_packet()
252 urb->transfer_buffer_length - urb->actual_length); in out_packet()
255 && usb_gettoggle(urb->dev, ep->epnum, 1)) in out_packet()
258 data_reg = sl811->data_reg; in out_packet()
265 writeb(SL_OUT | ep->epnum, data_reg); in out_packet()
266 writeb(usb_pipedevice(urb->pipe), data_reg); in out_packet()
270 ep->length = len; in out_packet()
271 PACKET("OUT%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", in out_packet()
272 !!usb_gettoggle(urb->dev, ep->epnum, 1), ep, len); in out_packet()
275 /*-------------------------------------------------------------------------*/
277 /* caller updates on-chip enables later */
281 if (sl811->irq_enable & SL11H_INTMASK_SOFINTR) in sofirq_on()
283 dev_dbg(sl811_to_hcd(sl811)->self.controller, "sof irq on\n"); in sofirq_on()
284 sl811->irq_enable |= SL11H_INTMASK_SOFINTR; in sofirq_on()
289 if (!(sl811->irq_enable & SL11H_INTMASK_SOFINTR)) in sofirq_off()
291 dev_dbg(sl811_to_hcd(sl811)->self.controller, "sof irq off\n"); in sofirq_off()
292 sl811->irq_enable &= ~SL11H_INTMASK_SOFINTR; in sofirq_off()
295 /*-------------------------------------------------------------------------*/
300 * transfers, scheduled round-robin.
310 if (sl811->next_periodic) { in start()
311 ep = sl811->next_periodic; in start()
312 sl811->next_periodic = ep->next; in start()
314 if (sl811->next_async) in start()
315 ep = sl811->next_async; in start()
316 else if (!list_empty(&sl811->async)) in start()
317 ep = container_of(sl811->async.next, in start()
327 if ((bank && sl811->active_b == ep) || sl811->active_a == ep) in start()
331 if (ep->schedule.next == &sl811->async) in start()
332 sl811->next_async = NULL; in start()
334 sl811->next_async = container_of(ep->schedule.next, in start()
338 if (unlikely(list_empty(&ep->hep->urb_list))) { in start()
339 dev_dbg(sl811_to_hcd(sl811)->self.controller, in start()
344 urb = container_of(ep->hep->urb_list.next, struct urb, urb_list); in start()
345 control = ep->defctrl; in start()
348 * packet, wait till the next frame. too-simple algorithm... in start()
351 fclock -= 100; /* setup takes not much time */ in start()
352 if (urb->dev->speed == USB_SPEED_LOW) { in start()
355 fclock -= 800; in start()
357 fclock -= ep->maxpacket << 8; in start()
361 if (ep->period) in start()
362 sl811->stat_overrun++; in start()
367 fclock -= 12000 / 19; /* 19 64byte packets/msec */ in start()
369 if (ep->period) in start()
370 sl811->stat_overrun++; in start()
374 } else if (ep->nak_count) in start()
379 switch (ep->nextpid) { in start()
393 dev_dbg(sl811_to_hcd(sl811)->self.controller, in start()
394 "bad ep%p pid %02x\n", ep, ep->nextpid); in start()
404 if (sl811->port1 & USB_PORT_STAT_SUSPEND) in start_transfer()
406 if (sl811->active_a == NULL) { in start_transfer()
407 sl811->active_a = start(sl811, SL811_EP_A(SL811_HOST_BUF)); in start_transfer()
408 if (sl811->active_a != NULL) in start_transfer()
409 sl811->jiffies_a = jiffies + MIN_JIFFIES; in start_transfer()
412 if (sl811->active_b == NULL) { in start_transfer()
413 sl811->active_b = start(sl811, SL811_EP_B(SL811_HOST_BUF)); in start_transfer()
414 if (sl811->active_b != NULL) in start_transfer()
415 sl811->jiffies_b = jiffies + MIN_JIFFIES; in start_transfer()
425 ) __releases(sl811->lock) __acquires(sl811->lock) in finish_request()
429 if (usb_pipecontrol(urb->pipe)) in finish_request()
430 ep->nextpid = USB_PID_SETUP; in finish_request()
433 spin_unlock(&sl811->lock); in finish_request()
435 spin_lock(&sl811->lock); in finish_request()
438 if (!list_empty(&ep->hep->urb_list)) in finish_request()
442 if (!list_empty(&ep->schedule)) { in finish_request()
443 list_del_init(&ep->schedule); in finish_request()
444 if (ep == sl811->next_async) in finish_request()
445 sl811->next_async = NULL; in finish_request()
450 dev_dbg(sl811_to_hcd(sl811)->self.controller, in finish_request()
451 "deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); in finish_request()
452 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { in finish_request()
454 struct sl811h_ep **prev = &sl811->periodic[i]; in finish_request()
457 prev = &temp->next; in finish_request()
459 *prev = ep->next; in finish_request()
460 sl811->load[i] -= ep->load; in finish_request()
462 ep->branch = PERIODIC_SIZE; in finish_request()
463 sl811->periodic_count--; in finish_request()
464 sl811_to_hcd(sl811)->self.bandwidth_allocated in finish_request()
465 -= ep->load / ep->period; in finish_request()
466 if (ep == sl811->next_periodic) in finish_request()
467 sl811->next_periodic = ep->next; in finish_request()
470 if (sl811->periodic_count == 0) in finish_request()
479 int urbstat = -EINPROGRESS; in done()
486 urb = container_of(ep->hep->urb_list.next, struct urb, urb_list); in done()
491 if (!ep->period) in done()
492 ep->nak_count++; in done()
493 ep->error_count = 0; in done()
497 struct usb_device *udev = urb->dev; in done()
501 /* urb->iso_frame_desc is currently ignored here... */ in done()
503 ep->nak_count = ep->error_count = 0; in done()
504 switch (ep->nextpid) { in done()
507 urb->actual_length += ep->length; in done()
508 usb_dotoggle(udev, ep->epnum, 1); in done()
509 if (urb->actual_length in done()
510 == urb->transfer_buffer_length) { in done()
511 if (usb_pipecontrol(urb->pipe)) in done()
512 ep->nextpid = USB_PID_ACK; in done()
517 else if (ep->length < ep->maxpacket in done()
518 || !(urb->transfer_flags in done()
525 buf = urb->transfer_buffer + urb->actual_length; in done()
527 len = ep->maxpacket - sl811_read(sl811, in done()
529 if (len > ep->length) { in done()
530 len = ep->length; in done()
531 urbstat = -EOVERFLOW; in done()
533 urb->actual_length += len; in done()
536 usb_dotoggle(udev, ep->epnum, 0); in done()
537 if (urbstat == -EINPROGRESS && in done()
538 (len < ep->maxpacket || in done()
539 urb->actual_length == in done()
540 urb->transfer_buffer_length)) { in done()
541 if (usb_pipecontrol(urb->pipe)) in done()
542 ep->nextpid = USB_PID_ACK; in done()
549 if (urb->transfer_buffer_length == urb->actual_length) in done()
550 ep->nextpid = USB_PID_ACK; in done()
551 else if (usb_pipeout(urb->pipe)) { in done()
553 ep->nextpid = USB_PID_OUT; in done()
556 ep->nextpid = USB_PID_IN; in done()
568 ep->nak_count = ep->error_count = 0; in done()
569 urbstat = -EPIPE; in done()
572 } else if (++ep->error_count >= 3) { in done()
574 urbstat = -ETIME; in done()
576 urbstat = -EOVERFLOW; in done()
578 urbstat = -EPROTO; in done()
579 ep->error_count = 0; in done()
584 if (urbstat != -EINPROGRESS || urb->unlinked) in done()
593 if (sl811->active_a && time_before_eq(sl811->jiffies_a, jiffies)) { in checkdone()
597 dev_dbg(sl811_to_hcd(sl811)->self.controller, in checkdone()
605 if (sl811->active_b && time_before_eq(sl811->jiffies_b, jiffies)) { in checkdone()
609 dev_dbg(sl811_to_hcd(sl811)->self.controller, in checkdone()
627 spin_lock(&sl811->lock); in sl811h_irq()
633 irqstat &= sl811->irq_enable; in sl811h_irq()
641 sl811->stat_lost++; in sl811h_irq()
649 done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF)); in sl811h_irq()
650 sl811->active_a = NULL; in sl811h_irq()
651 sl811->stat_a++; in sl811h_irq()
655 done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF)); in sl811h_irq()
656 sl811->active_b = NULL; in sl811h_irq()
657 sl811->stat_b++; in sl811h_irq()
663 index = sl811->frame++ % (PERIODIC_SIZE - 1); in sl811h_irq()
664 sl811->stat_sof++; in sl811h_irq()
666 /* be graceful about almost-inevitable periodic schedule in sl811h_irq()
670 if (sl811->next_periodic) { in sl811h_irq()
671 // dev_err(hcd->self.controller, "overrun to slot %d\n", index); in sl811h_irq()
672 sl811->stat_overrun++; in sl811h_irq()
674 if (sl811->periodic[index]) in sl811h_irq()
675 sl811->next_periodic = sl811->periodic[index]; in sl811h_irq()
680 sl811->stat_insrmv++; in sl811h_irq()
683 sl811->stat_wake = 0; in sl811h_irq()
684 sl811->stat_sof = 0; in sl811h_irq()
685 sl811->stat_a = 0; in sl811h_irq()
686 sl811->stat_b = 0; in sl811h_irq()
687 sl811->stat_lost = 0; in sl811h_irq()
689 sl811->ctrl1 = 0; in sl811h_irq()
690 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_irq()
692 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_irq()
693 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_irq()
696 if (sl811->active_a) { in sl811h_irq()
698 finish_request(sl811, sl811->active_a, in sl811h_irq()
699 container_of(sl811->active_a in sl811h_irq()
700 ->hep->urb_list.next, in sl811h_irq()
702 -ESHUTDOWN); in sl811h_irq()
703 sl811->active_a = NULL; in sl811h_irq()
706 if (sl811->active_b) { in sl811h_irq()
708 finish_request(sl811, sl811->active_b, in sl811h_irq()
709 container_of(sl811->active_b in sl811h_irq()
710 ->hep->urb_list.next, in sl811h_irq()
712 NULL, -ESHUTDOWN); in sl811h_irq()
713 sl811->active_b = NULL; in sl811h_irq()
721 sl811->port1 &= ~USB_PORT_STAT_CONNECTION; in sl811h_irq()
723 sl811->port1 |= USB_PORT_STAT_CONNECTION; in sl811h_irq()
725 sl811->port1 |= USB_PORT_STAT_C_CONNECTION << 16; in sl811h_irq()
728 if (sl811->port1 & USB_PORT_STAT_SUSPEND) { in sl811h_irq()
729 dev_dbg(hcd->self.controller, "wakeup\n"); in sl811h_irq()
730 sl811->port1 |= USB_PORT_STAT_C_SUSPEND << 16; in sl811h_irq()
731 sl811->stat_wake++; in sl811h_irq()
737 if (sl811->port1 & USB_PORT_STAT_ENABLE) in sl811h_irq()
740 if (retries--) in sl811h_irq()
744 if (sl811->periodic_count == 0 && list_empty(&sl811->async)) in sl811h_irq()
746 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_irq()
748 spin_unlock(&sl811->lock); in sl811h_irq()
753 /*-------------------------------------------------------------------------*/
766 int i, branch = -ENOSPC; in balance()
772 if (branch < 0 || sl811->load[branch] > sl811->load[i]) { in balance()
776 if ((sl811->load[j] + load) in balance()
788 /*-------------------------------------------------------------------------*/
796 struct usb_device *udev = urb->dev; in sl811h_urb_enqueue()
797 unsigned int pipe = urb->pipe; in sl811h_urb_enqueue()
805 struct usb_host_endpoint *hep = urb->ep; in sl811h_urb_enqueue()
809 return -ENOSPC; in sl811h_urb_enqueue()
813 if (!hep->hcpriv) { in sl811h_urb_enqueue()
816 return -ENOMEM; in sl811h_urb_enqueue()
819 spin_lock_irqsave(&sl811->lock, flags); in sl811h_urb_enqueue()
822 if (!(sl811->port1 & USB_PORT_STAT_ENABLE) in sl811h_urb_enqueue()
823 || !HC_IS_RUNNING(hcd->state)) { in sl811h_urb_enqueue()
824 retval = -ENODEV; in sl811h_urb_enqueue()
834 if (hep->hcpriv) { in sl811h_urb_enqueue()
836 ep = hep->hcpriv; in sl811h_urb_enqueue()
838 retval = -ENOMEM; in sl811h_urb_enqueue()
842 INIT_LIST_HEAD(&ep->schedule); in sl811h_urb_enqueue()
843 ep->udev = udev; in sl811h_urb_enqueue()
844 ep->epnum = epnum; in sl811h_urb_enqueue()
845 ep->maxpacket = usb_maxpacket(udev, urb->pipe); in sl811h_urb_enqueue()
846 ep->defctrl = SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENABLE; in sl811h_urb_enqueue()
850 ep->nextpid = USB_PID_SETUP; in sl811h_urb_enqueue()
852 ep->nextpid = USB_PID_OUT; in sl811h_urb_enqueue()
854 ep->nextpid = USB_PID_IN; in sl811h_urb_enqueue()
856 if (ep->maxpacket > H_MAXPACKET) { in sl811h_urb_enqueue()
858 dev_dbg(hcd->self.controller, in sl811h_urb_enqueue()
859 "dev %d ep%d maxpacket %d\n", udev->devnum, in sl811h_urb_enqueue()
860 epnum, ep->maxpacket); in sl811h_urb_enqueue()
861 retval = -EINVAL; in sl811h_urb_enqueue()
866 if (udev->speed == USB_SPEED_LOW) { in sl811h_urb_enqueue()
868 if (!(sl811->ctrl1 & SL11H_CTL1MASK_LSPD)) in sl811h_urb_enqueue()
869 ep->defctrl |= SL11H_HCTLMASK_PREAMBLE; in sl811h_urb_enqueue()
874 if (urb->interval > PERIODIC_SIZE) in sl811h_urb_enqueue()
875 urb->interval = PERIODIC_SIZE; in sl811h_urb_enqueue()
876 ep->period = urb->interval; in sl811h_urb_enqueue()
877 ep->branch = PERIODIC_SIZE; in sl811h_urb_enqueue()
879 ep->defctrl |= SL11H_HCTLMASK_ISOCH; in sl811h_urb_enqueue()
880 ep->load = usb_calc_bus_time(udev->speed, !is_out, in sl811h_urb_enqueue()
887 ep->hep = hep; in sl811h_urb_enqueue()
888 hep->hcpriv = ep; in sl811h_urb_enqueue()
895 if (list_empty(&ep->schedule)) in sl811h_urb_enqueue()
896 list_add_tail(&ep->schedule, &sl811->async); in sl811h_urb_enqueue()
900 urb->interval = ep->period; in sl811h_urb_enqueue()
901 if (ep->branch < PERIODIC_SIZE) { in sl811h_urb_enqueue()
907 urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) in sl811h_urb_enqueue()
908 + ep->branch; in sl811h_urb_enqueue()
912 retval = balance(sl811, ep->period, ep->load); in sl811h_urb_enqueue()
915 ep->branch = retval; in sl811h_urb_enqueue()
917 urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) in sl811h_urb_enqueue()
918 + ep->branch; in sl811h_urb_enqueue()
924 dev_dbg(hcd->self.controller, "schedule qh%d/%p branch %d\n", in sl811h_urb_enqueue()
925 ep->period, ep, ep->branch); in sl811h_urb_enqueue()
926 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { in sl811h_urb_enqueue()
927 struct sl811h_ep **prev = &sl811->periodic[i]; in sl811h_urb_enqueue()
931 if (ep->period > here->period) in sl811h_urb_enqueue()
933 prev = &here->next; in sl811h_urb_enqueue()
937 ep->next = here; in sl811h_urb_enqueue()
940 sl811->load[i] += ep->load; in sl811h_urb_enqueue()
942 sl811->periodic_count++; in sl811h_urb_enqueue()
943 hcd->self.bandwidth_allocated += ep->load / ep->period; in sl811h_urb_enqueue()
947 urb->hcpriv = hep; in sl811h_urb_enqueue()
949 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_urb_enqueue()
954 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_urb_enqueue()
966 spin_lock_irqsave(&sl811->lock, flags); in sl811h_urb_dequeue()
971 hep = urb->hcpriv; in sl811h_urb_dequeue()
972 ep = hep->hcpriv; in sl811h_urb_dequeue()
977 if (ep->hep->urb_list.next != &urb->urb_list) { in sl811h_urb_dequeue()
981 } else if (sl811->active_a == ep) { in sl811h_urb_dequeue()
982 if (time_before_eq(sl811->jiffies_a, jiffies)) { in sl811h_urb_dequeue()
984 dev_dbg(hcd->self.controller, in sl811h_urb_dequeue()
992 sl811->active_a = NULL; in sl811h_urb_dequeue()
996 } else if (sl811->active_b == ep) { in sl811h_urb_dequeue()
997 if (time_before_eq(sl811->jiffies_a, jiffies)) { in sl811h_urb_dequeue()
999 dev_dbg(hcd->self.controller, in sl811h_urb_dequeue()
1007 sl811->active_b = NULL; in sl811h_urb_dequeue()
1018 dev_dbg(sl811_to_hcd(sl811)->self.controller, in sl811h_urb_dequeue()
1020 (sl811->active_a == ep) ? "A" : "B"); in sl811h_urb_dequeue()
1022 retval = -EINVAL; in sl811h_urb_dequeue()
1024 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_urb_dequeue()
1031 struct sl811h_ep *ep = hep->hcpriv; in sl811h_endpoint_disable()
1037 if (!list_empty(&hep->urb_list)) in sl811h_endpoint_disable()
1039 if (!list_empty(&hep->urb_list)) in sl811h_endpoint_disable()
1040 dev_warn(hcd->self.controller, "ep %p not empty?\n", ep); in sl811h_endpoint_disable()
1043 hep->hcpriv = NULL; in sl811h_endpoint_disable()
1052 * never matches the on-the-wire frame; in sl811h_get_frame()
1055 return sl811->frame; in sl811h_get_frame()
1059 /*-------------------------------------------------------------------------*/
1069 /* non-SMP HACK: use root hub timer as i/o watchdog in sl811h_hub_status_data()
1073 if (!timer_pending(&sl811->timer)) { in sl811h_hub_status_data()
1075 sl811->stat_lost++; in sl811h_hub_status_data()
1080 if (!(sl811->port1 & (0xffff << 16))) in sl811h_hub_status_data()
1095 desc->bDescriptorType = USB_DT_HUB; in sl811h_hub_descriptor()
1096 desc->bHubContrCurrent = 0; in sl811h_hub_descriptor()
1098 desc->bNbrPorts = 1; in sl811h_hub_descriptor()
1099 desc->bDescLength = 9; in sl811h_hub_descriptor()
1101 /* per-port power switching (gang of one!), or none */ in sl811h_hub_descriptor()
1102 desc->bPwrOn2PwrGood = 0; in sl811h_hub_descriptor()
1103 if (sl811->board && sl811->board->port_power) { in sl811h_hub_descriptor()
1104 desc->bPwrOn2PwrGood = sl811->board->potpg; in sl811h_hub_descriptor()
1105 if (!desc->bPwrOn2PwrGood) in sl811h_hub_descriptor()
1106 desc->bPwrOn2PwrGood = 10; in sl811h_hub_descriptor()
1114 desc->wHubCharacteristics = cpu_to_le16(temp); in sl811h_hub_descriptor()
1117 desc->u.hs.DeviceRemovable[0] = 0 << 1; in sl811h_hub_descriptor()
1118 desc->u.hs.DeviceRemovable[1] = ~0; in sl811h_hub_descriptor()
1127 u8 signaling = sl811->ctrl1 & SL11H_CTL1MASK_FORCE; in sl811h_timer()
1132 spin_lock_irqsave(&sl811->lock, flags); in sl811h_timer()
1135 sl811->ctrl1 &= ~SL11H_CTL1MASK_FORCE; in sl811h_timer()
1136 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_timer()
1143 dev_dbg(sl811_to_hcd(sl811)->self.controller, "end reset\n"); in sl811h_timer()
1144 sl811->port1 = (USB_PORT_STAT_C_RESET << 16) in sl811h_timer()
1146 sl811->ctrl1 = 0; in sl811h_timer()
1152 dev_dbg(sl811_to_hcd(sl811)->self.controller, "end resume\n"); in sl811h_timer()
1153 sl811->port1 &= ~USB_PORT_STAT_SUSPEND; in sl811h_timer()
1156 dev_dbg(sl811_to_hcd(sl811)->self.controller, in sl811h_timer()
1164 if (sl811->port1 & USB_PORT_STAT_CONNECTION) in sl811h_timer()
1165 sl811->port1 |= (USB_PORT_STAT_C_CONNECTION << 16) in sl811h_timer()
1167 sl811->port1 &= ~mask; in sl811h_timer()
1168 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_timer()
1170 sl811->port1 |= mask; in sl811h_timer()
1172 sl811->port1 &= ~USB_PORT_STAT_LOW_SPEED; in sl811h_timer()
1173 sl811->irq_enable = SL11H_INTMASK_INSRMV | SL11H_INTMASK_RD; in sl811h_timer()
1176 if (sl811->port1 & USB_PORT_STAT_CONNECTION) { in sl811h_timer()
1179 sl811->irq_enable |= SL11H_INTMASK_DONE_A; in sl811h_timer()
1181 sl811->irq_enable |= SL11H_INTMASK_DONE_B; in sl811h_timer()
1183 if (sl811->port1 & USB_PORT_STAT_LOW_SPEED) { in sl811h_timer()
1184 sl811->ctrl1 |= SL11H_CTL1MASK_LSPD; in sl811h_timer()
1189 sl811->ctrl1 |= SL11H_CTL1MASK_SOF_ENA; in sl811h_timer()
1195 writeb(SL_SOF, sl811->data_reg); in sl811h_timer()
1196 writeb(0, sl811->data_reg); in sl811h_timer()
1202 sl811->ctrl1 = 0; in sl811h_timer()
1204 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_timer()
1207 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_timer()
1208 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_timer()
1224 spin_lock_irqsave(&sl811->lock, flags); in sl811h_hub_control()
1243 sl811->port1 &= USB_PORT_STAT_POWER; in sl811h_hub_control()
1244 sl811->ctrl1 = 0; in sl811h_hub_control()
1245 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1246 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_hub_control()
1248 sl811->irq_enable); in sl811h_hub_control()
1251 if (!(sl811->port1 & USB_PORT_STAT_SUSPEND)) in sl811h_hub_control()
1255 dev_dbg(hcd->self.controller, "start resume...\n"); in sl811h_hub_control()
1256 sl811->irq_enable = 0; in sl811h_hub_control()
1258 sl811->irq_enable); in sl811h_hub_control()
1259 sl811->ctrl1 |= SL11H_CTL1MASK_K; in sl811h_hub_control()
1260 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1262 mod_timer(&sl811->timer, jiffies in sl811h_hub_control()
1277 sl811->port1 &= ~(1 << wValue); in sl811h_hub_control()
1288 put_unaligned_le32(sl811->port1, buf); in sl811h_hub_control()
1292 dev_dbg(hcd->self.controller, "GetPortStatus %08x\n", in sl811h_hub_control()
1293 sl811->port1); in sl811h_hub_control()
1300 if (sl811->port1 & USB_PORT_STAT_RESET) in sl811h_hub_control()
1302 if (!(sl811->port1 & USB_PORT_STAT_ENABLE)) in sl811h_hub_control()
1305 dev_dbg(hcd->self.controller,"suspend...\n"); in sl811h_hub_control()
1306 sl811->ctrl1 &= ~SL11H_CTL1MASK_SOF_ENA; in sl811h_hub_control()
1307 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1313 if (sl811->port1 & USB_PORT_STAT_SUSPEND) in sl811h_hub_control()
1315 if (!(sl811->port1 & USB_PORT_STAT_POWER)) in sl811h_hub_control()
1319 sl811->irq_enable = 0; in sl811h_hub_control()
1321 sl811->irq_enable); in sl811h_hub_control()
1322 sl811->ctrl1 = SL11H_CTL1MASK_SE0; in sl811h_hub_control()
1323 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1324 sl811->port1 |= USB_PORT_STAT_RESET; in sl811h_hub_control()
1325 mod_timer(&sl811->timer, jiffies in sl811h_hub_control()
1331 sl811->port1 |= 1 << wValue; in sl811h_hub_control()
1337 retval = -EPIPE; in sl811h_hub_control()
1340 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_hub_control()
1350 dev_dbg(hcd->self.controller, "%s\n", __func__); in sl811h_bus_suspend()
1358 dev_dbg(hcd->self.controller, "%s\n", __func__); in sl811h_bus_resume()
1370 /*-------------------------------------------------------------------------*/
1385 struct sl811 *sl811 = s->private; in sl811h_debug_show()
1390 sl811_to_hcd(sl811)->product_desc, in sl811h_debug_show()
1392 sl811->port1); in sl811h_debug_show()
1394 seq_printf(s, "insert/remove: %ld\n", sl811->stat_insrmv); in sl811h_debug_show()
1397 sl811->stat_a, sl811->stat_b, in sl811h_debug_show()
1398 sl811->stat_wake, sl811->stat_sof, in sl811h_debug_show()
1399 sl811->stat_overrun, sl811->stat_lost); in sl811h_debug_show()
1401 spin_lock_irq(&sl811->lock); in sl811h_debug_show()
1403 if (sl811->ctrl1 & SL11H_CTL1MASK_SUSPEND) in sl811h_debug_show()
1427 seq_printf(s, "A: qh%p ctl %02x sts %02x\n", sl811->active_a, in sl811h_debug_show()
1430 seq_printf(s, "B: qh%p ctl %02x sts %02x\n", sl811->active_b, in sl811h_debug_show()
1434 list_for_each_entry (ep, &sl811->async, schedule) { in sl811h_debug_show()
1439 (ep == sl811->active_a) ? "(A) " : "", in sl811h_debug_show()
1440 (ep == sl811->active_b) ? "(B) " : "", in sl811h_debug_show()
1441 ep, ep->epnum, in sl811h_debug_show()
1442 ({ char *s; switch (ep->nextpid) { in sl811h_debug_show()
1449 ep->maxpacket, in sl811h_debug_show()
1450 ep->nak_count, ep->error_count); in sl811h_debug_show()
1451 list_for_each_entry (urb, &ep->hep->urb_list, urb_list) { in sl811h_debug_show()
1453 urb->actual_length, in sl811h_debug_show()
1454 urb->transfer_buffer_length); in sl811h_debug_show()
1457 if (!list_empty(&sl811->async)) in sl811h_debug_show()
1463 ep = sl811->periodic[i]; in sl811h_debug_show()
1466 seq_printf(s, "%2d [%3d]:\n", i, sl811->load[i]); in sl811h_debug_show()
1473 (ep == sl811->active_a) ? "(A) " : "", in sl811h_debug_show()
1474 (ep == sl811->active_b) ? "(B) " : "", in sl811h_debug_show()
1475 ep->period, ep, in sl811h_debug_show()
1476 (ep->udev->speed == USB_SPEED_FULL) in sl811h_debug_show()
1478 ep->udev->devnum, ep->epnum, in sl811h_debug_show()
1479 (ep->epnum == 0) ? "" in sl811h_debug_show()
1480 : ((ep->nextpid == USB_PID_IN) in sl811h_debug_show()
1483 ep->maxpacket, ep->error_count); in sl811h_debug_show()
1484 ep = ep->next; in sl811h_debug_show()
1488 spin_unlock_irq(&sl811->lock); in sl811h_debug_show()
1507 /*-------------------------------------------------------------------------*/
1515 del_timer_sync(&hcd->rh_timer); in sl811h_stop()
1517 spin_lock_irqsave(&sl811->lock, flags); in sl811h_stop()
1519 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_stop()
1528 hcd->state = HC_STATE_RUNNING; in sl811h_start()
1530 if (sl811->board) { in sl811h_start()
1531 if (!device_can_wakeup(hcd->self.controller)) in sl811h_start()
1532 device_init_wakeup(hcd->self.controller, in sl811h_start()
1533 sl811->board->can_wakeup); in sl811h_start()
1534 hcd->power_budget = sl811->board->power * 2; in sl811h_start()
1543 /*-------------------------------------------------------------------------*/
1580 /*-------------------------------------------------------------------------*/
1595 iounmap(sl811->data_reg); in sl811h_remove()
1599 iounmap(sl811->addr_reg); in sl811h_remove()
1618 return -ENODEV; in sl811h_probe()
1624 return -ENODEV; in sl811h_probe()
1626 /* basic sanity checks first. board-specific init logic should in sl811h_probe()
1632 if (dev->num_resources < 3 || !ires) in sl811h_probe()
1633 return -ENODEV; in sl811h_probe()
1635 irq = ires->start; in sl811h_probe()
1636 irqflags = ires->flags & IRQF_TRIGGER_MASK; in sl811h_probe()
1641 * NOTE: 64-bit resource->start is getting truncated in sl811h_probe()
1642 * to avoid compiler warning, assuming that ->start in sl811h_probe()
1643 * is always 32-bit for this case in sl811h_probe()
1645 addr_reg = (void __iomem *) (unsigned long) addr->start; in sl811h_probe()
1646 data_reg = (void __iomem *) (unsigned long) data->start; in sl811h_probe()
1648 addr_reg = ioremap(addr->start, 1); in sl811h_probe()
1650 retval = -ENOMEM; in sl811h_probe()
1654 data_reg = ioremap(data->start, 1); in sl811h_probe()
1656 retval = -ENOMEM; in sl811h_probe()
1662 hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev_name(&dev->dev)); in sl811h_probe()
1664 retval = -ENOMEM; in sl811h_probe()
1667 hcd->rsrc_start = addr->start; in sl811h_probe()
1670 spin_lock_init(&sl811->lock); in sl811h_probe()
1671 INIT_LIST_HEAD(&sl811->async); in sl811h_probe()
1672 sl811->board = dev_get_platdata(&dev->dev); in sl811h_probe()
1673 timer_setup(&sl811->timer, sl811h_timer, 0); in sl811h_probe()
1674 sl811->addr_reg = addr_reg; in sl811h_probe()
1675 sl811->data_reg = data_reg; in sl811h_probe()
1677 spin_lock_irq(&sl811->lock); in sl811h_probe()
1679 spin_unlock_irq(&sl811->lock); in sl811h_probe()
1685 hcd->product_desc = "SL811HS v1.2"; in sl811h_probe()
1688 hcd->product_desc = "SL811HS v1.5"; in sl811h_probe()
1692 dev_dbg(&dev->dev, "chiprev %02x\n", tmp); in sl811h_probe()
1693 retval = -ENXIO; in sl811h_probe()
1711 device_wakeup_enable(hcd->self.controller); in sl811h_probe()
1725 dev_dbg(&dev->dev, "init error, %d\n", retval); in sl811h_probe()
1761 /* with no "check to see if VBUS is still powered" board hook, in sl811h_resume()
1762 * let's assume it'd only be powered to enable remote wakeup. in sl811h_resume()
1764 if (!sl811->port1 || !device_can_wakeup(&hcd->self.root_hub->dev)) { in sl811h_resume()
1765 sl811->port1 = 0; in sl811h_resume()
1767 usb_root_hub_lost_power(hcd->self.root_hub); in sl811h_resume()