Lines Matching refs:dbc
89 static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length) in xhci_dbc_init_contexts() argument
97 if (!dbc) in xhci_dbc_init_contexts()
101 info = (struct dbc_info_context *)dbc->ctx->bytes; in xhci_dbc_init_contexts()
102 dma = dbc->string_dma; in xhci_dbc_init_contexts()
110 ep_ctx = dbc_bulkout_ctx(dbc); in xhci_dbc_init_contexts()
111 max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control)); in xhci_dbc_init_contexts()
112 deq = dbc_bulkout_enq(dbc); in xhci_dbc_init_contexts()
115 ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state); in xhci_dbc_init_contexts()
118 ep_ctx = dbc_bulkin_ctx(dbc); in xhci_dbc_init_contexts()
119 deq = dbc_bulkin_enq(dbc); in xhci_dbc_init_contexts()
122 ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state); in xhci_dbc_init_contexts()
125 lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp); in xhci_dbc_init_contexts()
128 writel(dev_info, &dbc->regs->devinfo1); in xhci_dbc_init_contexts()
131 writel(dev_info, &dbc->regs->devinfo2); in xhci_dbc_init_contexts()
135 __releases(&dbc->lock) in xhci_dbc_giveback()
136 __acquires(&dbc->lock) in xhci_dbc_giveback()
138 struct xhci_dbc *dbc = req->dbc; in xhci_dbc_giveback() local
139 struct device *dev = dbc->dev; in xhci_dbc_giveback()
156 spin_unlock(&dbc->lock); in xhci_dbc_giveback()
157 req->complete(dbc, req); in xhci_dbc_giveback()
158 spin_lock(&dbc->lock); in xhci_dbc_giveback()
182 static void xhci_dbc_flush_requests(struct xhci_dbc *dbc) in xhci_dbc_flush_requests() argument
184 xhci_dbc_flush_endpoint_requests(&dbc->eps[BULK_OUT]); in xhci_dbc_flush_requests()
185 xhci_dbc_flush_endpoint_requests(&dbc->eps[BULK_IN]); in xhci_dbc_flush_requests()
189 dbc_alloc_request(struct xhci_dbc *dbc, unsigned int direction, gfp_t flags) in dbc_alloc_request() argument
197 if (!dbc) in dbc_alloc_request()
204 req->dbc = dbc; in dbc_alloc_request()
251 struct xhci_dbc *dbc = req->dbc; in xhci_dbc_queue_bulk_tx() local
289 writel(DBC_DOOR_BELL_TARGET(dep->direction), &dbc->regs->doorbell); in xhci_dbc_queue_bulk_tx()
298 struct xhci_dbc *dbc = req->dbc; in dbc_ep_do_queue() local
299 struct device *dev = dbc->dev; in dbc_ep_do_queue()
300 struct dbc_ep *dep = &dbc->eps[req->direction]; in dbc_ep_do_queue()
313 dev_err(dbc->dev, "failed to map buffer\n"); in dbc_ep_do_queue()
319 dev_err(dbc->dev, "failed to queue trbs\n"); in dbc_ep_do_queue()
335 struct xhci_dbc *dbc = req->dbc; in dbc_ep_queue() local
338 if (!dbc) in dbc_ep_queue()
345 spin_lock_irqsave(&dbc->lock, flags); in dbc_ep_queue()
346 if (dbc->state == DS_CONFIGURED) in dbc_ep_queue()
348 spin_unlock_irqrestore(&dbc->lock, flags); in dbc_ep_queue()
350 mod_delayed_work(system_wq, &dbc->event_work, 0); in dbc_ep_queue()
357 static inline void xhci_dbc_do_eps_init(struct xhci_dbc *dbc, bool direction) in xhci_dbc_do_eps_init() argument
361 dep = &dbc->eps[direction]; in xhci_dbc_do_eps_init()
362 dep->dbc = dbc; in xhci_dbc_do_eps_init()
364 dep->ring = direction ? dbc->ring_in : dbc->ring_out; in xhci_dbc_do_eps_init()
369 static void xhci_dbc_eps_init(struct xhci_dbc *dbc) in xhci_dbc_eps_init() argument
371 xhci_dbc_do_eps_init(dbc, BULK_OUT); in xhci_dbc_eps_init()
372 xhci_dbc_do_eps_init(dbc, BULK_IN); in xhci_dbc_eps_init()
375 static void xhci_dbc_eps_exit(struct xhci_dbc *dbc) in xhci_dbc_eps_exit() argument
377 memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps)); in xhci_dbc_eps_exit()
467 static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags) in xhci_dbc_mem_init() argument
472 struct device *dev = dbc->dev; in xhci_dbc_mem_init()
475 dbc->ring_evt = xhci_dbc_ring_alloc(dev, TYPE_EVENT, flags); in xhci_dbc_mem_init()
476 if (!dbc->ring_evt) in xhci_dbc_mem_init()
479 dbc->ring_in = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags); in xhci_dbc_mem_init()
480 if (!dbc->ring_in) in xhci_dbc_mem_init()
483 dbc->ring_out = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags); in xhci_dbc_mem_init()
484 if (!dbc->ring_out) in xhci_dbc_mem_init()
488 ret = dbc_erst_alloc(dev, dbc->ring_evt, &dbc->erst, flags); in xhci_dbc_mem_init()
493 dbc->ctx = dbc_alloc_ctx(dev, flags); /* was sysdev, and is still */ in xhci_dbc_mem_init()
494 if (!dbc->ctx) in xhci_dbc_mem_init()
498 dbc->string_size = sizeof(struct dbc_str_descs); in xhci_dbc_mem_init()
499 dbc->string = dma_alloc_coherent(dev, dbc->string_size, in xhci_dbc_mem_init()
500 &dbc->string_dma, flags); in xhci_dbc_mem_init()
501 if (!dbc->string) in xhci_dbc_mem_init()
505 writel(dbc->erst.erst_size, &dbc->regs->ersts); in xhci_dbc_mem_init()
507 lo_hi_writeq(dbc->erst.erst_dma_addr, &dbc->regs->erstba); in xhci_dbc_mem_init()
508 deq = xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg, in xhci_dbc_mem_init()
509 dbc->ring_evt->dequeue); in xhci_dbc_mem_init()
510 lo_hi_writeq(deq, &dbc->regs->erdp); in xhci_dbc_mem_init()
513 string_length = xhci_dbc_populate_strings(dbc->string); in xhci_dbc_mem_init()
514 xhci_dbc_init_contexts(dbc, string_length); in xhci_dbc_mem_init()
516 xhci_dbc_eps_init(dbc); in xhci_dbc_mem_init()
517 dbc->state = DS_INITIALIZED; in xhci_dbc_mem_init()
522 dbc_free_ctx(dev, dbc->ctx); in xhci_dbc_mem_init()
523 dbc->ctx = NULL; in xhci_dbc_mem_init()
525 dbc_erst_free(dev, &dbc->erst); in xhci_dbc_mem_init()
527 dbc_ring_free(dev, dbc->ring_out); in xhci_dbc_mem_init()
528 dbc->ring_out = NULL; in xhci_dbc_mem_init()
530 dbc_ring_free(dev, dbc->ring_in); in xhci_dbc_mem_init()
531 dbc->ring_in = NULL; in xhci_dbc_mem_init()
533 dbc_ring_free(dev, dbc->ring_evt); in xhci_dbc_mem_init()
534 dbc->ring_evt = NULL; in xhci_dbc_mem_init()
539 static void xhci_dbc_mem_cleanup(struct xhci_dbc *dbc) in xhci_dbc_mem_cleanup() argument
541 if (!dbc) in xhci_dbc_mem_cleanup()
544 xhci_dbc_eps_exit(dbc); in xhci_dbc_mem_cleanup()
546 if (dbc->string) { in xhci_dbc_mem_cleanup()
547 dma_free_coherent(dbc->dev, dbc->string_size, in xhci_dbc_mem_cleanup()
548 dbc->string, dbc->string_dma); in xhci_dbc_mem_cleanup()
549 dbc->string = NULL; in xhci_dbc_mem_cleanup()
552 dbc_free_ctx(dbc->dev, dbc->ctx); in xhci_dbc_mem_cleanup()
553 dbc->ctx = NULL; in xhci_dbc_mem_cleanup()
555 dbc_erst_free(dbc->dev, &dbc->erst); in xhci_dbc_mem_cleanup()
556 dbc_ring_free(dbc->dev, dbc->ring_out); in xhci_dbc_mem_cleanup()
557 dbc_ring_free(dbc->dev, dbc->ring_in); in xhci_dbc_mem_cleanup()
558 dbc_ring_free(dbc->dev, dbc->ring_evt); in xhci_dbc_mem_cleanup()
559 dbc->ring_in = NULL; in xhci_dbc_mem_cleanup()
560 dbc->ring_out = NULL; in xhci_dbc_mem_cleanup()
561 dbc->ring_evt = NULL; in xhci_dbc_mem_cleanup()
564 static int xhci_do_dbc_start(struct xhci_dbc *dbc) in xhci_do_dbc_start() argument
569 if (dbc->state != DS_DISABLED) in xhci_do_dbc_start()
572 writel(0, &dbc->regs->control); in xhci_do_dbc_start()
573 ret = xhci_handshake(&dbc->regs->control, in xhci_do_dbc_start()
579 ret = xhci_dbc_mem_init(dbc, GFP_ATOMIC); in xhci_do_dbc_start()
583 ctrl = readl(&dbc->regs->control); in xhci_do_dbc_start()
585 &dbc->regs->control); in xhci_do_dbc_start()
586 ret = xhci_handshake(&dbc->regs->control, in xhci_do_dbc_start()
592 dbc->state = DS_ENABLED; in xhci_do_dbc_start()
597 static int xhci_do_dbc_stop(struct xhci_dbc *dbc) in xhci_do_dbc_stop() argument
599 if (dbc->state == DS_DISABLED) in xhci_do_dbc_stop()
602 writel(0, &dbc->regs->control); in xhci_do_dbc_stop()
603 dbc->state = DS_DISABLED; in xhci_do_dbc_stop()
608 static int xhci_dbc_start(struct xhci_dbc *dbc) in xhci_dbc_start() argument
613 WARN_ON(!dbc); in xhci_dbc_start()
615 pm_runtime_get_sync(dbc->dev); /* note this was self.controller */ in xhci_dbc_start()
617 spin_lock_irqsave(&dbc->lock, flags); in xhci_dbc_start()
618 ret = xhci_do_dbc_start(dbc); in xhci_dbc_start()
619 spin_unlock_irqrestore(&dbc->lock, flags); in xhci_dbc_start()
622 pm_runtime_put(dbc->dev); /* note this was self.controller */ in xhci_dbc_start()
626 return mod_delayed_work(system_wq, &dbc->event_work, 1); in xhci_dbc_start()
629 static void xhci_dbc_stop(struct xhci_dbc *dbc) in xhci_dbc_stop() argument
634 WARN_ON(!dbc); in xhci_dbc_stop()
636 switch (dbc->state) { in xhci_dbc_stop()
641 if (dbc->driver->disconnect) in xhci_dbc_stop()
642 dbc->driver->disconnect(dbc); in xhci_dbc_stop()
648 cancel_delayed_work_sync(&dbc->event_work); in xhci_dbc_stop()
650 spin_lock_irqsave(&dbc->lock, flags); in xhci_dbc_stop()
651 ret = xhci_do_dbc_stop(dbc); in xhci_dbc_stop()
652 spin_unlock_irqrestore(&dbc->lock, flags); in xhci_dbc_stop()
655 xhci_dbc_mem_cleanup(dbc); in xhci_dbc_stop()
656 pm_runtime_put_sync(dbc->dev); /* note, was self.controller */ in xhci_dbc_stop()
661 dbc_handle_port_status(struct xhci_dbc *dbc, union xhci_trb *event) in dbc_handle_port_status() argument
665 portsc = readl(&dbc->regs->portsc); in dbc_handle_port_status()
667 dev_info(dbc->dev, "DbC port connect change\n"); in dbc_handle_port_status()
670 dev_info(dbc->dev, "DbC port reset change\n"); in dbc_handle_port_status()
673 dev_info(dbc->dev, "DbC port link status change\n"); in dbc_handle_port_status()
676 dev_info(dbc->dev, "DbC config error change\n"); in dbc_handle_port_status()
679 writel(portsc & ~DBC_PORTSC_RESET_CHANGE, &dbc->regs->portsc); in dbc_handle_port_status()
682 static void dbc_handle_xfer_event(struct xhci_dbc *dbc, union xhci_trb *event) in dbc_handle_xfer_event() argument
696 get_out_ep(dbc) : get_in_ep(dbc); in dbc_handle_xfer_event()
710 dev_warn(dbc->dev, "tx error %d detected\n", comp_code); in dbc_handle_xfer_event()
714 dev_err(dbc->dev, "unknown tx error %d\n", comp_code); in dbc_handle_xfer_event()
728 dev_warn(dbc->dev, "no matched request\n"); in dbc_handle_xfer_event()
750 static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc) in xhci_dbc_do_handle_events() argument
759 switch (dbc->state) { in xhci_dbc_do_handle_events()
765 portsc = readl(&dbc->regs->portsc); in xhci_dbc_do_handle_events()
767 dbc->state = DS_CONNECTED; in xhci_dbc_do_handle_events()
768 dev_info(dbc->dev, "DbC connected\n"); in xhci_dbc_do_handle_events()
773 ctrl = readl(&dbc->regs->control); in xhci_dbc_do_handle_events()
775 dbc->state = DS_CONFIGURED; in xhci_dbc_do_handle_events()
776 dev_info(dbc->dev, "DbC configured\n"); in xhci_dbc_do_handle_events()
777 portsc = readl(&dbc->regs->portsc); in xhci_dbc_do_handle_events()
778 writel(portsc, &dbc->regs->portsc); in xhci_dbc_do_handle_events()
785 portsc = readl(&dbc->regs->portsc); in xhci_dbc_do_handle_events()
788 dev_info(dbc->dev, "DbC cable unplugged\n"); in xhci_dbc_do_handle_events()
789 dbc->state = DS_ENABLED; in xhci_dbc_do_handle_events()
790 xhci_dbc_flush_requests(dbc); in xhci_dbc_do_handle_events()
797 dev_info(dbc->dev, "DbC port reset\n"); in xhci_dbc_do_handle_events()
798 writel(portsc, &dbc->regs->portsc); in xhci_dbc_do_handle_events()
799 dbc->state = DS_ENABLED; in xhci_dbc_do_handle_events()
800 xhci_dbc_flush_requests(dbc); in xhci_dbc_do_handle_events()
806 ctrl = readl(&dbc->regs->control); in xhci_dbc_do_handle_events()
809 dev_info(dbc->dev, "DbC Endpoint stall\n"); in xhci_dbc_do_handle_events()
810 dbc->state = DS_STALLED; in xhci_dbc_do_handle_events()
813 dep = get_in_ep(dbc); in xhci_dbc_do_handle_events()
818 dep = get_out_ep(dbc); in xhci_dbc_do_handle_events()
827 writel(ctrl, &dbc->regs->control); in xhci_dbc_do_handle_events()
828 ctrl = readl(&dbc->regs->control); in xhci_dbc_do_handle_events()
833 ctrl = readl(&dbc->regs->control); in xhci_dbc_do_handle_events()
837 dbc->state = DS_CONFIGURED; in xhci_dbc_do_handle_events()
843 dev_err(dbc->dev, "Unknown DbC state %d\n", dbc->state); in xhci_dbc_do_handle_events()
848 evt = dbc->ring_evt->dequeue; in xhci_dbc_do_handle_events()
850 dbc->ring_evt->cycle_state) { in xhci_dbc_do_handle_events()
857 trace_xhci_dbc_handle_event(dbc->ring_evt, &evt->generic); in xhci_dbc_do_handle_events()
861 dbc_handle_port_status(dbc, evt); in xhci_dbc_do_handle_events()
864 dbc_handle_xfer_event(dbc, evt); in xhci_dbc_do_handle_events()
870 inc_evt_deq(dbc->ring_evt); in xhci_dbc_do_handle_events()
872 evt = dbc->ring_evt->dequeue; in xhci_dbc_do_handle_events()
878 deq = xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg, in xhci_dbc_do_handle_events()
879 dbc->ring_evt->dequeue); in xhci_dbc_do_handle_events()
880 lo_hi_writeq(deq, &dbc->regs->erdp); in xhci_dbc_do_handle_events()
889 struct xhci_dbc *dbc; in xhci_dbc_handle_events() local
892 dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work); in xhci_dbc_handle_events()
894 spin_lock_irqsave(&dbc->lock, flags); in xhci_dbc_handle_events()
895 evtr = xhci_dbc_do_handle_events(dbc); in xhci_dbc_handle_events()
896 spin_unlock_irqrestore(&dbc->lock, flags); in xhci_dbc_handle_events()
900 if (dbc->driver->configure) in xhci_dbc_handle_events()
901 dbc->driver->configure(dbc); in xhci_dbc_handle_events()
904 if (dbc->driver->disconnect) in xhci_dbc_handle_events()
905 dbc->driver->disconnect(dbc); in xhci_dbc_handle_events()
910 dev_info(dbc->dev, "stop handling dbc events\n"); in xhci_dbc_handle_events()
914 mod_delayed_work(system_wq, &dbc->event_work, 1); in xhci_dbc_handle_events()
922 struct xhci_dbc *dbc; in dbc_show() local
926 dbc = xhci->dbc; in dbc_show()
928 switch (dbc->state) { in dbc_show()
959 struct xhci_dbc *dbc; in dbc_store() local
962 dbc = xhci->dbc; in dbc_store()
965 xhci_dbc_start(dbc); in dbc_store()
967 xhci_dbc_stop(dbc); in dbc_store()
974 static DEVICE_ATTR_RW(dbc);
979 struct xhci_dbc *dbc; in xhci_alloc_dbc() local
982 dbc = kzalloc(sizeof(*dbc), GFP_KERNEL); in xhci_alloc_dbc()
983 if (!dbc) in xhci_alloc_dbc()
986 dbc->regs = base; in xhci_alloc_dbc()
987 dbc->dev = dev; in xhci_alloc_dbc()
988 dbc->driver = driver; in xhci_alloc_dbc()
990 if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) in xhci_alloc_dbc()
993 INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events); in xhci_alloc_dbc()
994 spin_lock_init(&dbc->lock); in xhci_alloc_dbc()
1000 return dbc; in xhci_alloc_dbc()
1002 kfree(dbc); in xhci_alloc_dbc()
1007 void xhci_dbc_remove(struct xhci_dbc *dbc) in xhci_dbc_remove() argument
1009 if (!dbc) in xhci_dbc_remove()
1012 xhci_dbc_stop(dbc); in xhci_dbc_remove()
1015 device_remove_file(dbc->dev, &dev_attr_dbc); in xhci_dbc_remove()
1017 kfree(dbc); in xhci_dbc_remove()
1037 if (xhci->dbc) in xhci_create_dbc_dev()
1049 if (!xhci->dbc) in xhci_remove_dbc_dev()
1052 xhci_dbc_tty_remove(xhci->dbc); in xhci_remove_dbc_dev()
1054 xhci->dbc = NULL; in xhci_remove_dbc_dev()
1061 struct xhci_dbc *dbc = xhci->dbc; in xhci_dbc_suspend() local
1063 if (!dbc) in xhci_dbc_suspend()
1066 if (dbc->state == DS_CONFIGURED) in xhci_dbc_suspend()
1067 dbc->resume_required = 1; in xhci_dbc_suspend()
1069 xhci_dbc_stop(dbc); in xhci_dbc_suspend()
1077 struct xhci_dbc *dbc = xhci->dbc; in xhci_dbc_resume() local
1079 if (!dbc) in xhci_dbc_resume()
1082 if (dbc->resume_required) { in xhci_dbc_resume()
1083 dbc->resume_required = 0; in xhci_dbc_resume()
1084 xhci_dbc_start(dbc); in xhci_dbc_resume()