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
65 MODULE_ALIAS("platform:sl811-hcd");
75 static const char hcd_name[] = "sl811-hcd";
77 /*-------------------------------------------------------------------------*/
83 /* hub is inactive unless the port is powered */ in port_power()
85 if (sl811->port1 & USB_PORT_STAT_POWER) in port_power()
88 sl811->port1 = USB_PORT_STAT_POWER; in port_power()
89 sl811->irq_enable = SL11H_INTMASK_INSRMV; in port_power()
91 sl811->port1 = 0; in port_power()
92 sl811->irq_enable = 0; in port_power()
93 hcd->state = HC_STATE_HALT; in port_power()
95 sl811->ctrl1 = 0; in port_power()
99 if (sl811->board && sl811->board->port_power) { in port_power()
101 dev_dbg(hcd->self.controller, "power %s\n", in port_power()
103 sl811->board->port_power(hcd->self.controller, is_on); in port_power()
107 if (sl811->board && sl811->board->reset) in port_power()
108 sl811->board->reset(hcd->self.controller); in port_power()
115 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in port_power()
117 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in port_power()
122 /*-------------------------------------------------------------------------*/
124 /* This is a PIO-only HCD. Queueing appends URBs to the endpoint's queue,
149 data_reg = sl811->data_reg; in setup_packet()
150 sl811_write_buf(sl811, addr, urb->setup_packet, len); in setup_packet()
155 writeb(SL_SETUP /* | ep->epnum */, data_reg); in setup_packet()
156 writeb(usb_pipedevice(urb->pipe), data_reg); in setup_packet()
161 ep->length = 0; in setup_packet()
177 do_out = urb->transfer_buffer_length && usb_pipein(urb->pipe); in status_packet()
178 data_reg = sl811->data_reg; in status_packet()
183 writeb((do_out ? SL_OUT : SL_IN) /* | ep->epnum */, data_reg); in status_packet()
184 writeb(usb_pipedevice(urb->pipe), data_reg); in status_packet()
191 ep->length = 0; in status_packet()
192 PACKET("STATUS%s/%s qh%p\n", ep->nak_count ? "/retry" : "", in status_packet()
198 * urb->iso_frame_desc is currently ignored here...
213 len = ep->maxpacket; in in_packet()
216 && usb_gettoggle(urb->dev, ep->epnum, 0)) in in_packet()
218 data_reg = sl811->data_reg; in in_packet()
223 writeb(SL_IN | ep->epnum, data_reg); in in_packet()
224 writeb(usb_pipedevice(urb->pipe), data_reg); in in_packet()
227 ep->length = min_t(u32, len, in in_packet()
228 urb->transfer_buffer_length - urb->actual_length); in in_packet()
229 PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", in in_packet()
230 !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); in in_packet()
234 * urb->iso_frame_desc is currently ignored here...
249 buf = urb->transfer_buffer + urb->actual_length; in out_packet()
252 len = min_t(u32, ep->maxpacket, in out_packet()
253 urb->transfer_buffer_length - urb->actual_length); in out_packet()
256 && usb_gettoggle(urb->dev, ep->epnum, 1)) in out_packet()
259 data_reg = sl811->data_reg; in out_packet()
266 writeb(SL_OUT | ep->epnum, data_reg); in out_packet()
267 writeb(usb_pipedevice(urb->pipe), data_reg); in out_packet()
271 ep->length = len; in out_packet()
272 PACKET("OUT%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", in out_packet()
273 !!usb_gettoggle(urb->dev, ep->epnum, 1), ep, len); in out_packet()
276 /*-------------------------------------------------------------------------*/
278 /* caller updates on-chip enables later */
282 if (sl811->irq_enable & SL11H_INTMASK_SOFINTR) in sofirq_on()
284 dev_dbg(sl811_to_hcd(sl811)->self.controller, "sof irq on\n"); in sofirq_on()
285 sl811->irq_enable |= SL11H_INTMASK_SOFINTR; in sofirq_on()
290 if (!(sl811->irq_enable & SL11H_INTMASK_SOFINTR)) in sofirq_off()
292 dev_dbg(sl811_to_hcd(sl811)->self.controller, "sof irq off\n"); in sofirq_off()
293 sl811->irq_enable &= ~SL11H_INTMASK_SOFINTR; in sofirq_off()
296 /*-------------------------------------------------------------------------*/
301 * transfers, scheduled round-robin.
311 if (sl811->next_periodic) { in start()
312 ep = sl811->next_periodic; in start()
313 sl811->next_periodic = ep->next; in start()
315 if (sl811->next_async) in start()
316 ep = sl811->next_async; in start()
317 else if (!list_empty(&sl811->async)) in start()
318 ep = container_of(sl811->async.next, in start()
328 if ((bank && sl811->active_b == ep) || sl811->active_a == ep) in start()
332 if (ep->schedule.next == &sl811->async) in start()
333 sl811->next_async = NULL; in start()
335 sl811->next_async = container_of(ep->schedule.next, in start()
339 if (unlikely(list_empty(&ep->hep->urb_list))) { in start()
340 dev_dbg(sl811_to_hcd(sl811)->self.controller, in start()
345 urb = container_of(ep->hep->urb_list.next, struct urb, urb_list); in start()
346 control = ep->defctrl; in start()
349 * packet, wait till the next frame. too-simple algorithm... in start()
352 fclock -= 100; /* setup takes not much time */ in start()
353 if (urb->dev->speed == USB_SPEED_LOW) { in start()
356 fclock -= 800; in start()
358 fclock -= ep->maxpacket << 8; in start()
362 if (ep->period) in start()
363 sl811->stat_overrun++; in start()
368 fclock -= 12000 / 19; /* 19 64byte packets/msec */ in start()
370 if (ep->period) in start()
371 sl811->stat_overrun++; in start()
375 } else if (ep->nak_count) in start()
380 switch (ep->nextpid) { in start()
394 dev_dbg(sl811_to_hcd(sl811)->self.controller, in start()
395 "bad ep%p pid %02x\n", ep, ep->nextpid); in start()
405 if (sl811->port1 & USB_PORT_STAT_SUSPEND) in start_transfer()
407 if (sl811->active_a == NULL) { in start_transfer()
408 sl811->active_a = start(sl811, SL811_EP_A(SL811_HOST_BUF)); in start_transfer()
409 if (sl811->active_a != NULL) in start_transfer()
410 sl811->jiffies_a = jiffies + MIN_JIFFIES; in start_transfer()
413 if (sl811->active_b == NULL) { in start_transfer()
414 sl811->active_b = start(sl811, SL811_EP_B(SL811_HOST_BUF)); in start_transfer()
415 if (sl811->active_b != NULL) in start_transfer()
416 sl811->jiffies_b = jiffies + MIN_JIFFIES; in start_transfer()
426 ) __releases(sl811->lock) __acquires(sl811->lock) in finish_request()
430 if (usb_pipecontrol(urb->pipe)) in finish_request()
431 ep->nextpid = USB_PID_SETUP; in finish_request()
434 spin_unlock(&sl811->lock); in finish_request()
436 spin_lock(&sl811->lock); in finish_request()
439 if (!list_empty(&ep->hep->urb_list)) in finish_request()
443 if (!list_empty(&ep->schedule)) { in finish_request()
444 list_del_init(&ep->schedule); in finish_request()
445 if (ep == sl811->next_async) in finish_request()
446 sl811->next_async = NULL; in finish_request()
451 dev_dbg(sl811_to_hcd(sl811)->self.controller, in finish_request()
452 "deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); in finish_request()
453 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { in finish_request()
455 struct sl811h_ep **prev = &sl811->periodic[i]; in finish_request()
458 prev = &temp->next; in finish_request()
460 *prev = ep->next; in finish_request()
461 sl811->load[i] -= ep->load; in finish_request()
463 ep->branch = PERIODIC_SIZE; in finish_request()
464 sl811->periodic_count--; in finish_request()
465 sl811_to_hcd(sl811)->self.bandwidth_allocated in finish_request()
466 -= ep->load / ep->period; in finish_request()
467 if (ep == sl811->next_periodic) in finish_request()
468 sl811->next_periodic = ep->next; in finish_request()
471 if (sl811->periodic_count == 0) in finish_request()
480 int urbstat = -EINPROGRESS; in done()
487 urb = container_of(ep->hep->urb_list.next, struct urb, urb_list); in done()
492 if (!ep->period) in done()
493 ep->nak_count++; in done()
494 ep->error_count = 0; in done()
498 struct usb_device *udev = urb->dev; in done()
502 /* urb->iso_frame_desc is currently ignored here... */ in done()
504 ep->nak_count = ep->error_count = 0; in done()
505 switch (ep->nextpid) { in done()
508 urb->actual_length += ep->length; in done()
509 usb_dotoggle(udev, ep->epnum, 1); in done()
510 if (urb->actual_length in done()
511 == urb->transfer_buffer_length) { in done()
512 if (usb_pipecontrol(urb->pipe)) in done()
513 ep->nextpid = USB_PID_ACK; in done()
518 else if (ep->length < ep->maxpacket in done()
519 || !(urb->transfer_flags in done()
526 buf = urb->transfer_buffer + urb->actual_length; in done()
528 len = ep->maxpacket - sl811_read(sl811, in done()
530 if (len > ep->length) { in done()
531 len = ep->length; in done()
532 urbstat = -EOVERFLOW; in done()
534 urb->actual_length += len; in done()
537 usb_dotoggle(udev, ep->epnum, 0); in done()
538 if (urbstat == -EINPROGRESS && in done()
539 (len < ep->maxpacket || in done()
540 urb->actual_length == in done()
541 urb->transfer_buffer_length)) { in done()
542 if (usb_pipecontrol(urb->pipe)) in done()
543 ep->nextpid = USB_PID_ACK; in done()
550 if (urb->transfer_buffer_length == urb->actual_length) in done()
551 ep->nextpid = USB_PID_ACK; in done()
552 else if (usb_pipeout(urb->pipe)) { in done()
554 ep->nextpid = USB_PID_OUT; in done()
557 ep->nextpid = USB_PID_IN; in done()
569 ep->nak_count = ep->error_count = 0; in done()
570 urbstat = -EPIPE; in done()
573 } else if (++ep->error_count >= 3) { in done()
575 urbstat = -ETIME; in done()
577 urbstat = -EOVERFLOW; in done()
579 urbstat = -EPROTO; in done()
580 ep->error_count = 0; in done()
585 if (urbstat != -EINPROGRESS || urb->unlinked) in done()
595 if (sl811->active_a && time_before_eq(sl811->jiffies_a, jiffies)) { in checkdone()
599 dev_dbg(sl811_to_hcd(sl811)->self.controller, in checkdone()
607 if (sl811->active_b && time_before_eq(sl811->jiffies_b, jiffies)) { in checkdone()
611 dev_dbg(sl811_to_hcd(sl811)->self.controller, in checkdone()
630 spin_lock(&sl811->lock); in sl811h_irq()
636 irqstat &= sl811->irq_enable; in sl811h_irq()
644 sl811->stat_lost++; in sl811h_irq()
652 done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF)); in sl811h_irq()
653 sl811->active_a = NULL; in sl811h_irq()
654 sl811->stat_a++; in sl811h_irq()
658 done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF)); in sl811h_irq()
659 sl811->active_b = NULL; in sl811h_irq()
660 sl811->stat_b++; in sl811h_irq()
666 index = sl811->frame++ % (PERIODIC_SIZE - 1); in sl811h_irq()
667 sl811->stat_sof++; in sl811h_irq()
669 /* be graceful about almost-inevitable periodic schedule in sl811h_irq()
673 if (sl811->next_periodic) { in sl811h_irq()
674 // dev_err(hcd->self.controller, "overrun to slot %d\n", index); in sl811h_irq()
675 sl811->stat_overrun++; in sl811h_irq()
677 if (sl811->periodic[index]) in sl811h_irq()
678 sl811->next_periodic = sl811->periodic[index]; in sl811h_irq()
683 sl811->stat_insrmv++; in sl811h_irq()
686 sl811->stat_wake = 0; in sl811h_irq()
687 sl811->stat_sof = 0; in sl811h_irq()
688 sl811->stat_a = 0; in sl811h_irq()
689 sl811->stat_b = 0; in sl811h_irq()
690 sl811->stat_lost = 0; in sl811h_irq()
692 sl811->ctrl1 = 0; in sl811h_irq()
693 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_irq()
695 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_irq()
696 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_irq()
699 if (sl811->active_a) { in sl811h_irq()
701 finish_request(sl811, sl811->active_a, in sl811h_irq()
702 container_of(sl811->active_a in sl811h_irq()
703 ->hep->urb_list.next, in sl811h_irq()
705 -ESHUTDOWN); in sl811h_irq()
706 sl811->active_a = NULL; in sl811h_irq()
709 if (sl811->active_b) { in sl811h_irq()
711 finish_request(sl811, sl811->active_b, in sl811h_irq()
712 container_of(sl811->active_b in sl811h_irq()
713 ->hep->urb_list.next, in sl811h_irq()
715 NULL, -ESHUTDOWN); in sl811h_irq()
716 sl811->active_b = NULL; in sl811h_irq()
724 sl811->port1 &= ~USB_PORT_STAT_CONNECTION; in sl811h_irq()
726 sl811->port1 |= USB_PORT_STAT_CONNECTION; in sl811h_irq()
728 sl811->port1 |= USB_PORT_STAT_C_CONNECTION << 16; in sl811h_irq()
731 if (sl811->port1 & USB_PORT_STAT_SUSPEND) { in sl811h_irq()
732 dev_dbg(hcd->self.controller, "wakeup\n"); in sl811h_irq()
733 sl811->port1 |= USB_PORT_STAT_C_SUSPEND << 16; in sl811h_irq()
734 sl811->stat_wake++; in sl811h_irq()
740 if (sl811->port1 & USB_PORT_STAT_ENABLE) in sl811h_irq()
743 if (retries--) in sl811h_irq()
747 if (sl811->periodic_count == 0 && list_empty(&sl811->async)) in sl811h_irq()
749 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_irq()
751 spin_unlock(&sl811->lock); in sl811h_irq()
756 /*-------------------------------------------------------------------------*/
769 int i, branch = -ENOSPC; in balance()
775 if (branch < 0 || sl811->load[branch] > sl811->load[i]) { in balance()
779 if ((sl811->load[j] + load) in balance()
791 /*-------------------------------------------------------------------------*/
799 struct usb_device *udev = urb->dev; in sl811h_urb_enqueue()
800 unsigned int pipe = urb->pipe; in sl811h_urb_enqueue()
808 struct usb_host_endpoint *hep = urb->ep; in sl811h_urb_enqueue()
812 return -ENOSPC; in sl811h_urb_enqueue()
816 if (!hep->hcpriv) { in sl811h_urb_enqueue()
819 return -ENOMEM; in sl811h_urb_enqueue()
822 spin_lock_irqsave(&sl811->lock, flags); in sl811h_urb_enqueue()
825 if (!(sl811->port1 & USB_PORT_STAT_ENABLE) in sl811h_urb_enqueue()
826 || !HC_IS_RUNNING(hcd->state)) { in sl811h_urb_enqueue()
827 retval = -ENODEV; in sl811h_urb_enqueue()
837 if (hep->hcpriv) { in sl811h_urb_enqueue()
839 ep = hep->hcpriv; in sl811h_urb_enqueue()
841 retval = -ENOMEM; in sl811h_urb_enqueue()
845 INIT_LIST_HEAD(&ep->schedule); in sl811h_urb_enqueue()
846 ep->udev = udev; in sl811h_urb_enqueue()
847 ep->epnum = epnum; in sl811h_urb_enqueue()
848 ep->maxpacket = usb_maxpacket(udev, urb->pipe); in sl811h_urb_enqueue()
849 ep->defctrl = SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENABLE; in sl811h_urb_enqueue()
853 ep->nextpid = USB_PID_SETUP; in sl811h_urb_enqueue()
855 ep->nextpid = USB_PID_OUT; in sl811h_urb_enqueue()
857 ep->nextpid = USB_PID_IN; in sl811h_urb_enqueue()
859 if (ep->maxpacket > H_MAXPACKET) { in sl811h_urb_enqueue()
861 dev_dbg(hcd->self.controller, in sl811h_urb_enqueue()
862 "dev %d ep%d maxpacket %d\n", udev->devnum, in sl811h_urb_enqueue()
863 epnum, ep->maxpacket); in sl811h_urb_enqueue()
864 retval = -EINVAL; in sl811h_urb_enqueue()
869 if (udev->speed == USB_SPEED_LOW) { in sl811h_urb_enqueue()
871 if (!(sl811->ctrl1 & SL11H_CTL1MASK_LSPD)) in sl811h_urb_enqueue()
872 ep->defctrl |= SL11H_HCTLMASK_PREAMBLE; in sl811h_urb_enqueue()
877 if (urb->interval > PERIODIC_SIZE) in sl811h_urb_enqueue()
878 urb->interval = PERIODIC_SIZE; in sl811h_urb_enqueue()
879 ep->period = urb->interval; in sl811h_urb_enqueue()
880 ep->branch = PERIODIC_SIZE; in sl811h_urb_enqueue()
882 ep->defctrl |= SL11H_HCTLMASK_ISOCH; in sl811h_urb_enqueue()
883 ep->load = usb_calc_bus_time(udev->speed, !is_out, in sl811h_urb_enqueue()
890 ep->hep = hep; in sl811h_urb_enqueue()
891 hep->hcpriv = ep; in sl811h_urb_enqueue()
898 if (list_empty(&ep->schedule)) in sl811h_urb_enqueue()
899 list_add_tail(&ep->schedule, &sl811->async); in sl811h_urb_enqueue()
903 urb->interval = ep->period; in sl811h_urb_enqueue()
904 if (ep->branch < PERIODIC_SIZE) { in sl811h_urb_enqueue()
910 urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) in sl811h_urb_enqueue()
911 + ep->branch; in sl811h_urb_enqueue()
915 retval = balance(sl811, ep->period, ep->load); in sl811h_urb_enqueue()
918 ep->branch = retval; in sl811h_urb_enqueue()
920 urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) in sl811h_urb_enqueue()
921 + ep->branch; in sl811h_urb_enqueue()
927 dev_dbg(hcd->self.controller, "schedule qh%d/%p branch %d\n", in sl811h_urb_enqueue()
928 ep->period, ep, ep->branch); in sl811h_urb_enqueue()
929 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { in sl811h_urb_enqueue()
930 struct sl811h_ep **prev = &sl811->periodic[i]; in sl811h_urb_enqueue()
934 if (ep->period > here->period) in sl811h_urb_enqueue()
936 prev = &here->next; in sl811h_urb_enqueue()
940 ep->next = here; in sl811h_urb_enqueue()
943 sl811->load[i] += ep->load; in sl811h_urb_enqueue()
945 sl811->periodic_count++; in sl811h_urb_enqueue()
946 hcd->self.bandwidth_allocated += ep->load / ep->period; in sl811h_urb_enqueue()
950 urb->hcpriv = hep; in sl811h_urb_enqueue()
952 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_urb_enqueue()
957 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_urb_enqueue()
969 spin_lock_irqsave(&sl811->lock, flags); in sl811h_urb_dequeue()
974 hep = urb->hcpriv; in sl811h_urb_dequeue()
975 ep = hep->hcpriv; in sl811h_urb_dequeue()
980 if (ep->hep->urb_list.next != &urb->urb_list) { in sl811h_urb_dequeue()
984 } else if (sl811->active_a == ep) { in sl811h_urb_dequeue()
985 if (time_before_eq(sl811->jiffies_a, jiffies)) { in sl811h_urb_dequeue()
987 dev_dbg(hcd->self.controller, in sl811h_urb_dequeue()
995 sl811->active_a = NULL; in sl811h_urb_dequeue()
999 } else if (sl811->active_b == ep) { in sl811h_urb_dequeue()
1000 if (time_before_eq(sl811->jiffies_a, jiffies)) { in sl811h_urb_dequeue()
1002 dev_dbg(hcd->self.controller, in sl811h_urb_dequeue()
1010 sl811->active_b = NULL; in sl811h_urb_dequeue()
1021 dev_dbg(sl811_to_hcd(sl811)->self.controller, in sl811h_urb_dequeue()
1023 (sl811->active_a == ep) ? "A" : "B"); in sl811h_urb_dequeue()
1025 retval = -EINVAL; in sl811h_urb_dequeue()
1027 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_urb_dequeue()
1034 struct sl811h_ep *ep = hep->hcpriv; in sl811h_endpoint_disable()
1040 if (!list_empty(&hep->urb_list)) in sl811h_endpoint_disable()
1042 if (!list_empty(&hep->urb_list)) in sl811h_endpoint_disable()
1043 dev_warn(hcd->self.controller, "ep %p not empty?\n", ep); in sl811h_endpoint_disable()
1046 hep->hcpriv = NULL; in sl811h_endpoint_disable()
1055 * never matches the on-the-wire frame; in sl811h_get_frame()
1058 return sl811->frame; in sl811h_get_frame()
1062 /*-------------------------------------------------------------------------*/
1072 /* non-SMP HACK: use root hub timer as i/o watchdog in sl811h_hub_status_data()
1076 if (!timer_pending(&sl811->timer)) { in sl811h_hub_status_data()
1078 sl811->stat_lost++; in sl811h_hub_status_data()
1083 if (!(sl811->port1 & (0xffff << 16))) in sl811h_hub_status_data()
1098 desc->bDescriptorType = USB_DT_HUB; in sl811h_hub_descriptor()
1099 desc->bHubContrCurrent = 0; in sl811h_hub_descriptor()
1101 desc->bNbrPorts = 1; in sl811h_hub_descriptor()
1102 desc->bDescLength = 9; in sl811h_hub_descriptor()
1104 /* per-port power switching (gang of one!), or none */ in sl811h_hub_descriptor()
1105 desc->bPwrOn2PwrGood = 0; in sl811h_hub_descriptor()
1106 if (sl811->board && sl811->board->port_power) { in sl811h_hub_descriptor()
1107 desc->bPwrOn2PwrGood = sl811->board->potpg; in sl811h_hub_descriptor()
1108 if (!desc->bPwrOn2PwrGood) in sl811h_hub_descriptor()
1109 desc->bPwrOn2PwrGood = 10; in sl811h_hub_descriptor()
1117 desc->wHubCharacteristics = cpu_to_le16(temp); in sl811h_hub_descriptor()
1120 desc->u.hs.DeviceRemovable[0] = 0 << 1; in sl811h_hub_descriptor()
1121 desc->u.hs.DeviceRemovable[1] = ~0; in sl811h_hub_descriptor()
1130 u8 signaling = sl811->ctrl1 & SL11H_CTL1MASK_FORCE; in sl811h_timer()
1135 spin_lock_irqsave(&sl811->lock, flags); in sl811h_timer()
1138 sl811->ctrl1 &= ~SL11H_CTL1MASK_FORCE; in sl811h_timer()
1139 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_timer()
1146 dev_dbg(sl811_to_hcd(sl811)->self.controller, "end reset\n"); in sl811h_timer()
1147 sl811->port1 = (USB_PORT_STAT_C_RESET << 16) in sl811h_timer()
1149 sl811->ctrl1 = 0; in sl811h_timer()
1155 dev_dbg(sl811_to_hcd(sl811)->self.controller, "end resume\n"); in sl811h_timer()
1156 sl811->port1 &= ~USB_PORT_STAT_SUSPEND; in sl811h_timer()
1159 dev_dbg(sl811_to_hcd(sl811)->self.controller, in sl811h_timer()
1167 if (sl811->port1 & USB_PORT_STAT_CONNECTION) in sl811h_timer()
1168 sl811->port1 |= (USB_PORT_STAT_C_CONNECTION << 16) in sl811h_timer()
1170 sl811->port1 &= ~mask; in sl811h_timer()
1171 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_timer()
1173 sl811->port1 |= mask; in sl811h_timer()
1175 sl811->port1 &= ~USB_PORT_STAT_LOW_SPEED; in sl811h_timer()
1176 sl811->irq_enable = SL11H_INTMASK_INSRMV | SL11H_INTMASK_RD; in sl811h_timer()
1179 if (sl811->port1 & USB_PORT_STAT_CONNECTION) { in sl811h_timer()
1182 sl811->irq_enable |= SL11H_INTMASK_DONE_A; in sl811h_timer()
1184 sl811->irq_enable |= SL11H_INTMASK_DONE_B; in sl811h_timer()
1186 if (sl811->port1 & USB_PORT_STAT_LOW_SPEED) { in sl811h_timer()
1187 sl811->ctrl1 |= SL11H_CTL1MASK_LSPD; in sl811h_timer()
1192 sl811->ctrl1 |= SL11H_CTL1MASK_SOF_ENA; in sl811h_timer()
1198 writeb(SL_SOF, sl811->data_reg); in sl811h_timer()
1199 writeb(0, sl811->data_reg); in sl811h_timer()
1205 sl811->ctrl1 = 0; in sl811h_timer()
1207 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_timer()
1210 sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); in sl811h_timer()
1211 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_timer()
1227 spin_lock_irqsave(&sl811->lock, flags); in sl811h_hub_control()
1246 sl811->port1 &= USB_PORT_STAT_POWER; in sl811h_hub_control()
1247 sl811->ctrl1 = 0; in sl811h_hub_control()
1248 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1249 sl811->irq_enable = SL11H_INTMASK_INSRMV; in sl811h_hub_control()
1251 sl811->irq_enable); in sl811h_hub_control()
1254 if (!(sl811->port1 & USB_PORT_STAT_SUSPEND)) in sl811h_hub_control()
1258 dev_dbg(hcd->self.controller, "start resume...\n"); in sl811h_hub_control()
1259 sl811->irq_enable = 0; in sl811h_hub_control()
1261 sl811->irq_enable); in sl811h_hub_control()
1262 sl811->ctrl1 |= SL11H_CTL1MASK_K; in sl811h_hub_control()
1263 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1265 mod_timer(&sl811->timer, jiffies in sl811h_hub_control()
1280 sl811->port1 &= ~(1 << wValue); in sl811h_hub_control()
1291 put_unaligned_le32(sl811->port1, buf); in sl811h_hub_control()
1295 dev_dbg(hcd->self.controller, "GetPortStatus %08x\n", in sl811h_hub_control()
1296 sl811->port1); in sl811h_hub_control()
1303 if (sl811->port1 & USB_PORT_STAT_RESET) in sl811h_hub_control()
1305 if (!(sl811->port1 & USB_PORT_STAT_ENABLE)) in sl811h_hub_control()
1308 dev_dbg(hcd->self.controller,"suspend...\n"); in sl811h_hub_control()
1309 sl811->ctrl1 &= ~SL11H_CTL1MASK_SOF_ENA; in sl811h_hub_control()
1310 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1316 if (sl811->port1 & USB_PORT_STAT_SUSPEND) in sl811h_hub_control()
1318 if (!(sl811->port1 & USB_PORT_STAT_POWER)) in sl811h_hub_control()
1322 sl811->irq_enable = 0; in sl811h_hub_control()
1324 sl811->irq_enable); in sl811h_hub_control()
1325 sl811->ctrl1 = SL11H_CTL1MASK_SE0; in sl811h_hub_control()
1326 sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); in sl811h_hub_control()
1327 sl811->port1 |= USB_PORT_STAT_RESET; in sl811h_hub_control()
1328 mod_timer(&sl811->timer, jiffies in sl811h_hub_control()
1334 sl811->port1 |= 1 << wValue; in sl811h_hub_control()
1340 retval = -EPIPE; in sl811h_hub_control()
1343 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_hub_control()
1353 dev_dbg(hcd->self.controller, "%s\n", __func__); in sl811h_bus_suspend()
1361 dev_dbg(hcd->self.controller, "%s\n", __func__); in sl811h_bus_resume()
1373 /*-------------------------------------------------------------------------*/
1388 struct sl811 *sl811 = s->private; in sl811h_debug_show()
1393 sl811_to_hcd(sl811)->product_desc, in sl811h_debug_show()
1395 sl811->port1); in sl811h_debug_show()
1397 seq_printf(s, "insert/remove: %ld\n", sl811->stat_insrmv); in sl811h_debug_show()
1400 sl811->stat_a, sl811->stat_b, in sl811h_debug_show()
1401 sl811->stat_wake, sl811->stat_sof, in sl811h_debug_show()
1402 sl811->stat_overrun, sl811->stat_lost); in sl811h_debug_show()
1404 spin_lock_irq(&sl811->lock); in sl811h_debug_show()
1406 if (sl811->ctrl1 & SL11H_CTL1MASK_SUSPEND) in sl811h_debug_show()
1430 seq_printf(s, "A: qh%p ctl %02x sts %02x\n", sl811->active_a, in sl811h_debug_show()
1433 seq_printf(s, "B: qh%p ctl %02x sts %02x\n", sl811->active_b, in sl811h_debug_show()
1437 list_for_each_entry (ep, &sl811->async, schedule) { in sl811h_debug_show()
1442 (ep == sl811->active_a) ? "(A) " : "", in sl811h_debug_show()
1443 (ep == sl811->active_b) ? "(B) " : "", in sl811h_debug_show()
1444 ep, ep->epnum, in sl811h_debug_show()
1445 ({ char *s; switch (ep->nextpid) { in sl811h_debug_show()
1452 ep->maxpacket, in sl811h_debug_show()
1453 ep->nak_count, ep->error_count); in sl811h_debug_show()
1454 list_for_each_entry (urb, &ep->hep->urb_list, urb_list) { in sl811h_debug_show()
1456 urb->actual_length, in sl811h_debug_show()
1457 urb->transfer_buffer_length); in sl811h_debug_show()
1460 if (!list_empty(&sl811->async)) in sl811h_debug_show()
1466 ep = sl811->periodic[i]; in sl811h_debug_show()
1469 seq_printf(s, "%2d [%3d]:\n", i, sl811->load[i]); in sl811h_debug_show()
1476 (ep == sl811->active_a) ? "(A) " : "", in sl811h_debug_show()
1477 (ep == sl811->active_b) ? "(B) " : "", in sl811h_debug_show()
1478 ep->period, ep, in sl811h_debug_show()
1479 (ep->udev->speed == USB_SPEED_FULL) in sl811h_debug_show()
1481 ep->udev->devnum, ep->epnum, in sl811h_debug_show()
1482 (ep->epnum == 0) ? "" in sl811h_debug_show()
1483 : ((ep->nextpid == USB_PID_IN) in sl811h_debug_show()
1486 ep->maxpacket, ep->error_count); in sl811h_debug_show()
1487 ep = ep->next; in sl811h_debug_show()
1491 spin_unlock_irq(&sl811->lock); in sl811h_debug_show()
1510 /*-------------------------------------------------------------------------*/
1518 del_timer_sync(&hcd->rh_timer); in sl811h_stop()
1520 spin_lock_irqsave(&sl811->lock, flags); in sl811h_stop()
1522 spin_unlock_irqrestore(&sl811->lock, flags); in sl811h_stop()
1531 hcd->state = HC_STATE_RUNNING; in sl811h_start()
1533 if (sl811->board) { in sl811h_start()
1534 if (!device_can_wakeup(hcd->self.controller)) in sl811h_start()
1535 device_init_wakeup(hcd->self.controller, in sl811h_start()
1536 sl811->board->can_wakeup); in sl811h_start()
1537 hcd->power_budget = sl811->board->power * 2; in sl811h_start()
1546 /*-------------------------------------------------------------------------*/
1583 /*-------------------------------------------------------------------------*/
1598 iounmap(sl811->data_reg); in sl811h_remove()
1602 iounmap(sl811->addr_reg); in sl811h_remove()
1621 return -ENODEV; in sl811h_probe()
1627 return -ENODEV; in sl811h_probe()
1629 /* basic sanity checks first. board-specific init logic should in sl811h_probe()
1635 if (dev->num_resources < 3 || !ires) in sl811h_probe()
1636 return -ENODEV; in sl811h_probe()
1638 irq = ires->start; in sl811h_probe()
1639 irqflags = ires->flags & IRQF_TRIGGER_MASK; in sl811h_probe()
1644 * NOTE: 64-bit resource->start is getting truncated in sl811h_probe()
1645 * to avoid compiler warning, assuming that ->start in sl811h_probe()
1646 * is always 32-bit for this case in sl811h_probe()
1648 addr_reg = (void __iomem *) (unsigned long) addr->start; in sl811h_probe()
1649 data_reg = (void __iomem *) (unsigned long) data->start; in sl811h_probe()
1651 addr_reg = ioremap(addr->start, 1); in sl811h_probe()
1653 retval = -ENOMEM; in sl811h_probe()
1657 data_reg = ioremap(data->start, 1); in sl811h_probe()
1659 retval = -ENOMEM; in sl811h_probe()
1665 hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev_name(&dev->dev)); in sl811h_probe()
1667 retval = -ENOMEM; in sl811h_probe()
1670 hcd->rsrc_start = addr->start; in sl811h_probe()
1673 spin_lock_init(&sl811->lock); in sl811h_probe()
1674 INIT_LIST_HEAD(&sl811->async); in sl811h_probe()
1675 sl811->board = dev_get_platdata(&dev->dev); in sl811h_probe()
1676 timer_setup(&sl811->timer, sl811h_timer, 0); in sl811h_probe()
1677 sl811->addr_reg = addr_reg; in sl811h_probe()
1678 sl811->data_reg = data_reg; in sl811h_probe()
1680 spin_lock_irq(&sl811->lock); in sl811h_probe()
1682 spin_unlock_irq(&sl811->lock); in sl811h_probe()
1688 hcd->product_desc = "SL811HS v1.2"; in sl811h_probe()
1691 hcd->product_desc = "SL811HS v1.5"; in sl811h_probe()
1695 dev_dbg(&dev->dev, "chiprev %02x\n", tmp); in sl811h_probe()
1696 retval = -ENXIO; in sl811h_probe()
1714 device_wakeup_enable(hcd->self.controller); in sl811h_probe()
1728 dev_dbg(&dev->dev, "init error, %d\n", retval); in sl811h_probe()
1764 /* with no "check to see if VBUS is still powered" board hook, in sl811h_resume()
1765 * let's assume it'd only be powered to enable remote wakeup. in sl811h_resume()
1767 if (!sl811->port1 || !device_can_wakeup(&hcd->self.root_hub->dev)) { in sl811h_resume()
1768 sl811->port1 = 0; in sl811h_resume()
1770 usb_root_hub_lost_power(hcd->self.root_hub); in sl811h_resume()