Loading drivers/usb/gadget/function/f_serial.c +44 −0 Original line number Diff line number Diff line Loading @@ -619,6 +619,48 @@ static void gser_disable(struct usb_function *f) gser->online = 0; } static void gser_suspend(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); switch (gser->transport) { case USB_GADGET_XPORT_SMD: gsmd_suspend(&gser->port, port_num); break; default: pr_err("%s: Un-supported transport: %s\n", __func__, xport_to_str(gser->transport)); } } static void gser_resume(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); switch (gser->transport) { case USB_GADGET_XPORT_SMD: gsmd_resume(&gser->port, port_num); break; default: pr_err("%s: Un-supported transport: %s\n", __func__, xport_to_str(gser->transport)); } } static int gser_notify(struct f_gser *gser, u8 type, u16 value, void *data, unsigned length) { Loading Loading @@ -1056,6 +1098,8 @@ static struct usb_function *gser_alloc(struct usb_function_instance *fi) else gser->port.func.name = "modem2"; gser->port.func.setup = gser_setup; gser->port.func.suspend = gser_suspend; gser->port.func.resume = gser_resume; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; Loading drivers/usb/gadget/function/u_serial.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ void gserial_disconnect(struct gserial *); int gsmd_setup(struct usb_gadget *g, unsigned n_ports); int gsmd_connect(struct gserial *, u8 port_num); void gsmd_disconnect(struct gserial *, u8 portno); void gsmd_suspend(struct gserial *, u8 port_num); void gsmd_resume(struct gserial *, u8 port_num); int gsmd_write(u8 portno, char *buf, unsigned int size); /* functions are bound to configurations by a config or gadget driver */ Loading drivers/usb/gadget/function/u_smd.c +50 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ struct gsmd_port { /* pkt counters */ unsigned long nbytes_tomodem; unsigned long nbytes_tolaptop; bool is_suspended; }; static struct smd_portmaster { Loading Loading @@ -299,7 +300,10 @@ static void gsmd_tx_pull(struct work_struct *w) struct gsmd_port *port = container_of(w, struct gsmd_port, pull); struct list_head *pool = &port->write_pool; struct smd_port_info *pi = port->pi; struct usb_function *func; struct usb_gadget *gadget; struct usb_ep *in; int ret; pr_debug("%s: port:%p port#%d pool:%p\n", __func__, port, port->port_num, pool); Loading @@ -314,6 +318,27 @@ static void gsmd_tx_pull(struct work_struct *w) } in = port->port_usb->in; func = &port->port_usb->func; gadget = func->config->cdev->gadget; if (port->is_suspended) { spin_unlock_irq(&port->port_lock); ret = usb_gadget_wakeup(gadget); spin_lock_irq(&port->port_lock); if (ret) pr_err("Failed to wake up the USB core. ret=%d.\n", ret); if (!port->port_usb) { pr_debug("%s: USB disconnected\n", __func__); spin_unlock_irq(&port->port_lock); gsmd_read_pending(port); return; } spin_unlock_irq(&port->port_lock); return; } while (pi->ch && !list_empty(pool)) { struct usb_request *req; int avail; Loading Loading @@ -1003,6 +1028,31 @@ free_smd_ports: return ret; } void gsmd_suspend(struct gserial *gser, u8 portno) { struct gsmd_port *port; pr_debug("%s: gserial:%p portno:%u\n", __func__, gser, portno); port = smd_ports[portno].port; spin_lock(&port->port_lock); port->is_suspended = true; spin_unlock(&port->port_lock); } void gsmd_resume(struct gserial *gser, u8 portno) { struct gsmd_port *port; pr_debug("%s: gserial:%p portno:%u\n", __func__, gser, portno); port = smd_ports[portno].port; spin_lock(&port->port_lock); port->is_suspended = false; spin_unlock(&port->port_lock); queue_work(gsmd_wq, &port->pull); } void gsmd_cleanup(struct usb_gadget *g, unsigned count) { /* TBD */ Loading Loading
drivers/usb/gadget/function/f_serial.c +44 −0 Original line number Diff line number Diff line Loading @@ -619,6 +619,48 @@ static void gser_disable(struct usb_function *f) gser->online = 0; } static void gser_suspend(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); switch (gser->transport) { case USB_GADGET_XPORT_SMD: gsmd_suspend(&gser->port, port_num); break; default: pr_err("%s: Un-supported transport: %s\n", __func__, xport_to_str(gser->transport)); } } static void gser_resume(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); switch (gser->transport) { case USB_GADGET_XPORT_SMD: gsmd_resume(&gser->port, port_num); break; default: pr_err("%s: Un-supported transport: %s\n", __func__, xport_to_str(gser->transport)); } } static int gser_notify(struct f_gser *gser, u8 type, u16 value, void *data, unsigned length) { Loading Loading @@ -1056,6 +1098,8 @@ static struct usb_function *gser_alloc(struct usb_function_instance *fi) else gser->port.func.name = "modem2"; gser->port.func.setup = gser_setup; gser->port.func.suspend = gser_suspend; gser->port.func.resume = gser_resume; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; Loading
drivers/usb/gadget/function/u_serial.h +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ void gserial_disconnect(struct gserial *); int gsmd_setup(struct usb_gadget *g, unsigned n_ports); int gsmd_connect(struct gserial *, u8 port_num); void gsmd_disconnect(struct gserial *, u8 portno); void gsmd_suspend(struct gserial *, u8 port_num); void gsmd_resume(struct gserial *, u8 port_num); int gsmd_write(u8 portno, char *buf, unsigned int size); /* functions are bound to configurations by a config or gadget driver */ Loading
drivers/usb/gadget/function/u_smd.c +50 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,7 @@ struct gsmd_port { /* pkt counters */ unsigned long nbytes_tomodem; unsigned long nbytes_tolaptop; bool is_suspended; }; static struct smd_portmaster { Loading Loading @@ -299,7 +300,10 @@ static void gsmd_tx_pull(struct work_struct *w) struct gsmd_port *port = container_of(w, struct gsmd_port, pull); struct list_head *pool = &port->write_pool; struct smd_port_info *pi = port->pi; struct usb_function *func; struct usb_gadget *gadget; struct usb_ep *in; int ret; pr_debug("%s: port:%p port#%d pool:%p\n", __func__, port, port->port_num, pool); Loading @@ -314,6 +318,27 @@ static void gsmd_tx_pull(struct work_struct *w) } in = port->port_usb->in; func = &port->port_usb->func; gadget = func->config->cdev->gadget; if (port->is_suspended) { spin_unlock_irq(&port->port_lock); ret = usb_gadget_wakeup(gadget); spin_lock_irq(&port->port_lock); if (ret) pr_err("Failed to wake up the USB core. ret=%d.\n", ret); if (!port->port_usb) { pr_debug("%s: USB disconnected\n", __func__); spin_unlock_irq(&port->port_lock); gsmd_read_pending(port); return; } spin_unlock_irq(&port->port_lock); return; } while (pi->ch && !list_empty(pool)) { struct usb_request *req; int avail; Loading Loading @@ -1003,6 +1028,31 @@ free_smd_ports: return ret; } void gsmd_suspend(struct gserial *gser, u8 portno) { struct gsmd_port *port; pr_debug("%s: gserial:%p portno:%u\n", __func__, gser, portno); port = smd_ports[portno].port; spin_lock(&port->port_lock); port->is_suspended = true; spin_unlock(&port->port_lock); } void gsmd_resume(struct gserial *gser, u8 portno) { struct gsmd_port *port; pr_debug("%s: gserial:%p portno:%u\n", __func__, gser, portno); port = smd_ports[portno].port; spin_lock(&port->port_lock); port->is_suspended = false; spin_unlock(&port->port_lock); queue_work(gsmd_wq, &port->pull); } void gsmd_cleanup(struct usb_gadget *g, unsigned count) { /* TBD */ Loading